我想建立一个专家系统,在一些楼层(一楼+三层)发生紧急情况时,电梯应该把人们带到地面。从第一层(第三层)到第二层(第二层),再到第一层(第一层),先把人救出来。我对规则的重要性有异议(我对每一层都有各自的规则)。在一开始,最突出的是规则"MoveFloor3“--把电梯搬到三楼(因为我首先想把人从最高层救出来)。当我从三楼拯救所有的人时,我想把这个规则中的显着性更改为0(或者比第二层和第一层的显着性更小的数字),因为在那之后,我想从第二层和第一层拯救人们。此规则的代码如下所示,如何修改此代码,以便在该楼层上的人数变为0之后更改显着性。
(defrule moveFloor3
(declare (salience 50))
?j<-(lastJob ?t&~moveFloor3)
?e<-(elevator ?peopleInElevator)
?f<-(floor3 ?peopleInFloor)
(capacityElevator ?capacityElevator)
=>
(bind ?newPeopleInElevator (+ ?peopleInElevator (min ?peopleInFloor (- ?capacityElevator ?peopleInElevator))))
(bind ?newPeopleInFloor (- ?peopleInFloor (min ?peopleInFloor (- ?capacityElevator ?peopleInElevator))))
(retract ?e ?f ?s ?j)
(assert (elevator ?newPeopleInElevator))
(assert (floor3 ?newPeopleInFloor))
(assert (lastJob moveFloor3))
(printout t "Elevator moved to third floor" crlf)
)发布于 2020-01-13 08:14:54
使用全局变量来设置显着性,一旦触发,就可以在规则的RHS中对其进行更改。还请参见Using variables in salience declaration in a rule definition
发布于 2020-01-13 18:50:18
这里有一个替代解决方案,它只需要两个规则就可以处理任意数量的楼层,并且不需要使用凸性:
CLIPS (6.31 6/12/19)
CLIPS>
(deftemplate floor
(slot #)
(slot people))
CLIPS>
(deftemplate elevator
(slot capacity)
(slot occupants))
CLIPS>
(deffacts initial
(elevator (capacity 8)
(occupants 0))
(floor (# ground) (people 0))
(floor (# 1) (people 4))
(floor (# 2) (people 8))
(floor (# 3) (people 13)))
CLIPS>
(defrule pick-up-people
;; The elevator is not full
?e <- (elevator (capacity ?c)
(occupants ?o&~?c))
;; There's a floor with people on it
?f <- (floor (# ?f1&~ground) (people ?p&~0))
;; There's not a higher floor with people
(not (floor (# ?f2&~ground&:(> ?f2 ?f1)) (people ~0)))
=>
;; The number of people that can enter the elevator is
;; the minimum of the remaining occupancy of the elevator
;; and the number of people on the floor
(bind ?added-people (min (- ?c ?o) ?p))
;; Print a message
(printout t "Elevator moves to floor " ?f1
" and picks up " ?added-people " "
(if (= ?added-people 1) then person else people)
crlf)
;; Update the number of people in the elevator and on the floor
(modify ?e (occupants (+ ?o ?added-people)))
(modify ?f (people (- ?p ?added-people))))
CLIPS>
(defrule drop-off-people
;; Determine the number of people on the ground floor
?f <- (floor (# ground) (people ?p))
;; There must be people in the elevator
?e <- (elevator (occupants ?o&~0)
(capacity ?c))
;; There are no remaining people on any of the floors
;; or the elevator is at full occupancy
(or (not (floor (# ~ground) (people ~0)))
(test (= ?c ?o)))
=>
;; Print a message
(printout t "Elevator moves to ground floor and drops off "
?o " " (if (= ?o 1) then person else people) crlf)
;; Update the number of people on the ground floor and
;; in the elevator
(modify ?f (people (+ ?o ?p)))
(modify ?e (occupants 0)))
CLIPS> (reset)
CLIPS> (run)
Elevator moves to floor 3 and picks up 8 people
Elevator moves to ground floor and drops off 8 people
Elevator moves to floor 3 and picks up 5 people
Elevator moves to floor 2 and picks up 3 people
Elevator moves to ground floor and drops off 8 people
Elevator moves to floor 2 and picks up 5 people
Elevator moves to floor 1 and picks up 3 people
Elevator moves to ground floor and drops off 8 people
Elevator moves to floor 1 and picks up 1 person
Elevator moves to ground floor and drops off 1 person
CLIPS> 发布于 2020-01-13 14:44:44
如果有人有同样的问题-这是我的解决方案,它是有效的!
**(defglobal ?*floor3* = 0)**
(defrule moveFloor3
**(declare (salience (+ ?*floor3* 40)))**
?j<-(lastJob ?t&~moveFloor3)
?e<-(elevator ?peopleInElevator)
?f<-(floor3 ?peopleInFloor)
(capacityElevator ?capacityElevator)
=>
(if (eq ?peopleInFloor 0)
then
**(bind ?*floor3* -40)**
else
(bind ?newPeopleInElevator (+ ?peopleInElevator (min ?peopleInFloor (- ?capacityElevator ?peopleInElevator))))
(bind ?newPeopleInFloor (- ?peopleInFloor (min ?peopleInFloor (- ?capacityElevator ?peopleInElevator))))
(retract ?e ?f ?j)
(assert (elevator ?newPeopleInElevator))
(assert (floor3 ?newPeopleInFloor))
(assert (lastJob moveFloor3))
(printout t "Elevator moved to third floor" crlf)
)
)https://stackoverflow.com/questions/59708989
复制相似问题