流口水,累加总和然后最大值

Drools, accumulate sum and then max

我的 java class 任务有成员 groupId(String) 和 duration(long)。各组任务时长之和,假设group1有task1、task2、task3,对应的时长为d1、d2、d3,所以sum=d1+d2+d3;我想得到所有组中最大的 s,比如 group1 的总和是 s1,group2 是 s2,我想得到 $smax = max(s1,s2,...) 然后在 $smax 上做一些事情在“然后”。我怎样才能做到这一点?没有组class,用一个名为groupId的String来标识同一个组。如何指定“same-group-id”?一定要介绍组class吗?以及如何获得$smax?非常感谢。

when
  accumulate(Task("same-group-id", $d: duration);
            $s: sum($d))
  accumulate($smax: max($s))
then
  // do something with $smax

进一步的问题。 Roddy 的回答在 drools 中非常有效。但在我的例子中,它是在 Optaplanner 中使用的,所以 Task 必须出现在“when”中,否则规则将不会被触发。有什么办法可以将 Roddy 的两条规则合二为一吗?目标仍然是在“then”中获得最大的组持续时间,以便可以在其上做一些事情。如果需要,我可以在 java 中进行更改。

你这里有一些文字墙,但我会尝试解析你正在尝试做的事情。

  • 您的工作内存中有任务对象,成员 String groupIdlong duration
  • 您想按 groupId 对任务进行分组,然后对每个组的持续时间求和。 --> 基本上得到每组的总持续时间。
  • 最后,您想找到最长的总时长。 --> 实际上,您想知道哪个组的持续时间最长。

如果我避免在我的 accumulate 中使用内联自定义代码,我可能会这样做:

declare GroupDuration {
  id : String
  duration : long
}

rule "Find Group Durations"
salience 1
when
  Task( $id: groupId )
  not( GroupDuration( id == $id ))
  accumulate( Task( groupId == $id, $d: duration);
              $duration: sum($d))
then
  GroupDuration d = new GroupDuration();
  d.setId($id);
  d.setDuration($duration);
  insert(d)
end

rule "Find Longest Group Duration"
when
  GroupDuration( $id: id, $duration: duration )
  not( GroupDuration( duration > $duration ))
then
  // $id is the longest
end

我首先声明一个新类型 GroupDuration 来跟踪组的 ID 和总持续时间。然后我用第一条规则中的这些持续时间填充工作内存,使用 accumulate 总结具有匹配 ID 的任务的所有持续时间。最后,我找到持续时间最长的实例并抽取它的 id。