流口水规则实施

Drools rule implementation

我有一个规则,不知道是否可以在drools中实现。

说明:ALP都是facts/POJOs,是连在一起的。我需要找出每个 A 是否可以通过 L 分配给一个免费的 P。如果没有,还有多少 A 个元素未分配。

在上述情况下 A 将保留未分配。

我想到了一个简单描述的算法:

  1. 找到边数最少的 A

    • 如果A没有边,结果计数器加1,移除A
  2. A 中随机选择 L->P 并删除 A, L, P 元素

  3. 重复直到没有 A 剩余

我很难用流口水来描述它。我不是流口水规则方面的专家。在 JAVA 中,您必须对集合进行大量操作,包括排序,而 drools 似乎不支持这些操作。是否有可能以某种方式在 drools 中执行此操作?

这是一组实现算法的规则。它在大量 As 和 Ps 上不是很有效。一个纯粹的 Java 解决方案也不应该那么困难。请注意,从集合中删除一个 A 并清除所有悬挂的 L 和 P 对象后,不需要进行完整排序。

rule findMin
when
    $mina: A( $edges: edges )
    not A( edges.size() < $edges.size() )
then
    System.out.println( "retract " + $mina );
    retract( $mina );
end

rule countFail extends findMin
when
    eval( $edges.size() == 0 )
then
    Main.counter++;
    System.out.println( "fail to match " + $mina );
end

rule matchLP extends findMin
when
    $l: L( this memberOf $edges, $p: p )
then
    retract( $p );
    retract( $l );
    System.out.println( "retract " + $p + " and " + $l );
end

rule cleanup
salience 10
when
    $l: L( $p: p )
    not P( this == $p )
    $a: A( edges contains $l )
then
    retract( $l );
    modify( $a ){
        remove( $l );
    }
    System.out.println( "cleanup " + $l + ", " + $a );
end