如何在多槽字段中对整数求和,尝试 CLIPS 中的所有可能组合



我有这样的情况:

(deftemplate trip
(multislot place-sequence)
(multislot days-distribution)
)
(deftemplate travel-banchmark
(slot name)
(slot value)
)
(trip (place-sequence milano roma venezia) (days-distribution 1 1 1))
(trip (place-sequence roma milano venezia) (days-distribution 1 1 1))
(travel-banchmark (name travel-duration) (value 5))

现在,对于每个行程事实,我必须断言所有可能具有不同天数分布的行程(日分布的总和必须是travel-duration(例如,5((

例:

(trip (place-sequence milano roma venezia) (days-distribution 3 1 1))
(trip (place-sequence milano roma venezia) (days-distribution 1 3 1))
(trip (place-sequence milano roma venezia) (days-distribution 1 1 3))
(trip (place-sequence milano roma venezia) (days-distribution 2 2 1))
(trip (place-sequence milano roma venezia) (days-distribution 1 1 2))
...

是否可以使用规则执行此操作?我在理解使用基于规则的系统做这种事情的最佳方法方面遇到了一些问题

编辑: 这是我计算多插槽内总和的方法,但我仍然无法弄清楚如何计算不同的天数 - distrub

(defrule test
(travel-banchmark (name travel-duration) (value ?duration))
?p <- (trip
(days-distribution $?d))
(test (<= (+ 0 (expand$ ?d)) ?duration))
=>
...
)

您不必使用规则来执行所有操作,尤其是在有明显的算法解决方案的情况下。例如,这样做是没有意义的:

(defrule hello
?f <- (count ?c&:(> ?c 0))
=>
(printout t "Hello" crlf)
(retract ?f)
(assert (count (- ?c 1))))

当您可以执行此操作时:

(deffunction hello (?count)
(loop-for-count ?count (printout t "Hello" crlf)))

使用递归函数调用生成分布非常简单,可以从单个规则触发中执行此操作,而无需增量构建解决方案,然后删除中间步骤。

CLIPS (6.31 6/12/19)
CLIPS> 
(deftemplate trip
(multislot place-sequence)
(multislot days-distribution))
CLIPS> 
(deftemplate travel-banchmark
(slot name)
(slot value))
CLIPS> 
(deffacts initial
(travel-banchmark (name travel-duration) (value 5))
(trip (place-sequence milano roma venezia) (days-distribution)))
CLIPS> 
(deffunction create-distributions (?cc ?cities ?days ?duration $?distribution)
(bind ?max-alloc (- ?duration ?days (- ?cc 1)))   
(if (= ?cc 1)
then
(assert (trip (place-sequence ?cities) (days-distribution ?distribution ?max-alloc)))
(return))
(loop-for-count (?a ?max-alloc)
(create-distributions (- ?cc 1) ?cities (+ ?days ?a) ?duration ?distribution ?a)))
CLIPS> 
(defrule test
(travel-banchmark (name travel-duration) (value ?duration))
?p <- (trip (place-sequence $?cities) (days-distribution))
=>
(bind ?city-count (length$ ?cities))
(create-distributions ?city-count ?cities 0 ?duration)
(retract ?p))
CLIPS> (reset)
CLIPS> (run)
CLIPS> (facts)
f-0     (initial-fact)
f-1     (travel-banchmark (name travel-duration) (value 5))
f-3     (trip (place-sequence milano roma venezia) (days-distribution 1 1 3))
f-4     (trip (place-sequence milano roma venezia) (days-distribution 1 2 2))
f-5     (trip (place-sequence milano roma venezia) (days-distribution 1 3 1))
f-6     (trip (place-sequence milano roma venezia) (days-distribution 2 1 2))
f-7     (trip (place-sequence milano roma venezia) (days-distribution 2 2 1))
f-8     (trip (place-sequence milano roma venezia) (days-distribution 3 1 1))
For a total of 8 facts.
CLIPS> 

好的,我找到了问题的答案:

CLIPS> 
(deftemplate trip
(multislot place-sequence)
(multislot days-distribution)
)
CLIPS> 
(deftemplate travel-banchmark
(slot name)
(slot value)
)
CLIPS> 
(deffacts initial
(travel-banchmark (name travel-duration) (value 5))
(trip (place-sequence milano roma venezia) (days-distribution 1 1 1))
)
CLIPS> 
(defrule test
(travel-banchmark (name travel-duration) (value ?duration))
?p <- (trip
(place-sequence $?cities)
(days-distribution $?days-distribution))
(test (< (+ 0 (expand$ ?days-distribution)) ?duration))
=>
(retract ?p)
(loop-for-count (?cnt1 1 (length$ ?days-distribution)) do
(bind ?new-days-distribution (replace$ ?days-distribution ?cnt1 ?cnt1 (+ (nth$ ?cnt1 ?days-distribution) 1)))
(assert (trip 
(place-sequence ?cities)
(days-distribution ?new-days-distribution))
)
)
)
CLIPS>
(defrule clean
(declare (salience -5))
?p <- (trip
(place-sequence $?cities)
(days-distribution $?days-distribution))
?p2 <- (trip
(place-sequence $?cities)
(days-distribution $?days-distribution))
(test (neq ?p ?p2))
=>
(retract ?p)
)
CLIPS> (reset)
CLIPS> (run)
CLIPS> (facts)
f-0     (initial-fact)
f-1     (travel-banchmark (name travel-duration) (value 5))
f-6     (trip (place-sequence milano roma venezia) (days-distribution 2 1 2))
f-7     (trip (place-sequence milano roma venezia) (days-distribution 1 2 2))
f-8     (trip (place-sequence milano roma venezia) (days-distribution 1 1 3))
f-9     (trip (place-sequence milano roma venezia) (days-distribution 2 2 1))
f-10    (trip (place-sequence milano roma venezia) (days-distribution 1 3 1))
f-12    (trip (place-sequence milano roma venezia) (days-distribution 3 1 1))
For a total of 8 facts.
CLIPS> 

相关内容

最新更新