Plotting solution using custom distance and time matrix and vehicle prefer end location

Currently I’m using the given sample from here and here to have a proper distance/time matrix with the following key requirements:

  1. All vehicle start location is the same.
  2. Each vehicles has its own ID and also coordinates as their starting location which is not zero.
  3. Has its own multiple capacity dimension.
  4. Each vehicles has its own endLocation for their delivery.

I have no issue and get a proper solution for item 1, 2 and 3. However, if I set the endLocation for each vehicles, error will be throw as there is no time value for start location with ID = 0 to the endLocation coordinates. Of cos, it can’t find the endLocation as is not part of distance matrix as each vehicles has their own endLocation - what we want is to consider each of the vehicles endLocation when assigning/planning which vehicles to choose for the route planning.

From the error, if I want to have all the vehicles to have their own endLocation, I have to do something with the custom matrix.

Any advise on how to set the endLocation of each of my delivery vehicles using cost matrix builder?

public class JSpritExample {

public static void main(String[] args) {
    final int NUMBER_OF_BOXES = 0;
    final int DELIVERY_POINTS = 1;

    Location startVehicleLocation = Location.Builder.newInstance().setId("0")
            .setCoordinate(Coordinate.newInstance(3.1054104954261823, 101.39172498261695)).build();

    VehicleTypeImpl vehicleType1 = VehicleTypeImpl.Builder.newInstance("type1")
            .addCapacityDimension(NUMBER_OF_BOXES, 22).addCapacityDimension(DELIVERY_POINTS, 15).build();
    VehicleImpl vehicle1 = VehicleImpl.Builder.newInstance("Leu").setStartLocation(startVehicleLocation)
            .setType(vehicleType1).build();

    VehicleTypeImpl vehicleType2 = VehicleTypeImpl.Builder.newInstance("type2")
            .addCapacityDimension(NUMBER_OF_BOXES, 22).addCapacityDimension(DELIVERY_POINTS, 15).build();
    VehicleImpl vehicle2 = VehicleImpl.Builder.newInstance("Vijay").setStartLocation(startVehicleLocation)
            .setType(vehicleType2).build();

    VehicleTypeImpl vehicleType3 = VehicleTypeImpl.Builder.newInstance("type3")
            .addCapacityDimension(NUMBER_OF_BOXES, 22).addCapacityDimension(DELIVERY_POINTS, 15).build();
    VehicleImpl vehicle3 = VehicleImpl.Builder.newInstance("Ring").setStartLocation(startVehicleLocation)
            .setType(vehicleType3).build();
    /*
     * build services at the required locations, each with its own capacity-demand
     * aka number of boxes.
     */
    Location location1 = Location.Builder.newInstance().setId("1")
            .setCoordinate(Coordinate.newInstance(3.0651174019721434, 101.79107501515256)).build();
    Service deliveryJob1 = Service.Builder.newInstance("1").addSizeDimension(NUMBER_OF_BOXES, 1)
            .addSizeDimension(DELIVERY_POINTS, 1).setLocation(location1).build();

    Location location2 = Location.Builder.newInstance().setId("2")
            .setCoordinate(Coordinate.newInstance(3.0362824146932934, 101.75871771663888)).build();
    Service deliveryJob2 = Service.Builder.newInstance("2").addSizeDimension(NUMBER_OF_BOXES, 1)
            .addSizeDimension(DELIVERY_POINTS, 1).setLocation(location2).build();

    Location location3 = Location.Builder.newInstance().setId("3")
            .setCoordinate(Coordinate.newInstance(3.0717816850989803, 101.75618972318607)).build();
    Service deliveryJob3 = Service.Builder.newInstance("3").addSizeDimension(NUMBER_OF_BOXES, 1)
            .addSizeDimension(DELIVERY_POINTS, 1).setLocation(location3).build();

    /**
     * Costs Matrix builder
     */
    VehicleRoutingTransportCostsMatrix.Builder costMatrixBuilder = VehicleRoutingTransportCostsMatrix.Builder
            .newInstance(true);
    costMatrixBuilder.addTransportDistance("0", "1", 56732);
    costMatrixBuilder.addTransportDistance("0", "2", 55614);
    costMatrixBuilder.addTransportDistance("0", "3", 50785);
    costMatrixBuilder.addTransportDistance("1", "2", 5869);
    costMatrixBuilder.addTransportDistance("1", "3", 7580);
    costMatrixBuilder.addTransportDistance("2", "3", 8107);

    costMatrixBuilder.addTransportTime("0", "1", 3599);
    costMatrixBuilder.addTransportTime("0", "2", 3472);
    costMatrixBuilder.addTransportTime("0", "3", 3197);
    costMatrixBuilder.addTransportTime("1", "2", 880);
    costMatrixBuilder.addTransportTime("1", "3", 787);
    costMatrixBuilder.addTransportTime("2", "3", 791);

    VehicleRoutingTransportCosts costMatrix = costMatrixBuilder.build();

    VehicleRoutingProblem.Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance();
    vrpBuilder.addVehicle(vehicle1).addVehicle(vehicle2).addVehicle(vehicle3);

    vrpBuilder.addJob(deliveryJob1).addJob(deliveryJob2).addJob(deliveryJob3);

    vrpBuilder.setFleetSize(FleetSize.FINITE);
    vrpBuilder.setRoutingCost(costMatrix);

    VehicleRoutingProblem problem = vrpBuilder.build();

    /*
     * get the algorithm out-of-the-box.
     */
    VehicleRoutingAlgorithm algorithm = Jsprit.createAlgorithm(problem);

    /*
     * and search a solution
     */
    Collection<VehicleRoutingProblemSolution> solutions = algorithm.searchSolutions();

    /*
     * get the best
     */
    VehicleRoutingProblemSolution bestSolution = Solutions.bestOf(solutions);

    SolutionPrinter.print(problem, bestSolution, SolutionPrinter.Print.VERBOSE);

    /*
     * plot
     */
    new Plotter(problem, bestSolution).plot("output/plot.png", "Plot Result");

    /*
     * render problem and solution with GraphStream
     */
    new GraphStreamViewer(problem, bestSolution).labelWith(Label.ID).setRenderDelay(200).display();
}

I don’t see any end location construct and assign. Can you paste your solution with end location?