多日车辆路线 - 使用具有较小日期索引的车辆

时间:2017-12-04 07:19:13

标签: java optaplanner

我尝试基于optaplanner车辆路线示例构建多日车辆路线。我创建了VehicleDay类来为一天的旅行建模车辆。 VehicleDay类是Vehicle对象和Day对象的连接。 这是课程:

public class Day extends AbstractPersistable {
    protected int dayIndex;
    protected int dayInt;
    protected String day;

    // getter and setter methods
    ...
}

public class Vehicle extends AbstractPersistable {
    protected int capacity;
    protected Depot depot;

    // getter and setter methods
    ...
}

public class VehicleDay extends AbstractPersistable implements Standstill {
    protected Vehicle vehicle;
    protected Day day;

    // Shadow variables
    protected Customer nextCustomer;

    // getter and setter methods
    ...
}

我将计划实体从Vehicle移到了VehicleDay。然后我尝试创建一个样本数据集(cvrp-72customers-edited.xml),其中包含8个车辆日和71个客户。我从cvrp-72customers获取此样本数据集,并将车辆容量修改为仅原始数据的3/4(22000)。 8个车辆日包括:

  1. 第1天(星期一)的车辆ID 1
  2. 第2天(星期二)的车辆ID 1
  3. 第1天(星期一)的车辆ID 2
  4. 第2天(星期二)的车辆ID 2
  5. 第1天(星期一)的车辆ID 3
  6. 第2天(星期二)的车辆ID 3
  7. 第1天(星期一)的车辆ID 4
  8. 第2天(星期二)的车辆识别码4
  9. 但是当我试图运行它时,结果是第1天的某些车辆没有被使用,而是计划者从第2天开始使用一些车辆(cvrp-72customers-edited-solved.xml)。我试图实现的是,计划者在第1天使用车辆,在使用第1天的所有车辆之后,然后计划员在第2天开始使用车辆。我尝试使用Comparator并创建了StandstillDifficultyComparator类:

    public class StandstillDifficultyComparator implements Comparator<Standstill>, Serializable {
    
        @Override
        public int compare(Standstill a, Standstill b) {
            if (a instanceof Customer) {
                return new CompareToBuilder()
                        .append(((Customer)a).getId(), ((Customer)b).getId())
                        .toComparison();    
            } else {
                return new CompareToBuilder()
                        .append(((VehicleDay)a).getDay().getDayIndex(), ((VehicleDay)b).getDay().getDayIndex())
                        .append(((VehicleDay)a).getId(), ((VehicleDay)b).getId())
                        .toComparison();    
            }        
        }
    
    }
    

    然后在unionMoveSelector配置中,我添加我的比较器类,如下所示:

    <unionMoveSelector>
          <changeMoveSelector>
            <entitySelector>
                <cacheType>PHASE</cacheType>
                <selectionOrder>SORTED</selectionOrder>
                <sorterComparatorClass>org.optaplanner.examples.vehiclerouting.domain.solver.StandstillDifficultyComparator</sorterComparatorClass>
                <sorterOrder>ASCENDING</sorterOrder>
            </entitySelector>
          </changeMoveSelector>
          <swapMoveSelector>
            <entitySelector>
                <cacheType>PHASE</cacheType>
                <selectionOrder>SORTED</selectionOrder>
                <sorterComparatorClass>org.optaplanner.examples.vehiclerouting.domain.solver.StandstillDifficultyComparator</sorterComparatorClass>
                <sorterOrder>ASCENDING</sorterOrder>
            </entitySelector>
          </swapMoveSelector>
          <tailChainSwapMoveSelector>
            <entitySelector>
                <cacheType>PHASE</cacheType>
                <selectionOrder>SORTED</selectionOrder>
                <sorterComparatorClass>org.optaplanner.examples.vehiclerouting.domain.solver.StandstillDifficultyComparator</sorterComparatorClass>
                <sorterOrder>ASCENDING</sorterOrder>
            </entitySelector>      
          </tailChainSwapMoveSelector>
          <subChainChangeMoveSelector>
            <selectReversingMoveToo>true</selectReversingMoveToo>
            <entitySelector>
                <cacheType>PHASE</cacheType>
                <selectionOrder>SORTED</selectionOrder>
                <sorterComparatorClass>org.optaplanner.examples.vehiclerouting.domain.solver.StandstillDifficultyComparator</sorterComparatorClass>
                <sorterOrder>ASCENDING</sorterOrder>
            </entitySelector>
          </subChainChangeMoveSelector>
          <subChainSwapMoveSelector>
            <selectReversingMoveToo>true</selectReversingMoveToo>
            <entitySelector>
                <cacheType>PHASE</cacheType>
                <selectionOrder>SORTED</selectionOrder>
                <sorterComparatorClass>org.optaplanner.examples.vehiclerouting.domain.solver.StandstillDifficultyComparator</sorterComparatorClass>
                <sorterOrder>ASCENDING</sorterOrder>
            </entitySelector>
          </subChainSwapMoveSelector>
        </unionMoveSelector>
    

    当我运行它时,会抛出异常:

    Exception in thread "main" java.lang.IllegalArgumentException: Unmarshalling of solverConfigResource (org/optaplanner/examples/vehiclerouting/solver/vehicleRoutingSolverConfig.xml) fails on line number (53).
        at org.optaplanner.core.impl.solver.XStreamXmlSolverFactory.configure(XStreamXmlSolverFactory.java:123)
        at org.optaplanner.core.api.solver.SolverFactory.createFromXmlResource(SolverFactory.java:90)
        at org.optaplanner.examples.common.app.CommonApp.createSolver(CommonApp.java:102)
        at org.optaplanner.examples.common.app.CommonApp.createSolutionBusiness(CommonApp.java:97)
        at org.optaplanner.examples.common.app.CommonApp.init(CommonApp.java:84)
        at org.optaplanner.examples.common.app.CommonApp.init(CommonApp.java:80)
        at org.optaplanner.examples.vehiclerouting.app.VehicleRoutingApp.main(VehicleRoutingApp.java:34)
    Caused by: " com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter$UnknownFieldException: No such field org.optaplanner.core.config.heuristic.selector.move.generic.chained.SubChainChangeMoveSelectorConfig.entitySelector
    ---- Debugging information ----
    message             : No such field org.optaplanner.core.config.heuristic.selector.move.generic.chained.SubChainChangeMoveSelectorConfig.entitySelector
    field               : entitySelector
    class               : org.optaplanner.core.config.heuristic.selector.move.generic.chained.SubChainChangeMoveSelectorConfig
    required-type       : org.optaplanner.core.config.heuristic.selector.move.generic.chained.SubChainChangeMoveSelectorConfig
    converter-type      : com.thoughtworks.xstream.converters.reflection.ReflectionConverter
    line number         : 53
    class[1]            : org.optaplanner.core.config.heuristic.selector.move.composite.UnionMoveSelectorConfig
    class[2]            : org.optaplanner.core.config.localsearch.LocalSearchPhaseConfig
    class[3]            : org.optaplanner.core.config.solver.SolverConfig
    version             : 1.4.10
    -------------------------------
        at org.optaplanner.core.impl.solver.XStreamXmlSolverFactory.configure(XStreamXmlSolverFactory.java:123)
        at org.optaplanner.core.api.solver.SolverFactory.createFromXmlResource(SolverFactory.java:90)
        at org.optaplanner.examples.common.app.CommonApp.createSolver(CommonApp.java:102)
        at org.optaplanner.examples.common.app.CommonApp.createSolutionBusiness(CommonApp.java:97)
        at org.optaplanner.examples.common.app.CommonApp.init(CommonApp.java:84)
        at org.optaplanner.examples.common.app.CommonApp.init(CommonApp.java:80)
        at org.optaplanner.examples.vehiclerouting.app.VehicleRoutingApp.main(VehicleRoutingApp.java:34)
    

    如何让计划员在第1天首先使用所有车辆,然后在第2天使用车辆?

1 个答案:

答案 0 :(得分:1)

我认为您需要创建一个评分规则,奖励OptaPlanner按顺序安排日期。所以在规则中你可以说,如果第X-1天尚未满,那么在第X天预定的每辆车都会扣除一分。