CLIPS巨大的内存使用量

时间:2016-01-05 15:12:04

标签: memory clips consumption

我正在使用剪辑框架来构建专家系统。但是我遇到了内存使用问题,这会使它不适合我的任务。所以这就是问题所在:

它产生了144个SpinWave事实,它总共有大约150个事实。每个事实不应该超过一堆整数(大约15)。 CLIPS消耗1GB内存,大约有6个内存请求。我有点困惑为什么它会分配那么多记忆......有人能指出我正确的方向或给出解释。我正在使用的代码如下。提前谢谢!

史蒂夫

; define helicity wave final or initial state template
(deftemplate SpinWaveMultiplet
    (slot unique_id (type INTEGER))
    (slot charge (type INTEGER))
    (slot isospin_num (type INTEGER))
    (slot isospin_denom (type INTEGER))
    (slot isospin_z_num (type INTEGER))
    (slot spin_num (type INTEGER))
    (slot spin_denom (type INTEGER))
    ; we have multislot of spin z to allow for specific components
    ; in the initial or final state
    (multislot spin_z_num)
    (slot parity (type INTEGER))
    (slot cparity (type INTEGER))
)

; define spin wave  
(deftemplate SpinWave
    (slot unique_id (type INTEGER))
    (slot charge (type INTEGER))
    (slot isospin_num (type INTEGER))
    (slot isospin_denom (type INTEGER))
    (slot isospin_z_num (type INTEGER))
    (slot spin_num (type INTEGER))
    (slot spin_denom (type INTEGER))
    (slot spin_z_num (type INTEGER))
    (slot parity (type INTEGER))
    (slot cparity (type INTEGER))
)

; allowed intermediate state spins
(deffacts user-conditions
    (AllowedQN
        (spin_nums 0 1 2) (spin_denom 1 ) (isospin_nums 0 1) (isospin_denom 1)
        (charge 0) (parity -1 1) (cparity -1 1)
    )
)


(deffacts initial-state
    (SpinWaveMultiplet (unique_id 0) (spin_num 1) (spin_denom 1) (spin_z_num -1 1)
        (isospin_num 0) (isospin_denom 1) (isospin_z_num 0)
    )
)

(deffacts final-state-list
    (SpinWaveMultiplet (unique_id 1) (spin_num 1) (spin_denom 1) (spin_z_num -1 1)
        (isospin_num 0) (isospin_denom 1) (isospin_z_num 0)
    )
    (SpinWaveMultiplet (unique_id 2) (spin_num 0) (spin_denom 1) (spin_z_num 0)
        (isospin_num 1) (isospin_denom 1) (isospin_z_num 0)
)
    (SpinWaveMultiplet (unique_id 3) (spin_num 0) (spin_denom 1) (spin_z_num 0)
        (isospin_num 1) (isospin_denom 1) (isospin_z_num 0)
    )
)

; create all spin waves
(defrule create-initial-spin-waves
    (AllowedQN
        (spin_nums $?spin_nums) (spin_denom ?spin_denom) 
        (isospin_nums $?isospin_nums) (isospin_denom ?isospin_denom)
        (charge $?charges)
        (parity $?parities)
        (cparity $?cparities)
    )
    =>
    (foreach ?charge ?charges
    (foreach ?parity ?parities
    (foreach ?cparity ?cparities

    (foreach ?isospin_num ?isospin_nums
        (bind ?isospin_z_num (* -1 ?isospin_num))
        (while (<= ?isospin_z_num ?isospin_num)
            (foreach ?spin_num ?spin_nums
                (bind ?spin_z_num (* -1 ?spin_num))
                (while (<= ?spin_z_num ?spin_num) 
                    (assert
                        (SpinWave (unique_id ?*total_unique_id_counter*) 
                        (spin_num ?spin_num) (spin_denom ?spin_denom) (spin_z_num ?spin_z_num)
                        (isospin_num ?isospin_num) (isospin_denom ?isospin_denom) (isospin_z_num ?isospin_z_num)
                        (charge ?charge) (parity ?parity) (cparity ?cparity)
                        )
                    )
                    (bind ?*total_unique_id_counter* (+ ?*total_unique_id_counter* 1))
                    (bind ?spin_z_num (+ ?spin_z_num ?spin_denom))
                )
            )
            (bind ?isospin_z_num (+ ?isospin_z_num ?isospin_denom))
        )
    )

    )
    )
    )
)

