如何在CLIPS 6.40 Beta中处理重叠规则实现单正确聚类结果输出
CLIPS 重叠规则触发的解决方法
这类重叠触发是CLIPS Rete网络下的常见问题:当两条规则的模式约束没有设置互斥关系时,落在重叠域内的坐标会同时生成两个独立激活,按默认的agenda调度逻辑(同优先级下按规则定义顺序执行)就会输出两个聚类结果。针对你的场景(重叠域坐标优先归属cluster0),可以根据维护需求选三类落地实现:
- 方案1:从规则约束层面消除重叠触发域,零额外运行开销
直接给低优先级的cluster23规则加排除条件,把所有会被cluster03捕获的坐标从cluster23的匹配域里剔除,CLIPS会在模式匹配阶段就直接过滤掉重叠区的匹配,不会生成无效激活。修改后的规则代码:
这种方式下,(defrule cluster23 (and (x ?x & :(&<= ?x 0.91)) (y ?y & :(&> ?y 1.35)) ;; 新增排除逻辑:不匹配属于cluster03触发域的坐标 (not (and (x ?x & :(&> ?x -1.16)) (y ?y & :(&> ?y 2.77)))) ) => (assert (cluster 2)) )(0,4)这类落在重叠域的坐标,会直接触发cluster23的not条件失效,不会生成对应激活,自然只输出cluster0的结果。方案优势是规则定义和业务聚类边界一一对应,没有额外工作内存开销,性能最好,适合规则边界固定的生产场景。 - 方案2:全局互斥前置条件+规则优先级,维护成本最低
给所有聚类规则加统一的前置约束:工作内存中不存在已断言的聚类结果事实,同时给优先级更高的cluster03设置更高的salience值。修改后的规则:
机制说明:当;; 高优先级规则,salience值高于cluster23 (defrule cluster03 (declare (salience 10)) (and (not (cluster ?any-cluster)) ;; 无已生成聚类结果时才允许触发 (x ?x & :(&> ?x -1.16)) (y ?y & :(&> ?y 2.77)) ) => (assert (cluster 0)) ) ;; 低优先级规则,默认salience为0 (defrule cluster23 (and (not (cluster ?any-cluster)) ;; 同样的全局互斥约束 (x ?x & :(&<= ?x 0.91)) (y ?y & :(&> ?y 1.35)) ) => (assert (cluster 2)) )(0,4)同时匹配两条规则时,CLIPS会把salience更高的cluster03激活排在agenda最前面优先执行;执行后在工作内存中新增(cluster 0)事实,原本排在agenda上的cluster23激活,会因为前置的(not (cluster ?any-cluster))条件失效,被Rete网络自动从agenda上撤回,根本不会执行。这个方案不需要计算规则之间的重叠域,后续新增聚类规则只要加上统一的前置约束和对应优先级即可,适合规则数量多、边界经常调整的场景。 - 方案3:高优先级规则触发时清理无效激活,适合快速调试场景
如果不想修改原有规则的模式约束,可以在高优先级的cluster03规则的动作部分,加上对低优先级规则激活的清理逻辑:
这个方案适合临时调试用,缺点是如果后续新增重叠的规则,需要手动给高优先级规则补(defrule cluster03 (and (x ?x & :(&> ?x -1.16)) (y ?y & :(&> ?y 2.77))) => (assert (cluster 0)) ;; 清除当前agenda上所有低优先级聚类规则的待执行激活 (remove-activations cluster23) )remove-activations逻辑,长期维护容易漏,不推荐生产环境使用。
常见误区提醒:不要仅通过设置
salience值就期望重叠规则不会触发。CLIPS的Rete机制会将所有满足模式的规则激活都纳入agenda,salience仅决定激活的执行顺序,不会主动删除已经生成的激活,必须配合显式的互斥约束才能实现单结果输出。
内容的提问来源于stack exchange,提问作者mickk
相关产品推荐
相关产品推荐

