jsprit icon indicating copy to clipboard operation
jsprit copied to clipboard

Multiple time windows are not considered in initial routes

Open tdeenes opened this issue 7 years ago • 1 comments

There is an undocumented limitation of using initial routes: multiple time windows of a job are silently dropped and only the first window is retained (as earliest and latest attributes). Minimal reproducible example:

package com.graphhopper.jsprit.examples;

import com.graphhopper.jsprit.core.algorithm.VehicleRoutingAlgorithm;
import com.graphhopper.jsprit.core.algorithm.box.Jsprit;
import com.graphhopper.jsprit.core.problem.Location;
import com.graphhopper.jsprit.core.problem.VehicleRoutingProblem;
import com.graphhopper.jsprit.core.problem.VehicleRoutingProblem.Builder;
import com.graphhopper.jsprit.core.problem.job.Service;
import com.graphhopper.jsprit.core.problem.solution.VehicleRoutingProblemSolution;
import com.graphhopper.jsprit.core.problem.solution.route.VehicleRoute;
import com.graphhopper.jsprit.core.problem.vehicle.VehicleImpl;
import com.graphhopper.jsprit.core.problem.vehicle.VehicleType;
import com.graphhopper.jsprit.core.problem.vehicle.VehicleTypeImpl;
import com.graphhopper.jsprit.core.reporting.SolutionPrinter;
import com.graphhopper.jsprit.core.util.Solutions;

import java.util.Collection;


public class SingleDepotWithInitialRouteExample {


	public static void main(String[] args) {

	    /*
	     * Build a vehicle type
		 */
	    VehicleTypeImpl.Builder vehicleTypeBuilder = VehicleTypeImpl.Builder.newInstance("vehicleType")
	        .addCapacityDimension(0, 2)
	        ;
	    VehicleType vehicleType = vehicleTypeBuilder.build();

		/*
	     * Build a vehicle with a broad time window
		 */
	    VehicleImpl.Builder vehicleBuilder = VehicleImpl.Builder.newInstance("v1")
	        .setStartLocation(Location.newInstance(0, 0))
	        .setType(vehicleType)
	        .setEarliestStart(0)
	        .setLatestArrival(1000)
	        .setReturnToDepot(false)
	        ;
	    VehicleImpl vehicle = vehicleBuilder.build();


		/*
	     * build service which has to be done first
		 */
	    Service service1 = Service.Builder.newInstance("s1")
	        .addTimeWindow(200, 500)
	        .addSizeDimension(0, 1)
	        .setServiceTime(100)
	        .setLocation(Location.newInstance(20, 20))
	        .build();

	    /*
	     * build service which has to be done second, in two possible time windows
		 */
	    Service service2 = Service.Builder.newInstance("s2")
	        .addTimeWindow(0, 200)
	        .addTimeWindow(700, 1000)
	        .addSizeDimension(0, 1)
	        .setServiceTime(100)
	        .setLocation(Location.newInstance(30, 30))
	        .build();

	    /*
	     * Build problem with initial route
	     */
	    VehicleRoute initialRoute = VehicleRoute.Builder.newInstance(vehicle)
	        .addService(service1)
	        .addService(service2)
	        .build();
	    Builder vrpBuilder = Builder.newInstance()
	        .addInitialVehicleRoute(initialRoute);
	    VehicleRoutingProblem vrp = vrpBuilder.build();

	    /*
	     * Find solution
	     */
	    VehicleRoutingAlgorithm vra = Jsprit.createAlgorithm(vrp);
	    Collection<VehicleRoutingProblemSolution> solutions = vra.searchSolutions();

	    /*
	     * Print the solution -
	     * the time window of s1 is considered, the vehicle is waiting from t28 until t200;
	     * however, the time window of s2 is violated - the second service should not be delivered
	     * between t314-414 but t700-800. This is because the second time window of s2 is not
	     * considered at all.
	     */
	    SolutionPrinter.print(vrp, Solutions.bestOf(solutions), SolutionPrinter.Print.VERBOSE);

	}
}

tdeenes avatar Jun 02 '17 15:06 tdeenes

hi everyone! this problem not considered?

ibatanov avatar Aug 02 '21 14:08 ibatanov