1 个答案:

答案 0 :(得分:3)

您发布的代码片段不会消耗大量内存(小于17 MB)。 CLIPS使用rete算法来保存规则的部分匹配状态,因此您可能有一个或多个规则匹配生成大量部分匹配的SpinWave事实。

您可以使用matches命令获取每个规则使用的部分匹配数的快照,并使用join-activity命令获取可能存在性能问题的规则的整体快照。

例如,在运行方式基准测试后,我可以看到使用这些命令,我​​应该检查find_seating和make_path规则是否存在性能问题。

CLIPS> (batch "manners128.bat")
TRUE
CLIPS> (clear)
CLIPS> (unwatch compilations)
CLIPS> (watch statistics)
CLIPS> (set-strategy depth)
depth
CLIPS> (load manners.clp)
:%%%%%%%********
TRUE
CLIPS> (reset)
CLIPS> (load-facts manners128.fct)
TRUE
CLIPS> (run)
8639 rules fired        Run time is 2.39572899999621 seconds.
3606.00051174973 rules per second.
4762 mean number of facts (8953 maximum).
1 mean number of instances (1 maximum).
138 mean number of activations (9490 maximum).
CLIPS> 
(progn$ 
   (?r (get-defrule-list)) 
   (printout t ?r ": " (join-activity ?r terse) crlf))
assign_first_seat: (1314 1315 1315)
find_seating: (5847660 7067211 7067211)
make_path: (49549 16510 16510)
path_done: (127 254 254)
are_we_done: (128 255 255)
continue: (0 127 127)
print_results: (257 258 128)
all_done: (0 1 0)
CLIPS> 
(progn$ 
   (?r (get-defrule-list)) 
   (printout t ?r ": " (matches ?r terse) crlf))
assign_first_seat: (439 0 0)
find_seating: (9260 0 0)
make_path: (16256 0 0)
path_done: (0 0 0)
are_we_done: (129 0 0)
continue: (0 0 0)
print_results: (8258 129 0)
all_done: (1 0 0)
CLIPS> 

从你的意见中跟进,这是你提到的引起问题的规则之一:

(defrule check-charge 
   ?mymother <- (SpinWave (charge ?charge_mother)) 
   ?mydaughter1 <- (SpinWave (charge ?charge_daughter1)) 
   ?mydaughter2 <- (SpinWave (charge ?charge_daughter2)) 
   =>)

没有一个模式具有限制与其他模式匹配的事实数量的条件,因此基本上这个规则匹配三个SpinWave事实的所有组合。由于有144个事实与三种模式中的每一种相匹配,因此规则将激活2,985,984(144 * 144 * 144)。因此,即使CLIPS没有为前两个模式生成部分匹配,仍然会有数百万次激活消耗内存,最终会在允许执行每个规则激活时释放。

在不知道规则应该做什么或SpinWave事实之间的关系的情况下,很难具体说明如何使规则更有效率,但通常你希望模式在事实数量上受到限制这将通过前面模式的变量绑定来匹配它们。

因此,如果事实之间存在父/子关系,您可以为SpinWave事实添加和填充父槽,并使用它来减少生成的部分匹配/激活的数量:

(defrule check-charge 
   ?mymother <- (SpinWave (charge ?charge_mother) (unique_id ?id)) 
   ?mydaughter1 <- (SpinWave (charge ?charge_daughter1) (parent ?id)) 
   ?mydaughter2 <- (SpinWave (charge ?charge_daughter2) (parent ?id)) 
   =>)