简体   繁体   English

如何在OptaPlanner中添加约束一辆车只能在一个方向上go?

[英]How to add constraint one car can only go in one direction in OptaPlanner?

  • Each employee has a direction in which he works.每个员工都有一个工作方向。
  • Each car can travel in one direction.每辆车都可以单向行驶。 If an employee who works in direction A was added to the car, then only employees who work in the same direction should be in it如果将一个在A方向工作的员工添加到汽车上,那么只有在同一方向工作的员工才应该在车上
@PlanningEntity
public class Employee {

    @PlanningId
    private Long id;

    private String direction;

    @PlanningVariable(valueRangeProviderRefs = "vehicleRange")
    private Vehicle vehicle;

}

@PlanningEntity
public class Vehicle {

    @PlanningId
    private Long id;

    @InverseRelationShadowVariable(sourceVariableName = "vehicle")
    List<Employee> employees = new ArrayList<>();

    private String direction;

}

What is the best constraint for this?对此最好的约束是什么?

Since the car's direction is not builtin but defined by the first passenger, I'd go with an instance variable.由于汽车的方向不是内置的,而是由第一位乘客定义的,所以我会使用实例变量 go 。

  • When the car is instantiated, it's direction is not set (=null).当汽车被实例化时,它的方向没有设置(=null)。
  • When adding the first passenger check the direction of the car添加第一个乘客时检查汽车的方向
    • If it is null, the car's direction is set to the passengers' direction and the passenger is added.如果是null,则将车的方向设置为乘客的方向并添加乘客。
    • If it is non-null, compare the passenger's direction with the car's direction.如果不为空,则将乘客的方向与汽车的方向进行比较。
      • If directions match, add the passenger.如果方向匹配,请添加乘客。
      • If no match, reject the passenger.如果不匹配,则拒绝该乘客。
  • When removing passengers, check if the car is now empty.移走乘客时,检查汽车现在是否是空的。 If it is empty, change the direction to null.如果为空,则将方向改为null。

That would allow you to reuse a car once the passengers have left.这将允许您在乘客离开后重新使用汽车。

I think I have found a solution.我想我已经找到了解决办法。

private Constraint directionConflict(ConstraintFactory factory) {
    return factory.forEach(Employee.class)
        .groupBy(Employee::getVehicle)
        .filter(vehicle -> vehicle.getEmployees().stream()
            .anyMatch(employee -> !Objects.equals(employee.getDirection(),
                vehicle.getEmployees().get(0).getDirection())))
        .penalize("Direction conflict", HardMediumSoftLongScore.ONE_HARD);
}

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

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