Vehicle break not working

I’m using latest version of jsprit 1.7-RC1. I have two vehicles at same location where shipment has pickup time and drop time. I have put break time window equivalent to shipment and duration equivalent to drop-pickup time for vehilce-1. But the problem is when i run jsprit it always picking vehicle-1 to do job. I should be vehicle-2. please suggest…

@abhilash_jain Can you write the code here? Or can you tell me exact values of the time windows?

public void f2()
{
final int WEIGHT_INDEX = 0;
VehicleTypeImpl.Builder vehicleTypeBuilder = VehicleTypeImpl.Builder.newInstance(“vehicleType”).addCapacityDimension(WEIGHT_INDEX, 750);
vehicleTypeBuilder.setCostPerDistance(7.4);
VehicleType vehicleType = vehicleTypeBuilder.build();

    Break v2Break = Break.Builder.newInstance("lunch")
            .setTimeWindow(TimeWindow.newInstance(addMinutes(new Date(), 5).getTime(), addMinutes(new Date(), 50).getTime())) // milliseconds
            .setServiceTime(2600) // seconds
            .build();

    VehicleImpl.Builder vb1 = VehicleImpl.Builder.newInstance("1");
    vb1.setStartLocation(loc(Coordinate.newInstance(15.3645877, 75.0391068)));
    vb1.setType(vehicleType);
    VehicleImpl v1 = vb1.build();

    VehicleImpl.Builder vb2 = VehicleImpl.Builder.newInstance("2");
    vb2.setStartLocation(loc(Coordinate.newInstance(15.3645877, 75.0391068)));
    vb2.setType(vehicleType);
    vb2.setBreak(v2Break);
    VehicleImpl v2 = vb2.build();

    Shipment shipment1 = Shipment.Builder.newInstance("101").setName("one_shipment").addSizeDimension(WEIGHT_INDEX, 750)
            .setPickupLocation(loc(Coordinate.newInstance(15.3645877, 75.0391068)))
            .setPickupTimeWindow(TimeWindow.newInstance(addMinutes(new Date(), 5).getTime(), addMinutes(new Date(), 10).getTime()))
            .setPickupServiceTime(120) // seconds
            .setDeliveryTimeWindow(TimeWindow.newInstance(addMinutes(new Date(), 40).getTime(), addMinutes(new Date(), 50).getTime()))
            .setDeliveryLocation(loc(Coordinate.newInstance(15.4589209, 74.9727882)))
            .setDeliveryServiceTime(120) // seconds
            .build();

    VehicleRoutingProblem vrpBuilder = VehicleRoutingProblem.Builder.newInstance().setFleetSize(VehicleRoutingProblem.FleetSize.FINITE)
            .addVehicle(v1).addVehicle(v2).addJob(shipment1).build();
    VehicleRoutingAlgorithm vehicleRoutingAlgorithm = Jsprit.Builder.newInstance(vrpBuilder).buildAlgorithm();

    Collection<VehicleRoutingProblemSolution> solutions = vehicleRoutingAlgorithm.searchSolutions();
    VehicleRoutingProblemSolution bestSolution = Solutions.bestOf(solutions);
    display(vrpBuilder, bestSolution, "1");
}

public static Date addMinutes(Date source, int minutes)
{
    return addSeconds(source, minutes * 60);
}

public static Date addSeconds(Date source, int seconds)
{
    if(null == source)
    {
        return null;
    }
    Calendar calendar = Calendar.getInstance();
    calendar.setTime(source);
    calendar.add(Calendar.SECOND, seconds);
    return calendar.getTime();

}

private void display(VehicleRoutingProblem problem, VehicleRoutingProblemSolution bestSolution, String modelName)
{
    System.out.println();
    System.out.println("BasicModel-"+modelName+" :");
    SolutionPrinter.print(problem, bestSolution, SolutionPrinter.Print.VERBOSE);
}

±-------------------------------------------------------------------------------------------------------------------------------+
| detailed solution |
±--------±---------------------±----------------------±----------------±----------------±----------------±----------------+
| route | vehicle | activity | job | arrTime | endTime | costs |
±--------±---------------------±----------------------±----------------±----------------±----------------±----------------+
| 1 | 2 | start | - | undef | 0 | 0 |
| 1 | 2 | pickupShipment | 101 | 0 | 1498644819938 | 0 |
| 1 | 2 | deliverShipment | 101 | 1498644819938 | 1498646919938 | 1 |
| 1 | 2 | end | - | 1498646919938 | undef | 2 |
±-------------------------------------------------------------------------------------------------------------------------------+

Even after giving break to vehicle 2, it is being chosen, it should chose vehicle 1 instead… can you please let me know ? thanks…

@stefan i need your little intervention here… can you please look into this, if i’ve have missed anything?

@abhilash_jain
I have modify little portion of your problem to debug. I took the timestamp in millisec. For an instance I found the below time windows:

  • Break start time (V2): 1498713389953
  • Break end time (V2): 1498716089968
  • Pickup start time: 1498713390084
  • Pickup end time: 1498713690084
  • Delivery start time: 1498715490084
  • Delivery end time: 1498716090084

And solution gives:
pickupShipment: arrTIme=> 0, endTime=>1498713390204
deliverShipment: arrTIme=> 1498713390204, endTime=>1498715490204

Which is actually fulfills all the constraints as V2 can take break after the completion of the shipment.

Thanks sutirtha for pointing out, that break can also be taken after task completion. But I have already given the Break Time Window and duration - 2400s, that means vehicle should stop for 2400s between only that “Time Window” otherwise other vehicle should be choose or if nothing satisfies then no results, which is not happening i guess?

@abhilash_jain The break time window means break must start between (on or after start time) to (on or before end time). Break can be end after the time window. Please follow my answer here

Thanks a lot… so, vehicle keep on servicing even after time window ends. Is there any way to give a strict end window means “by this time, break should end”? reason being, i have transporters with different break windows.

I think there is no direct way to do that. But you can specify

latest end time = (end time you want - break time) at the time of building problem

1 Like

| detailed solution |
±--------±---------------------±----------------------±----------------±----------------±----------------±----------------+
| route | vehicle | activity | job | arrTime | endTime | costs |
±--------±---------------------±----------------------±----------------±----------------±----------------±----------------+
| 1 | 2 | start | - | undef | 0 | 0 |
| 1 | 2 | pickupShipment | 101 | 0 | 1498818962740 | 0 |
| 1 | 2 | break | lunch | 1498818962740 | 1498820762740 | 0 |
| 1 | 2 | deliverShipment | 101 | 1498820762740 | 1498820762860 | 1 |
| 1 | 2 | end | - | 1498820762860 | undef | 2 |

If you see this case i have given
Break v2Break = Break.Builder.newInstance(“lunch”)
.setTimeWindow(TimeWindow.newInstance(addMinutes(new Date(), 2).getTime(), addMinutes(new Date(), 10).getTime())) // milliseconds
.setServiceTime(30601000) // seconds
.build();
to vehicle-2 and result shows that vehicle is running in its break duration and when the break ends, vehicle is at its destination which is not correct!??

@abhilash_jain You did not mention service location so break can be taken at any location. In this case it comes to destination and takes the break.

1 Like

i don’t want to give location in break but still the problem persist. No this time i applied 18000 sec break to both vehicle and two shipments so that break should be reflected…

public void breakExample()
{
final int WEIGHT_INDEX = 0;
VehicleTypeImpl.Builder vehicleTypeBuilder = VehicleTypeImpl.Builder.newInstance(“vehicleType”).addCapacityDimension(WEIGHT_INDEX, 750);
vehicleTypeBuilder.setCostPerDistance(7.4);
VehicleType vehicleType = vehicleTypeBuilder.build();

    Break v2Break = Break.Builder.newInstance("lunch")
            .setTimeWindow(TimeWindow.newInstance(addMinutes(new Date(), 5).getTime()/1000, addMinutes(new Date(), 7).getTime()/1000)) // milliseconds
            .setServiceTime(1800) // milli-seconds
            .build();

    VehicleImpl.Builder vb1 = VehicleImpl.Builder.newInstance("1");
    vb1.setStartLocation(loc(Coordinate.newInstance(15.3645877, 75.0391068)));
    vb1.setReturnToDepot(false);
    vb1.setType(vehicleType);
    vb1.setBreak(v2Break);
    VehicleImpl v1 = vb1.build();

    VehicleImpl.Builder vb2 = VehicleImpl.Builder.newInstance("2");
    vb2.setStartLocation(loc(Coordinate.newInstance(15.3645877, 75.0391068)));
    vb2.setType(vehicleType);
    vb2.setReturnToDepot(false);
    vb2.setBreak(v2Break);
    VehicleImpl v2 = vb2.build();

    Shipment shipment1 = Shipment.Builder.newInstance("101").setName("one_shipment").addSizeDimension(WEIGHT_INDEX, 750)
            .setPickupLocation(loc(Coordinate.newInstance(15.3645877, 75.0391068)))
            .setPickupTimeWindow(TimeWindow.newInstance(addMinutes(new Date(), 5).getTime()/1000, addMinutes(new Date(), 7).getTime()/1000))
            .setPickupServiceTime(120) // seconds
            .setDeliveryTimeWindow(TimeWindow.newInstance(addMinutes(new Date(), 30).getTime()/1000, addMinutes(new Date(), 40).getTime()/1000))
            .setDeliveryLocation(loc(Coordinate.newInstance(15.4589209, 74.9727882)))
            .setDeliveryServiceTime(120) // seconds
            .build();

    Shipment shipment2 = Shipment.Builder.newInstance("102").setName("two_shipment").addSizeDimension(WEIGHT_INDEX, 750)
            .setPickupLocation(loc(Coordinate.newInstance(15.4589209, 74.9727882)))
            .setPickupTimeWindow(TimeWindow.newInstance(addMinutes(new Date(), 30).getTime()/1000, addMinutes(new Date(), 40).getTime()/1000))
            .setPickupServiceTime(120) // seconds
            .setDeliveryTimeWindow(TimeWindow.newInstance(addMinutes(new Date(), 70).getTime()/1000, addMinutes(new Date(), 80).getTime()/1000))
            .setDeliveryLocation(loc(Coordinate.newInstance(15.3645877, 75.0391068)))
            .setDeliveryServiceTime(120) // seconds
            .build();

    VehicleRoutingProblem vrpBuilder = VehicleRoutingProblem.Builder.newInstance().setFleetSize(VehicleRoutingProblem.FleetSize.FINITE)
            .addVehicle(v1).addVehicle(v2).addJob(shipment1).addJob(shipment2).build();
    VehicleRoutingAlgorithm vehicleRoutingAlgorithm = Jsprit.Builder.newInstance(vrpBuilder).buildAlgorithm();

    Collection<VehicleRoutingProblemSolution> solutions = vehicleRoutingAlgorithm.searchSolutions();
    VehicleRoutingProblemSolution bestSolution = Solutions.bestOf(solutions);
    display(vrpBuilder, bestSolution, "1");
}

Solution:

±--------±---------------------±----------------------±----------------±----------------±----------------±----------------+
| route | vehicle | activity | job | arrTime | endTime | costs |
±--------±---------------------±----------------------±----------------±----------------±----------------±----------------+
| 1 | 2 | start | - | undef | 0 | 0 |
| 1 | 2 | pickupShipment | 101 | 0 | 1499087354 | 0 |
| 1 | 2 | break | lunch | 1499087354 | 1499089154 | 0 |
| 1 | 2 | deliverShipment | 101 | 1499089154 | 1499089274 | 1 |
| 1 | 2 | pickupShipment | 102 | 1499089274 | 1499089394 | 1 |
| 1 | 2 | deliverShipment | 102 | 1499089394 | 1499091254 | 2 |
| 1 | 2 | end | - | 1499091254 | undef | 2 |
±-------------------------------------------------------------------------------------------------------------------------------+

My question is again no vehicle should be picked up, considering the break… because duration is 1800 sec so next shipment can’t occur if it takes break in or before first shipment?? could you please let me know if anything i’m missing??

There’s a few things confusing me in this thread so I might be misunderstanding the issue. I don’t mean this in a rude way but I think you’ve tied yourself in knots.

  1. The biggest (?). In your code, you set a break duration that you // comment is in milliseconds. At the bottom of your post you say duration is “1800 sec”, at the top you say it’s “18000 secs”. When setting time windows you use addMinutes. By that point, I think you’ve lost all track of whatever units you’re in. Standardise to a single unit before you even begin formulating the problem.

  2. In your initial post you claim that the issue is that vehicle 2 should be doing the work (which it actually is) and then in a later post say that it should be vehicle 1. Is this a non-issue from a typo?

  3. From your printed output, the only thing that appears to have any impact on the duration of the route is service times. From pickup to delivery of shipment 1 takes 0 time units (whatever unit it is). Ok, there’s a break in the middle of it, but no travel time either before the break starts or after it ends. With shipment 2, the travel from delivery 1 is instant, and shipment 2 is delivered instantaneously. Something is not right here (which probably stems from Point 1).

yes, (1) comments in code are misleading. Ignore them. All are in seconds either it is service time or pick-drop time. (2) I’ve kept iterating my code and doing slice and dice in order to figure it out how break works that is why first post was kind of generic question. In a nutshell, i would say… even if break is given to one vehicle then also it is being picked for a job rather than other vehicle.