tl;dr在起诉书列表中,是否有一种方法可以仅包含(例如)来自BiConstraintStream<A, B>
的对象A
?除了这个问题之外,是否可以在ProblemFact
的构造期间在ProblemFact
上设置对PlanningEntity
s 的引用,以便稍后在计算期间快速引用它们?
完整的问题:
我目前有一个约束,看起来大致如下:
return constraintFactory
.forEach(Partition.cl)
.groupBy(Partition::getStudent, toList())
.filter((student, partitions) -> student.getMinEnrollments() != null)
.penalize("Not enough hours enrolled",
HardSoftScore.ONE_SOFT,
(student, partitionList) -> student.getMinEnrollments() - partitionList.stream().filter(Partition::getEnrolled).count();
);
这给了我我想要的惩罚,在我的情况下,对每个没有足够注册的学生的惩罚。
解决后,当我查看起诉书清单时,我看到类似
-12soft: justification (STUDENT_1) has 1 matches:
-12soft: constraint (Not enough hours enrolled)
-12soft: justification ([List, Of, Partition, Objects, ...]) has 1 matches:
-12soft: constraint (Not enough hours enrolled)
-8soft: justification (STUDENT_2) has 1 matches:
-8soft: constraint (Not enough hours enrolled)
...
这对我来说(一些实验似乎证实了这一点),(Uni,Bi,Tri,Quad)ConstraintStream 的每个部分都在起诉书列表中,我想这在某种程度上是有意义的。
在我的用例中(因为我想使用起诉书列表),对于这个约束,我只希望学生出现在这个列表中,而不是参与列表。
我尝试过的一件事是创建一个 BiConstraintStream & lt;学生,整数 & gt;其中“整数”是我想要设置的惩罚,并以类似的结尾
.penalize("Not enough hours enrolled",
HardSoftScore.ONE_SOFT,
(student, penalty) -> penalty
);
这在理论上是有效的(结果正确),但我仍然得到原始数据作为我的起诉书清单的一部分。
最后我尝试的是,在我的 PlanningSolution 的构建过程中,我设置了一个列表Partition
对象(我的PlanningEntity
s)在我的Student
对象是 ProblemFacts。
return constraintFactory
.forEach(Student.cl)
.filter(student -> student.getMinEnrollments() != null)
.penalize("Not enough hours enrolledv2",
HardSoftScore.ONE_SOFT,
(student) -> student.getMinEnrollments() - student.getPartitions().filter(Partition::getEnrolled).count();
);
我想这将是更有效的,因为我在初始化时间预先计算参与和学生之间的关系,而不是在每个惩罚计算(学生不是参与计划变量,所以没有问题)。
然而,这是行不通的,因为在约束计算点 student.getPartitions()对象不再对应于我最初构建的 PlanningEntities(我猜 Optaplanner 做了一些克隆这些对象,这意味着引用不能这样使用?)
有没有办法实现我想要的?另请参阅上面的 tl;dr。
本站系公益性非盈利分享网址,本文来自用户投稿,不代表边看边学立场,如若转载,请注明出处
评论列表(61条)