我使用的OptaPlanner有两个规划变量,其中一个定义为nullable=true。遵循会议示例(为简单起见),假设Room可以为空,但Time不能为空。
我在非空的time
变量上定义了一个约束,但似乎只有当可空的room
变量不为空时,惩罚才起作用,否则会失败。
下面是我的代码片段:
@PlanningEntity
public class Meeting {
@PlanningVariable(valueRangeProviderRefs = "time")
private LocalDateTime time;
@PlanningVariable(valueRangeProviderRefs = "availableRooms", nullable = true)
private Room room;
private long personId;
...
}
在我的约束提供者类中,我定义了以下约束来确保一个人不能参加两个单独的会议:
protected Constraint samePersonAndTimeConflict(ConstraintFactory constraintFactory) {
return constraintFactory
// Select each pair of 2 different meetings ...
.forEachUniquePair(Meeting.class,
// ... for the same person ...
equal(Meeting::getPersonId),
// ... in the same time ...
equal(Meeting::getDateTime))
// ... and penalize each pair with a hard weight.
.penalize(SAME_PERSON_AND_TIME_CONFLICT, HardSoftScore.ONE_HARD);
}
当创建两个具有非空值的对象时,如果假设同一个人同时参加两个单独的会议,则该约束将很好地工作,并以一个硬分数惩罚。然而,当处理可为null的房间变量确实为null的对象时,没有惩罚。结果是,我得到了一个解决方案,其中许多情况下,同一个人有相同的时间分配。
我还尝试了用其他方式处理约束,例如使用“forEachIncludingNullVars”和“forEach”,但我看到了相同的结果:
protected Constraint samePersonAndTimeConflict(ConstraintFactory constraintFactory) {
return constraintFactory
.forEachIncludingNullVars(Meeting.class)
//.filter(meeting -> meeting.getDateTime() != null)
.join(Meeting.class,
lessThan(Meeting::getId),
equal(Meeting::getTime),
equal(Meeting::getPersonId)) //,
.penalize(SAME_PERSON_AND_TIME_CONFLICT, HardSoftScore.ONE_HARD);
我还尝试将分数类更改为HardMediumSoftScore,并通过一个中等惩罚。对于没有会议室的会议,仍然没有处罚。
OptaPlanner似乎根本没有发挥应有的作用。在这一点上,我不知道我还能尝试什么。请建议。
***编辑***
按照下面的建议,使用嵌套的constraintFactory和附加的foreachingcludingnullvars子句,我最终实现了我的约束,如下所示——现在它可以工作了:
protected Constraint samePersonAndTimeConflict(ConstraintFactory constraintFactory) {
final Constraint constraint = constraintFactory.forEachIncludingNullVars(Meeting.class)
.join(
constraintFactory.forEachIncludingNullVars(Meeting.class)
.filter(meeting -> meeting.getTime() != null),
lessThan(WorkDay::getId),
equal(WorkDay::getEmployeeId),
equal(WorkDay::getDate))
.penalize("Same person and time conflict", HardMediumSoftScore.ONE_HARD);
return constraint;
}
forEach()
在这里不起作用,因为这只会给您提供没有任何变量为null的实体foreachingcludingnullvars()
是一种方法。但是您还需要了解,join与forEach具有相同的行为-它不包括具有空变量的实体。
要考虑到这一点,您需要使用嵌套流连接,如下所示:
protected Constraint samePersonAndTimeConflict(ConstraintFactory constraintFactory) {
return constraintFactory
.forEachIncludingNullVars(Meeting.class)
.join(
constraintFactory.forEachIncludingNullVars(Meeting.class),
// add your joiners here
).penalize(SAME_PERSON_AND_TIME_CONFLICT, HardSoftScore.ONE_HARD);
}
这样,连接将创建所有实体的交叉乘积,而不管它们的任何变量是否为空。然后,它就变成了filter
剔除您不希望看到空值的部分的问题。
问题内容: 在Eclipse下开发Java应用程序时,我收到有关“通过综合方法访问方法/值”的警告。解决方案只是将私有访问修饰符更改为默认级别。 这让我想知道:使用合成方法会受到什么惩罚?有一些?我认为编译器/ Eclipse会发出警告,但是它是否如此相关或可以安全地忽略? 我在这里没有看到这些信息,所以我问。 问题答案: Eclipse警告您,您可能会公开您认为是私有的信息。如下所示,恶意代码可
管道分支惩罚是ALU和IF之间非零距离的结果。 这句话是什么意思?
问题内容: 我看过布兰登·罗德斯(Brandon Rhodes)关于Cython的谈话-“ EXE的日子即将到来”。 布兰登在09:30提到对于一段特定的短代码,跳过解释可以使速度提高40%,而跳过分配和分配可以使速度提高574%(10:10)。 我的问题是-如何测量特定代码段?是否需要手动提取基础的c命令,然后以某种方式使运行时运行它们? 这是一个非常有趣的观察,但是如何重新创建实验? 问题答案
考虑以下几点: 为什么第一个版本是编译错误,当我已经声明lambda是可变的,并通过值捕获(我认为是它的副本)? 使用clang(x86_64-apple-darwin14.3.0)和Visual C(vc120)进行测试,这是错误消息的来源。
问题内容: from celery import Celery 这是我用来测试芹菜的代码。我希望每次使用addone()时,返回值都应该增加。但是为什么总是1? 结果 问题答案: 默认情况下,启动工作程序时,Celery以并发4启动它,这意味着它已启动4个进程来处理任务请求。(加上一个控制其他进程的进程。)我不知道该使用哪种算法将任务请求分配给为工作人员启动的进程,但是最终,如果执行足够,您将看到
我想使用Boost.Range和带有init-capture的C 1y lambdas来计算两个向量的元素差异。减去一个向量的固定(即第一个)元素的更简单情况是有效的。但是,当我尝试通过在第二个范围上增加迭代器(并使lambda可变)来计算“矢量化差异”时,我得到一个编译器错误。示例代码(请注意,我没有使用通用的 lambda,因此 g 4.8 和 Clang SVN 都可以解析此代码): 活生生