【问题标题】:CLIPS huge memory usageCLIPS 大量内存使用
【发布时间】:2016-01-05 15:12:03
【问题描述】:

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

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

史蒂夫

; 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))
        )
    )

    )
    )
    )
)

【问题讨论】:

    标签: memory clips consumption


    【解决方案1】:

    您发布的代码片段不会消耗大量内存(小于 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)) 
       =>)
    

    【讨论】:

    • 嗨,加里,感谢您的快速回复。你说的对。我有几条规则(现在总共 5 条,但它们会增加)看起来像这样,并将生成您提到的部分匹配: (defrule check-charge ?mymother
    • 对不起,风格不好的评论,但我不能再编辑它了。顺便说一句,我在没有其他规则的情况下再次检查了内存消耗,启动剪辑只有 1.7 mb,代码只使用了 100kb跨度>
    猜你喜欢
    • 2012-01-13
    • 2023-03-24
    • 1970-01-01
    • 2011-11-06
    • 2010-11-13
    • 2014-11-02
    • 2014-04-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多