繁体   English   中英

根据 Optaplanner 约束中的时间对列表进行排序

[英]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");
    }

你不需要对任何东西进行排序。 您确实需要更好地指定您的唯一对:

  • Select 第一次约会 ( forEach )。
  • Select 第二个约会在第一个约会结束后开始( join一些lessThan / greaterThan加入者)。
  • 确保两者之间没有第三次约会 ( ifNotExists )。

这将为您提供所有对的连续约会。 剩下的就是根据第一个结束和下一个开始之间的差异进行惩罚。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM