Решение Jsprit не является правильным, если поставки имеют несколько размеров измерения - PullRequest
0 голосов
/ 03 января 2019

Я новичок в Jsprit. Я пытался использовать размер нескольких размеров в моем списке отгрузки. Например, для некоторых отправлений я добавил размер измерения с помощью WHEELCHAIRSPACE_INDEX, а для некоторых отправлений я использую PASSENGERSEATS_INDEX в моем createJob (). Однако вывод кажется неправильным.

public class Test {

static int WHEELCHAIRSPACE_INDEX = 0;

static int PASSENGERSEATS_INDEX = 1;

private VehicleType vehicleType_wheelchair;

private VehicleType vehicleType_solelypassenger;

private VehicleImpl vehicle1,vehicle1_2,vehicle2,vehicle2_2;

private VehicleRoutingProblem.Builder vrpBuilder;

private HardRouteConstraint wheelchair_bus_passenger_pickup_constraint;

private VehicleRoutingAlgorithm algorithm;

private VehicleRoutingProblem problem;

private VehicleRoutingTransportCosts costMatrix;

private static final String FILENAME = "C:\\Users\\admin\\Desktop\\test.txt";

public static void main(String[] args) {
    // TODO Auto-generated method stub
    Examples.createOutputFolder();
    Test test = new Test();
    test.createVehicleType();
    test.createVehicle();
    test.createJob();
    test.createConstraint();
    test.createProblem();
    test.searchSolution();
}

private void searchSolution() {
    Collection<VehicleRoutingProblemSolution> solutions = algorithm.searchSolutions();
    VehicleRoutingProblemSolution bestSolution = Solutions.bestOf(solutions);
    SolutionPrinter.print(problem, bestSolution, SolutionPrinter.Print.VERBOSE);

    Plotter problemPlotter = new Plotter(problem);
    problemPlotter.plotShipments(true);
    problemPlotter.setLabel(Plotter.Label.SIZE);
    problemPlotter.plot("output/transportOfDisabledPeopleExample_problem.png", "disabled people tp");

    Plotter solutionPlotter = new Plotter(problem, Solutions.bestOf(solutions));
    solutionPlotter.plotShipments(true);
    solutionPlotter.setLabel(Plotter.Label.SIZE);
    solutionPlotter.plot("output/transportOfDisabledPeopleExample_solution.png", "disabled people tp");


}

private void createProblem() {


    StateManager stateManager = new StateManager(problem);

    ConstraintManager constraintManager = new ConstraintManager(problem, stateManager);
    constraintManager.addConstraint(wheelchair_bus_passenger_pickup_constraint);


    algorithm = Jsprit.Builder.newInstance(problem).setStateAndConstraintManager(stateManager,constraintManager).buildAlgorithm();
    algorithm.setPrematureAlgorithmTermination(new IterationWithoutImprovementTermination(100));
}

private void createConstraint() {
    wheelchair_bus_passenger_pickup_constraint = new HardRouteConstraint() {

        @Override
        public boolean fulfilled(JobInsertionContext insertionContext) {

            return true;
        }
    };
}

private void createJob() {
    com.graphhopper.jsprit.core.problem.job.Shipment.Builder builder1 = Shipment.Builder.newInstance("1");
    builder1.addSizeDimension(WHEELCHAIRSPACE_INDEX, 1);
    builder1.setPickupLocation(Location.newInstance("1a"));
    builder1.setDeliveryLocation(Location.newInstance("1b"));
    builder1.setDeliveryServiceTime(0);

    Shipment shipment1 = builder1.build();

    com.graphhopper.jsprit.core.problem.job.Shipment.Builder builder2 = Shipment.Builder.newInstance("2");
    builder2.addSizeDimension(PASSENGERSEATS_INDEX, 1);
    builder2.setPickupLocation(Location.newInstance("2a"));
    builder2.setDeliveryLocation(Location.newInstance("2b"));
    builder2.setDeliveryServiceTime(0);

    Shipment shipment2 = builder2.build();

    com.graphhopper.jsprit.core.problem.job.Shipment.Builder builder3 = Shipment.Builder.newInstance("3");
    builder3.addSizeDimension(WHEELCHAIRSPACE_INDEX, 1);
    builder3.setPickupLocation(Location.newInstance("3a"));
    builder3.setDeliveryLocation(Location.newInstance("3b"));
    builder3.setDeliveryServiceTime(0);

    Shipment shipment3 = builder3.build();

    com.graphhopper.jsprit.core.problem.job.Shipment.Builder builder4 = Shipment.Builder.newInstance("4");
    builder4.addSizeDimension(PASSENGERSEATS_INDEX, 1);
    builder4.setPickupLocation(Location.newInstance("4a"));
    builder4.setDeliveryLocation(Location.newInstance("4b"));
    builder4.setDeliveryServiceTime(0);

    Shipment shipment4 = builder4.build();

    com.graphhopper.jsprit.core.problem.job.Shipment.Builder builder5 = Shipment.Builder.newInstance("5");
    builder5.addSizeDimension(WHEELCHAIRSPACE_INDEX, 1);
    builder5.setPickupLocation(Location.newInstance("5a"));
    builder5.setDeliveryLocation(Location.newInstance("5b"));
    builder5.setDeliveryServiceTime(0);

    Shipment shipment5 = builder5.build();

    setTransportCost();

    vrpBuilder = VehicleRoutingProblem.Builder.newInstance();
    vrpBuilder.addVehicle(vehicle1);
    vrpBuilder.addVehicle(vehicle2);
    vrpBuilder.addVehicle(vehicle1_2);
    vrpBuilder.addVehicle(vehicle2_2);
    vrpBuilder.addJob(shipment1).addJob(shipment2).addJob(shipment3).addJob(shipment4);
    vrpBuilder.addJob(shipment5);

    vrpBuilder.setFleetSize(FleetSize.FINITE);
    vrpBuilder.setRoutingCost(costMatrix);
    problem = vrpBuilder.build();

}

private void setTransportCost() {
    // TODO Auto-generated method stub
    VehicleRoutingTransportCostsMatrix.Builder costMatrixBuilder = VehicleRoutingTransportCostsMatrix.Builder.newInstance(true);

    costMatrixBuilder.addTransportTime("0", "0", 0.0);
    costMatrixBuilder.addTransportTime("0", "1a", 2.0);
    costMatrixBuilder.addTransportTime("0", "1b", 3.3);
    costMatrixBuilder.addTransportTime("0", "2a", 2.0);
    costMatrixBuilder.addTransportTime("0", "2b", 4.3);
    costMatrixBuilder.addTransportTime("0", "3a", 3.5);
    costMatrixBuilder.addTransportTime("0", "3b", 3.0);
    costMatrixBuilder.addTransportTime("0", "4a", 1.5);
    costMatrixBuilder.addTransportTime("0", "4b", 2.7);
    costMatrixBuilder.addTransportTime("0", "5a", 1.2);
    costMatrixBuilder.addTransportTime("0", "5b", 3.5);

    costMatrixBuilder.addTransportTime("1a", "0", 2.0);
    costMatrixBuilder.addTransportTime("1a", "1a", 0.0);
    costMatrixBuilder.addTransportTime("1a", "1b", 2.5);
    costMatrixBuilder.addTransportTime("1a", "2a", 2.3);
    costMatrixBuilder.addTransportTime("1a", "2b", 4.4);
    costMatrixBuilder.addTransportTime("1a", "3a", 4.0);
    costMatrixBuilder.addTransportTime("1a", "3b", 4.0);
    costMatrixBuilder.addTransportTime("1a", "4a", 2.3);
    costMatrixBuilder.addTransportTime("1a", "4b", 4.5);
    costMatrixBuilder.addTransportTime("1a", "5a", 3.2);
    costMatrixBuilder.addTransportTime("1a", "5b", 1.5);

    costMatrixBuilder.addTransportTime("1b", "0", 3.3);
    costMatrixBuilder.addTransportTime("1b", "1a", 2.5);
    costMatrixBuilder.addTransportTime("1b", "1b", 0.0);
    costMatrixBuilder.addTransportTime("1b", "2a", 1.7);
    costMatrixBuilder.addTransportTime("1b", "2b", 2.2);
    costMatrixBuilder.addTransportTime("1b", "3a", 2.5);
    costMatrixBuilder.addTransportTime("1b", "3b", 3.4);
    costMatrixBuilder.addTransportTime("1b", "4a", 4.5);
    costMatrixBuilder.addTransportTime("1b", "4b", 5.0);
    costMatrixBuilder.addTransportTime("1b", "5a", 4.5);
    costMatrixBuilder.addTransportTime("1b", "5b", 2.2);

    costMatrixBuilder.addTransportTime("2a", "0", 2.0);
    costMatrixBuilder.addTransportTime("2a", "1a", 2.3);
    costMatrixBuilder.addTransportTime("2a", "1b", 1.7);
    costMatrixBuilder.addTransportTime("2a", "2a", 0.0);
    costMatrixBuilder.addTransportTime("2a", "2b", 2.3);
    costMatrixBuilder.addTransportTime("2a", "3a", 1.7);
    costMatrixBuilder.addTransportTime("2a", "3b", 1.8);
    costMatrixBuilder.addTransportTime("2a", "4a", 3.3);
    costMatrixBuilder.addTransportTime("2a", "4b", 3.2);
    costMatrixBuilder.addTransportTime("2a", "5a", 3.0);
    costMatrixBuilder.addTransportTime("2a", "5b", 2.9);

    costMatrixBuilder.addTransportTime("2b", "0", 4.3);
    costMatrixBuilder.addTransportTime("2b", "1a", 4.4);
    costMatrixBuilder.addTransportTime("2b", "1b", 2.2);
    costMatrixBuilder.addTransportTime("2b", "2a", 2.3);
    costMatrixBuilder.addTransportTime("2b", "2b", 0.0);
    costMatrixBuilder.addTransportTime("2b", "3a", 1.2);
    costMatrixBuilder.addTransportTime("2b", "3b", 2.8);
    costMatrixBuilder.addTransportTime("2b", "4a", 5.7);
    costMatrixBuilder.addTransportTime("2b", "4b", 4.5);
    costMatrixBuilder.addTransportTime("2b", "5a", 5.2);
    costMatrixBuilder.addTransportTime("2b", "5b", 4.3);

    costMatrixBuilder.addTransportTime("3a", "0", 3.5);
    costMatrixBuilder.addTransportTime("3a", "1a", 4.0);
    costMatrixBuilder.addTransportTime("3a", "1b", 2.5);
    costMatrixBuilder.addTransportTime("3a", "2a", 1.7);
    costMatrixBuilder.addTransportTime("3a", "2b", 1.2);
    costMatrixBuilder.addTransportTime("3a", "3a", 0.0);
    costMatrixBuilder.addTransportTime("3a", "3b", 1.5);
    costMatrixBuilder.addTransportTime("3a", "4a", 5.0);
    costMatrixBuilder.addTransportTime("3a", "4b", 3.3);
    costMatrixBuilder.addTransportTime("3a", "5a", 4.2);
    costMatrixBuilder.addTransportTime("3a", "5b", 4.3);

    costMatrixBuilder.addTransportTime("3b", "0", 3.0);
    costMatrixBuilder.addTransportTime("3b", "1a", 4.0);
    costMatrixBuilder.addTransportTime("3b", "1b", 3.4);
    costMatrixBuilder.addTransportTime("3b", "2a", 1.8);
    costMatrixBuilder.addTransportTime("3b", "2b", 2.8);
    costMatrixBuilder.addTransportTime("3b", "3a", 1.5);
    costMatrixBuilder.addTransportTime("3b", "3b", 0.0);
    costMatrixBuilder.addTransportTime("3b", "4a", 4.3);
    costMatrixBuilder.addTransportTime("3b", "4b", 1.8);
    costMatrixBuilder.addTransportTime("3b", "5a", 2.8);
    costMatrixBuilder.addTransportTime("3b", "5b", 5.0);

    costMatrixBuilder.addTransportTime("4a", "0", 1.5);
    costMatrixBuilder.addTransportTime("4a", "1a", 2.3);
    costMatrixBuilder.addTransportTime("4a", "1b", 4.5);
    costMatrixBuilder.addTransportTime("4a", "2a", 3.3);
    costMatrixBuilder.addTransportTime("4a", "2b", 5.7);
    costMatrixBuilder.addTransportTime("4a", "3a", 5.0);
    costMatrixBuilder.addTransportTime("4a", "3b", 4.3);
    costMatrixBuilder.addTransportTime("4a", "4a", 0.0);
    costMatrixBuilder.addTransportTime("4a", "4b", 3.6);
    costMatrixBuilder.addTransportTime("4a", "5a", 1.7);
    costMatrixBuilder.addTransportTime("4a", "5b", 3.8);

    costMatrixBuilder.addTransportTime("4b", "0", 2.7);
    costMatrixBuilder.addTransportTime("4b", "1a", 4.5);
    costMatrixBuilder.addTransportTime("4b", "1b", 5.0);
    costMatrixBuilder.addTransportTime("4b", "2a", 3.2);
    costMatrixBuilder.addTransportTime("4b", "2b", 4.5);
    costMatrixBuilder.addTransportTime("4b", "3a", 3.3);
    costMatrixBuilder.addTransportTime("4b", "3b", 1.8);
    costMatrixBuilder.addTransportTime("4b", "4a", 3.6);
    costMatrixBuilder.addTransportTime("4b", "4b", 0.0);
    costMatrixBuilder.addTransportTime("4b", "5a", 1.9);
    costMatrixBuilder.addTransportTime("4b", "5b", 5.7);

    costMatrixBuilder.addTransportTime("5a", "0", 1.2);
    costMatrixBuilder.addTransportTime("5a", "1a", 3.2);
    costMatrixBuilder.addTransportTime("5a", "1b", 4.5);
    costMatrixBuilder.addTransportTime("5a", "2a", 3.0);
    costMatrixBuilder.addTransportTime("5a", "2b", 5.2);
    costMatrixBuilder.addTransportTime("5a", "3a", 4.2);
    costMatrixBuilder.addTransportTime("5a", "3b", 2.8);
    costMatrixBuilder.addTransportTime("5a", "4a", 1.7);
    costMatrixBuilder.addTransportTime("5a", "4b", 1.9);
    costMatrixBuilder.addTransportTime("5a", "5a", 0.0);
    costMatrixBuilder.addTransportTime("5a", "5b", 4.7);

    costMatrixBuilder.addTransportTime("5b", "0", 3.5);
    costMatrixBuilder.addTransportTime("5b", "1a", 1.5);
    costMatrixBuilder.addTransportTime("5b", "1b", 2.2);
    costMatrixBuilder.addTransportTime("5b", "2a", 2.9);
    costMatrixBuilder.addTransportTime("5b", "2b", 4.3);
    costMatrixBuilder.addTransportTime("5b", "3a", 4.3);
    costMatrixBuilder.addTransportTime("5b", "3b", 5.0);
    costMatrixBuilder.addTransportTime("5b", "4a", 3.8);
    costMatrixBuilder.addTransportTime("5b", "4b", 5.7);
    costMatrixBuilder.addTransportTime("5b", "5a", 4.7);
    costMatrixBuilder.addTransportTime("5b", "5b", 0.0);

    costMatrix = costMatrixBuilder.build();
}

private void createVehicle() {
    Builder vehicleBuilder1 = VehicleImpl.Builder.newInstance("wheelchair_bus");
    vehicleBuilder1.setStartLocation(Location.newInstance("0")).setEndLocation(Location.newInstance("0"));
    vehicleBuilder1.setType(vehicleType_wheelchair);
    vehicleBuilder1.setEarliestStart(0);
    vehicleBuilder1.setLatestArrival(10);
    vehicle1 = vehicleBuilder1.build();

    Builder vehicleBuilder1_2 = VehicleImpl.Builder.newInstance("wheelchair_bus_2");
    vehicleBuilder1_2.setStartLocation(Location.newInstance("0")).setEndLocation(Location.newInstance("0"));
    vehicleBuilder1_2.setType(vehicleType_wheelchair);
    vehicleBuilder1_2.setEarliestStart(0);
    vehicleBuilder1_2.setLatestArrival(10);
    vehicle1_2 = vehicleBuilder1_2.build();

    Builder vehicleBuilder2 = VehicleImpl.Builder.newInstance("passenger_bus");
    vehicleBuilder2.setStartLocation(Location.newInstance("0")).setEndLocation(Location.newInstance("0"));
    vehicleBuilder2.setType(vehicleType_solelypassenger);
    vehicleBuilder2.setEarliestStart(0);
    vehicleBuilder2.setLatestArrival(10);
    vehicle2 = vehicleBuilder2.build();

    Builder vehicleBuilder2_2 = VehicleImpl.Builder.newInstance("passenger_bus_2");
    vehicleBuilder2_2.setStartLocation(Location.newInstance("0")).setEndLocation(Location.newInstance("0"));
    vehicleBuilder2_2.setType(vehicleType_solelypassenger);
    vehicleBuilder2_2.setEarliestStart(0);
    vehicleBuilder2_2.setLatestArrival(10);
    vehicle2_2 = vehicleBuilder2_2.build();
}

private void createVehicleType() {
    VehicleTypeImpl.Builder wheelChairTypeBuilder = VehicleTypeImpl.Builder.newInstance("wheelChairBusType");
    wheelChairTypeBuilder.addCapacityDimension(WHEELCHAIRSPACE_INDEX, 2);
    wheelChairTypeBuilder.addCapacityDimension(PASSENGERSEATS_INDEX, 4);
    //wheelChairTypeBuilder.setCostPerDistance(1);
    wheelChairTypeBuilder.setCostPerTransportTime(2);
    vehicleType_wheelchair = wheelChairTypeBuilder.build();

    VehicleTypeImpl.Builder soleyPassengerTypeBuilder = VehicleTypeImpl.Builder.newInstance("passengerBusType");
    soleyPassengerTypeBuilder.addCapacityDimension(PASSENGERSEATS_INDEX, 6);
    //soleyPassengerTypeBuilder.setCostPerDistance(1);
    soleyPassengerTypeBuilder.setCostPerTransportTime(2);
    vehicleType_solelypassenger = soleyPassengerTypeBuilder.build();
}

private static Location loc(Coordinate coordinate) {
    return Location.Builder.newInstance().setCoordinate(coordinate).build();
}

}

Это вывод enter image description here

Отгрузка 1 и отгрузка 5 не назначены списку работ. Однако, если я изменяю, добавляю все размеры в PASSENGERSEATS_INDEX, тогда все задания назначаются правильно. Означает ли это, что алгоритм не поддерживает множественный размер измерения?

Я обнаружил, что существует решение, которое назначает 4 задания, когда я вхожу в код в режиме отладки. Однако это считается неприемлемым решением в Jsprit. Исходя из логического мышления, это решение должно быть правильным решением, поскольку оно минимизирует неназначенное задание (по сравнению с исходным решением назначьте только 3 задания).

enter image description here

1 Ответ

0 голосов
/ 09 января 2019

Когда вы строили матрицу затрат, вы указывали только время в пути, а не расстояния.

По умолчанию стоимость неназначенного задания зависит от (максимального) расстояния между пунктом получения и доставки. Поскольку расстояния не заданы, штрафы за неназначенные задания отсутствуют.

Простым решением было бы добавить разумную метрику расстояния при построении матрицы затрат:

     private void setTransportCost() {
        VehicleRoutingTransportCostsMatrix.Builder costMatrixBuilder = VehicleRoutingTransportCostsMatrix.Builder.newInstance(true);

        String[] locationIds = new String[] {"0", "1a", "1b", "2a", "2b", "3a", "3b", "4a", "4b", "5a", "5b"};
        for (String l1: locationIds) {
            for (String l2: locationIds) {
                if (!l1.equals(l2)) {
                    costMatrixBuilder.addTransportDistance(l1, l2, 5);
                }
            }
        }

       // ... on with original implementation ... 
...