[英]Sort list based on time in Optaplanner constraint
我有一个用例,我想将销售人员分配给约会列表。 现在,这些销售人员必须从一个地方到另一个地方才能到达约会地点。 我正在使用 Optaplanner 将销售人员列表安排到一堆约会中。 我定义了一个约束:
Next appointment start time should be after previous appointment's end time + travel time to reach the next appointment + Grace time
Constraint nextApptConflict(ConstraintFactory constraintFactory) {
return constraintFactory
// Select each pair of 2 different appointments ...
.forEachUniquePair(Appointment.class,
Joiners.equal((appt) -> appt.getRep().getUuid()))
//Sort the result based on appointment start time
//Check for time gap is feasible or not
// ... and penalize each pair with a hard weight.
.penalize(HardSoftScore.ONE_HARD)
.asConstraint("SalesRep conflict");
}
这个想法是首先获取分配给每个销售代表的所有约会,然后根据约会开始时间对结果进行排序,然后检查违规情况(如果有)并进行相应的处罚。 但是,我不确定我们如何对约束 class 中的约会进行排序,我是否应该将约会分组或Joiners.equal((appt) -> appt.getRep().getUuid())
是否也正确?
编辑:我已经按照@lukas 的建议添加了代码,但出现以下错误
Constraint nextApptConflict(ConstraintFactory constraintFactory) {
// A sales-rep can accommodate at most one appointment at the same time.
return constraintFactory
// Select each pair of 2 different appointments ...
.forEachUniquePair(Appointment.class,
Joiners.equal((appt) -> appt.getRep().getUuid()),
Joiners.greaterThanOrEqual((appt) -> appt.getEndTime()))
.ifNotExists(Appointment.class, Joiners.greaterThanOrEqual((appt) -> appt.getEndTime()))
.filter((appt1, appt2) -> {
int timeInSec = Utility.getTime(Utility.distance(appt1.getPosition(), appt2.getPosition()));
Timestamp minReachTime = new Timestamp(appt1.getEndTime().getTime() + (timeInSec+GRACE_TIME_SEC) * 1000);
return appt2.getStartTime().before(minReachTime);
})
// ... and penalize each pair with a hard weight.
.penalize(HardSoftScore.ONE_HARD)
.asConstraint("SalesRep conflict");
}
我做错了什么吗?
编辑 2:
Constraint nextApptConflict(ConstraintFactory constraintFactory) {
// A sales-rep can accommodate at most one appointment at the same time.
return constraintFactory
// Select each pair of 2 different appointments ...
.forEachUniquePair(Appointment.class,
Joiners.equal((appt) -> appt.getRep().getUuid()),
Joiners.greaterThanOrEqual((appt1) -> appt1.getStartTime(), (appt2)-> appt2.getEndTime()))
.ifNotExists(Appointment.class, Joiners.greaterThan((appt1, appt2) -> appt2.getStartTime(), (appt3) -> appt3.getEndTime()))
.filter((appt1, appt2) -> {
int timeInSec = Utility.getTime(Utility.distance(appt1.getPosition(), appt2.getPosition()));
Timestamp minReachTime = new Timestamp(appt1.getEndTime().getTime() + (timeInSec+GRACE_TIME_SEC) * 1000);
return appt2.getStartTime().before(minReachTime);
})
// ... and penalize each pair with a hard weight.
.penalize(HardSoftScore.ONE_HARD)
.asConstraint("SalesRep conflict");
}
你不需要对任何东西进行排序。 您确实需要更好地指定您的唯一对:
forEach
)。join
一些lessThan
/ greaterThan
加入者)。ifNotExists
)。这将为您提供所有对的连续约会。 剩下的就是根据第一个结束和下一个开始之间的差异进行惩罚。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.