mirror of
https://github.com/graphhopper/jsprit.git
synced 2020-01-24 07:45:05 +01:00
refine max-time-in-vehicle constraint
This commit is contained in:
parent
b5998e1d93
commit
db0c39e1c2
22 changed files with 448 additions and 436 deletions
|
|
@ -17,14 +17,6 @@
|
||||||
*/
|
*/
|
||||||
package com.graphhopper.jsprit.core.algorithm;
|
package com.graphhopper.jsprit.core.algorithm;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import com.graphhopper.jsprit.core.algorithm.SearchStrategy.DiscoveredSolution;
|
import com.graphhopper.jsprit.core.algorithm.SearchStrategy.DiscoveredSolution;
|
||||||
import com.graphhopper.jsprit.core.algorithm.listener.SearchStrategyListener;
|
import com.graphhopper.jsprit.core.algorithm.listener.SearchStrategyListener;
|
||||||
import com.graphhopper.jsprit.core.algorithm.listener.SearchStrategyModuleListener;
|
import com.graphhopper.jsprit.core.algorithm.listener.SearchStrategyModuleListener;
|
||||||
|
|
@ -38,6 +30,13 @@ import com.graphhopper.jsprit.core.problem.solution.VehicleRoutingProblemSolutio
|
||||||
import com.graphhopper.jsprit.core.problem.solution.route.VehicleRoute;
|
import com.graphhopper.jsprit.core.problem.solution.route.VehicleRoute;
|
||||||
import com.graphhopper.jsprit.core.problem.solution.route.activity.TourActivity;
|
import com.graphhopper.jsprit.core.problem.solution.route.activity.TourActivity;
|
||||||
import com.graphhopper.jsprit.core.util.Solutions;
|
import com.graphhopper.jsprit.core.util.Solutions;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -190,6 +190,49 @@ public class UpdateMaxTimeInVehicle implements StateUpdater, ActivityVisitor{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void finish(List<TourActivity> activities, Job ignore) {
|
||||||
|
for (Vehicle v : vehicles) {
|
||||||
|
int vehicleIndex = v.getVehicleTypeIdentifier().getIndex();
|
||||||
|
|
||||||
|
//!!! open routes !!!
|
||||||
|
double routeEnd;
|
||||||
|
if (!v.isReturnToDepot()) routeEnd = prevActEndTimes[vehicleIndex];
|
||||||
|
else
|
||||||
|
routeEnd = prevActEndTimes[vehicleIndex] + transportTime.getTransportTime(prevActLocations[vehicleIndex], v.getEndLocation(), prevActEndTimes[vehicleIndex], route.getDriver(), v);
|
||||||
|
|
||||||
|
Map<String, Double> openDeliveries = new HashMap<>();
|
||||||
|
for (Job job : openPickupEndTimes.get(vehicleIndex).keySet()) {
|
||||||
|
if (job == ignore) continue;
|
||||||
|
double actEndTime = openPickupEndTimes.get(vehicleIndex).get(job);
|
||||||
|
double slackTime = job.getMaxTimeInVehicle() - (routeEnd - actEndTime);
|
||||||
|
openDeliveries.put(job.getId(), slackTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
double minSlackTimeAtEnd = minSlackTime(openDeliveries);
|
||||||
|
stateManager.putRouteState(route, v, latestStartId, routeEnd + minSlackTimeAtEnd);
|
||||||
|
List<TourActivity> acts = new ArrayList<>(activities);
|
||||||
|
Collections.reverse(acts);
|
||||||
|
for (TourActivity act : acts) {
|
||||||
|
if (act instanceof ServiceActivity || act instanceof PickupActivity) {
|
||||||
|
String jobId = ((TourActivity.JobActivity) act).getJob().getId();
|
||||||
|
openDeliveries.remove(jobId);
|
||||||
|
double minSlackTime = minSlackTime(openDeliveries);
|
||||||
|
double latestStart = actStart(act, v) + minSlackTime;
|
||||||
|
stateManager.putActivityState(act, v, latestStartId, latestStart);
|
||||||
|
} else {
|
||||||
|
String jobId = ((TourActivity.JobActivity) act).getJob().getId();
|
||||||
|
if (slackTimes.get(vehicleIndex).containsKey(act)) {
|
||||||
|
double slackTime = slackTimes.get(vehicleIndex).get(act);
|
||||||
|
openDeliveries.put(jobId, slackTime);
|
||||||
|
}
|
||||||
|
double minSlackTime = minSlackTime(openDeliveries);
|
||||||
|
double latestStart = actStart(act, v) + minSlackTime;
|
||||||
|
stateManager.putActivityState(act, v, latestStartId, latestStart);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private double actStart(TourActivity act, Vehicle v) {
|
private double actStart(TourActivity act, Vehicle v) {
|
||||||
return actStartTimes.get(v.getVehicleTypeIdentifier().getIndex()).get(act);
|
return actStartTimes.get(v.getVehicleTypeIdentifier().getIndex()).get(act);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -74,14 +74,13 @@ public final class Location implements HasIndex, HasId {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets user specific domain data associated with the object.
|
* Sets user specific domain data associated with the object.
|
||||||
*
|
* <p>
|
||||||
* <p>
|
* <p>
|
||||||
* The user data is a black box for the framework, it only stores it,
|
* The user data is a black box for the framework, it only stores it,
|
||||||
* but never interacts with it in any way.
|
* but never interacts with it in any way.
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* @param userData
|
* @param userData any object holding the domain specific user data
|
||||||
* any object holding the domain specific user data
|
|
||||||
* associated with the object.
|
* associated with the object.
|
||||||
* @return builder
|
* @return builder
|
||||||
*/
|
*/
|
||||||
|
|
@ -191,7 +190,9 @@ public final class Location implements HasIndex, HasId {
|
||||||
return coordinate;
|
return coordinate;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getName() { return name; }
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object o) {
|
public boolean equals(Object o) {
|
||||||
|
|
|
||||||
|
|
@ -72,6 +72,7 @@ public interface Vehicle extends HasId, HasIndex {
|
||||||
public abstract VehicleTypeKey getVehicleTypeIdentifier();
|
public abstract VehicleTypeKey getVehicleTypeIdentifier();
|
||||||
|
|
||||||
public abstract Skills getSkills();
|
public abstract Skills getSkills();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return User-specific domain data associated with the vehicle
|
* @return User-specific domain data associated with the vehicle
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -17,13 +17,12 @@
|
||||||
*/
|
*/
|
||||||
package com.graphhopper.jsprit.core.problem.vehicle;
|
package com.graphhopper.jsprit.core.problem.vehicle;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import com.graphhopper.jsprit.core.problem.AbstractVehicle;
|
import com.graphhopper.jsprit.core.problem.AbstractVehicle;
|
||||||
import com.graphhopper.jsprit.core.problem.Location;
|
import com.graphhopper.jsprit.core.problem.Location;
|
||||||
import com.graphhopper.jsprit.core.problem.Skills;
|
import com.graphhopper.jsprit.core.problem.Skills;
|
||||||
import com.graphhopper.jsprit.core.problem.job.Break;
|
import com.graphhopper.jsprit.core.problem.job.Break;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -153,14 +152,13 @@ public class VehicleImpl extends AbstractVehicle {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets user specific domain data associated with the object.
|
* Sets user specific domain data associated with the object.
|
||||||
*
|
* <p>
|
||||||
* <p>
|
* <p>
|
||||||
* The user data is a black box for the framework, it only stores it,
|
* The user data is a black box for the framework, it only stores it,
|
||||||
* but never interacts with it in any way.
|
* but never interacts with it in any way.
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* @param userData
|
* @param userData any object holding the domain specific user data
|
||||||
* any object holding the domain specific user data
|
|
||||||
* associated with the object.
|
* associated with the object.
|
||||||
* @return builder
|
* @return builder
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -138,9 +138,10 @@ public class UnassignedJobReasonTracker implements JobUnassignedListener {
|
||||||
public String getHumanReadableReason(String failedConstraintName) {
|
public String getHumanReadableReason(String failedConstraintName) {
|
||||||
return getCodesToReason().get(getCode(failedConstraintName));
|
return getCodesToReason().get(getCode(failedConstraintName));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the most likely reason code i.e. the reason (failed constraint) being observed most often.
|
* Returns the most likely reason code i.e. the reason (failed constraint) being observed most often.
|
||||||
*
|
* <p>
|
||||||
* 1 --> "cannot serve required skill
|
* 1 --> "cannot serve required skill
|
||||||
* 2 --> "cannot be visited within time window"
|
* 2 --> "cannot be visited within time window"
|
||||||
* 3 --> "does not fit into any vehicle due to capacity"
|
* 3 --> "does not fit into any vehicle due to capacity"
|
||||||
|
|
|
||||||
|
|
@ -18,17 +18,14 @@
|
||||||
|
|
||||||
package com.graphhopper.jsprit.core.problem;
|
package com.graphhopper.jsprit.core.problem;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import com.graphhopper.jsprit.core.util.Coordinate;
|
||||||
import static org.junit.Assert.assertNull;
|
import org.junit.Assert;
|
||||||
import static org.junit.Assert.assertTrue;
|
import org.junit.Test;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.junit.Assert;
|
import static org.junit.Assert.*;
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
import com.graphhopper.jsprit.core.util.Coordinate;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by schroeder on 16.12.14.
|
* Created by schroeder on 16.12.14.
|
||||||
|
|
|
||||||
|
|
@ -37,14 +37,14 @@ import com.graphhopper.jsprit.core.problem.solution.route.activity.TourActivity;
|
||||||
import com.graphhopper.jsprit.core.problem.vehicle.Vehicle;
|
import com.graphhopper.jsprit.core.problem.vehicle.Vehicle;
|
||||||
import com.graphhopper.jsprit.core.problem.vehicle.VehicleImpl;
|
import com.graphhopper.jsprit.core.problem.vehicle.VehicleImpl;
|
||||||
import com.graphhopper.jsprit.core.util.ManhattanCosts;
|
import com.graphhopper.jsprit.core.util.ManhattanCosts;
|
||||||
|
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
import static org.mockito.Mockito.mock;
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by schroeder on 18/05/16.
|
* Created by schroeder on 18/05/16.
|
||||||
|
|
|
||||||
|
|
@ -17,18 +17,14 @@
|
||||||
*/
|
*/
|
||||||
package com.graphhopper.jsprit.core.problem.job;
|
package com.graphhopper.jsprit.core.problem.job;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import com.graphhopper.jsprit.core.problem.Location;
|
||||||
import static org.junit.Assert.assertFalse;
|
import org.junit.Assert;
|
||||||
import static org.junit.Assert.assertNull;
|
import org.junit.Test;
|
||||||
import static org.junit.Assert.assertTrue;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.junit.Assert;
|
import static org.junit.Assert.*;
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
import com.graphhopper.jsprit.core.problem.Location;
|
|
||||||
|
|
||||||
public class DeliveryTest {
|
public class DeliveryTest {
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,18 +17,14 @@
|
||||||
*/
|
*/
|
||||||
package com.graphhopper.jsprit.core.problem.job;
|
package com.graphhopper.jsprit.core.problem.job;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import com.graphhopper.jsprit.core.problem.Location;
|
||||||
import static org.junit.Assert.assertFalse;
|
import org.junit.Assert;
|
||||||
import static org.junit.Assert.assertNull;
|
import org.junit.Test;
|
||||||
import static org.junit.Assert.assertTrue;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.junit.Assert;
|
import static org.junit.Assert.*;
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
import com.graphhopper.jsprit.core.problem.Location;
|
|
||||||
|
|
||||||
public class PickupTest {
|
public class PickupTest {
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,25 +17,19 @@
|
||||||
*/
|
*/
|
||||||
package com.graphhopper.jsprit.core.problem.job;
|
package com.graphhopper.jsprit.core.problem.job;
|
||||||
|
|
||||||
import static org.hamcrest.core.Is.is;
|
import com.graphhopper.jsprit.core.problem.Location;
|
||||||
import static org.hamcrest.core.IsCollectionContaining.hasItem;
|
import com.graphhopper.jsprit.core.problem.solution.route.activity.TimeWindow;
|
||||||
import static org.junit.Assert.assertEquals;
|
import org.junit.Assert;
|
||||||
import static org.junit.Assert.assertFalse;
|
import org.junit.Test;
|
||||||
import static org.junit.Assert.assertNotNull;
|
|
||||||
import static org.junit.Assert.assertNull;
|
|
||||||
import static org.junit.Assert.assertThat;
|
|
||||||
import static org.junit.Assert.assertTrue;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import org.junit.Assert;
|
import static org.hamcrest.core.Is.is;
|
||||||
import org.junit.Test;
|
import static org.hamcrest.core.IsCollectionContaining.hasItem;
|
||||||
|
import static org.junit.Assert.*;
|
||||||
import com.graphhopper.jsprit.core.problem.Location;
|
|
||||||
import com.graphhopper.jsprit.core.problem.solution.route.activity.TimeWindow;
|
|
||||||
|
|
||||||
public class ServiceTest {
|
public class ServiceTest {
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,25 +17,19 @@
|
||||||
*/
|
*/
|
||||||
package com.graphhopper.jsprit.core.problem.job;
|
package com.graphhopper.jsprit.core.problem.job;
|
||||||
|
|
||||||
import static org.hamcrest.core.Is.is;
|
|
||||||
import static org.hamcrest.core.IsCollectionContaining.hasItem;
|
|
||||||
import static org.junit.Assert.assertEquals;
|
|
||||||
import static org.junit.Assert.assertFalse;
|
|
||||||
import static org.junit.Assert.assertNotNull;
|
|
||||||
import static org.junit.Assert.assertNull;
|
|
||||||
import static org.junit.Assert.assertThat;
|
|
||||||
import static org.junit.Assert.assertTrue;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import org.junit.Assert;
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
import com.graphhopper.jsprit.core.problem.Location;
|
import com.graphhopper.jsprit.core.problem.Location;
|
||||||
import com.graphhopper.jsprit.core.problem.solution.route.activity.TimeWindow;
|
import com.graphhopper.jsprit.core.problem.solution.route.activity.TimeWindow;
|
||||||
import com.graphhopper.jsprit.core.util.Coordinate;
|
import com.graphhopper.jsprit.core.util.Coordinate;
|
||||||
import com.graphhopper.jsprit.core.util.TestUtils;
|
import com.graphhopper.jsprit.core.util.TestUtils;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static org.hamcrest.core.Is.is;
|
||||||
|
import static org.hamcrest.core.IsCollectionContaining.hasItem;
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
public class ShipmentTest {
|
public class ShipmentTest {
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,20 +18,15 @@
|
||||||
package com.graphhopper.jsprit.core.problem.vehicle;
|
package com.graphhopper.jsprit.core.problem.vehicle;
|
||||||
|
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import com.graphhopper.jsprit.core.problem.Location;
|
||||||
import static org.junit.Assert.assertFalse;
|
import com.graphhopper.jsprit.core.problem.job.Break;
|
||||||
import static org.junit.Assert.assertNotNull;
|
import com.graphhopper.jsprit.core.problem.solution.route.activity.TimeWindow;
|
||||||
import static org.junit.Assert.assertNull;
|
import org.junit.Test;
|
||||||
import static org.junit.Assert.assertTrue;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.junit.Test;
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
import com.graphhopper.jsprit.core.problem.Location;
|
|
||||||
import com.graphhopper.jsprit.core.problem.job.Break;
|
|
||||||
import com.graphhopper.jsprit.core.problem.solution.route.activity.TimeWindow;
|
|
||||||
|
|
||||||
|
|
||||||
public class VehicleImplTest {
|
public class VehicleImplTest {
|
||||||
|
|
|
||||||
|
|
@ -17,15 +17,12 @@
|
||||||
*/
|
*/
|
||||||
package com.graphhopper.jsprit.core.problem.vehicle;
|
package com.graphhopper.jsprit.core.problem.vehicle;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import org.junit.Test;
|
||||||
import static org.junit.Assert.assertNotNull;
|
|
||||||
import static org.junit.Assert.assertNull;
|
|
||||||
import static org.junit.Assert.assertTrue;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.junit.Test;
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
public class VehicleTypeImplTest {
|
public class VehicleTypeImplTest {
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue