Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Solution is crashed if there is any unassigned drivers in solution when using MaxTimeInVehicleConstraint #454

Open
kienthuan opened this issue Dec 24, 2018 · 3 comments

Comments

@kienthuan
Copy link

MaxTimeInVehicleConstraint got crashed in fulfilled(...) method if there is any unassigned drivers in solution.

This will cause whole solution got error when we can still have solution with one drive.

Please try MaxTimeInVehicle with multi-vehicle and there is an unassigned driver in solution.

I move whole code in method above inside try/catch block and everything works fine.

@alchemist1234
Copy link

I met the same question of Null pointer exception in MaxTimeInVehicleConstraint (line:106), but I think that is not because of the unassigned drivers, but the different types of vehicle.
If I set 2 vehicles with the same vehicle type(only one assigned), the program works fine, but if set 2 vehicles with different type, program crashed.

Here is the code, based on MaxTimeInVehicle_IT
Jsprit version is 1.7.3

@Test
public void maxTimeNullPointer() {
    Shipment s1 = Shipment.Builder.newInstance("s1").setPickupLocation(Location.newInstance(0, 0))
            .setDeliveryLocation(Location.newInstance(100, 0))
            .setDeliveryServiceTime(10).setMaxTimeInVehicle(100d).build();
    Shipment s2 = Shipment.Builder.newInstance("s2").setPickupLocation(Location.newInstance(0, 0))
            .setDeliveryLocation(Location.newInstance(100, 0))
            .setDeliveryServiceTime(10).setMaxTimeInVehicle(100d).build();

    VehicleTypeImpl type1 = VehicleTypeImpl.Builder.newInstance("type1").addCapacityDimension(0, 10).build();
    VehicleTypeImpl type2 = VehicleTypeImpl.Builder.newInstance("type2").addCapacityDimension(0, 7).build();

    VehicleImpl v1 = VehicleImpl.Builder.newInstance("v1").setStartLocation(Location.newInstance(0, 0)).setType(type1).build();

    // *****  if the type of v2 change to type1, the program works fine.  ***** 
    VehicleImpl v2 = VehicleImpl.Builder.newInstance("v2").setStartLocation(Location.newInstance(0, 0)).setType(type2).build();

    VehicleRoutingProblem vrp = VehicleRoutingProblem.Builder.newInstance()
            .addVehicle(v1).addVehicle(v2).addJob(s1).addJob(s2).build();

    StateManager stateManager = new StateManager(vrp);
    StateId id = stateManager.createStateId("max-time");
    StateId openJobsId = stateManager.createStateId("open-jobs-id");
    stateManager.addStateUpdater(new UpdateMaxTimeInVehicle(stateManager, id, vrp.getTransportCosts(), vrp.getActivityCosts(), openJobsId));

    ConstraintManager constraintManager = new ConstraintManager(vrp, stateManager);
    constraintManager.addConstraint(new MaxTimeInVehicleConstraint(vrp.getTransportCosts(), vrp.getActivityCosts(), id, stateManager, vrp, openJobsId), ConstraintManager.Priority.CRITICAL);

    VehicleRoutingAlgorithm vra = Jsprit.Builder.newInstance(vrp)
            .setStateAndConstraintManager(stateManager, constraintManager)
            .buildAlgorithm();
    VehicleRoutingProblemSolution solution = Solutions.bestOf(vra.searchSolutions());

     SolutionPrinter.print(vrp, solution, SolutionPrinter.Print.VERBOSE);
}

And the exception stacktrace

java.lang.NullPointerException
	at com.graphhopper.jsprit.core.problem.constraint.MaxTimeInVehicleConstraint.fulfilled(MaxTimeInVehicleConstraint.java:106)
	at com.graphhopper.jsprit.core.algorithm.recreate.AbstractInsertionCalculator.fulfilled(AbstractInsertionCalculator.java:52)
	at com.graphhopper.jsprit.core.algorithm.recreate.ShipmentInsertionCalculator.getInsertionData(ShipmentInsertionCalculator.java:148)
	at com.graphhopper.jsprit.core.algorithm.recreate.JobCalculatorSwitcher.getInsertionData(JobCalculatorSwitcher.java:40)
	at com.graphhopper.jsprit.core.algorithm.recreate.VehicleTypeDependentJobInsertionCalculator.getInsertionData(VehicleTypeDependentJobInsertionCalculator.java:116)
	at com.graphhopper.jsprit.core.algorithm.recreate.RegretInsertion.getScoredJob(RegretInsertion.java:169)
	at com.graphhopper.jsprit.core.algorithm.recreate.RegretInsertion.nextJob(RegretInsertion.java:140)
	at com.graphhopper.jsprit.core.algorithm.recreate.RegretInsertion.insertUnassignedJobs(RegretInsertion.java:112)
	at com.graphhopper.jsprit.core.algorithm.recreate.AbstractInsertionStrategy.insertJobs(AbstractInsertionStrategy.java:91)
	at com.graphhopper.jsprit.core.algorithm.InsertionInitialSolutionFactory.createSolution(InsertionInitialSolutionFactory.java:56)
	at com.graphhopper.jsprit.core.algorithm.PrettyAlgorithmBuilder$1.informAlgorithmStarts(PrettyAlgorithmBuilder.java:116)
	at com.graphhopper.jsprit.core.algorithm.listener.VehicleRoutingAlgorithmListeners.algorithmStarts(VehicleRoutingAlgorithmListeners.java:128)
	at com.graphhopper.jsprit.core.algorithm.VehicleRoutingAlgorithm.algorithmStarts(VehicleRoutingAlgorithm.java:334)
	at com.graphhopper.jsprit.core.algorithm.VehicleRoutingAlgorithm.searchSolutions(VehicleRoutingAlgorithm.java:222)
	at com.udiannet.jsprit.JspritTest.maxTimeNullPointer(JspritTest.java:396)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:628)
	at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:117)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$7(TestMethodTestDescriptor.java:184)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:180)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:127)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:68)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:135)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)

@sdTolik
Copy link

sdTolik commented Apr 12, 2020

Since vehicle switch does not matter for this constraint, I've used the simple fix to replace line 106 in MaxTimeInVehicleConstraint with the following
Double d = stateManager.getActivityState(nextAct, iFacts.getNewVehicle(), minSlackId, Double.class);
if(d == null) {
d = stateManager.getActivityState(nextAct, iFacts.getRoute().getVehicle(), minSlackId, Double.class);
}
minSlack = d;

Basically to check previous vehicle if minSlack data is not found for new vehicle.

@shmert
Copy link

shmert commented Aug 7, 2020

Thanks, @sdTolik that's a huge help. I also needed a similar patch around line 144

					if ( nextAfterPickup != null ) {
						openJobsAtNextOfPickup = stateManager.getActivityState(nextAfterPickup, iFacts.getNewVehicle(), openJobsId, Map.class);
						if (openJobsAtNextOfPickup == null) {
							// same patch as above, use different vehicle to get state
							openJobsAtNextOfPickup = stateManager.getActivityState(nextAfterPickup, iFacts.getRoute().getVehicle(), openJobsId, Map.class);
						}
					}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants