1
0
Fork 0
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:
oblonski 2017-07-05 10:41:23 +02:00
parent b5998e1d93
commit db0c39e1c2
No known key found for this signature in database
GPG key ID: 179DE487285680D1
22 changed files with 448 additions and 436 deletions

View file

@ -17,14 +17,6 @@
*/
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.listener.SearchStrategyListener;
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.activity.TourActivity;
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;
/**

View file

@ -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) {
return actStartTimes.get(v.getVehicleTypeIdentifier().getIndex()).get(act);
}

View file

@ -74,14 +74,13 @@ public final class Location implements HasIndex, HasId {
/**
* Sets user specific domain data associated with the object.
*
* <p>
* <p>
* The user data is a black box for the framework, it only stores it,
* but never interacts with it in any way.
* </p>
*
* @param userData
* any object holding the domain specific user data
* @param userData any object holding the domain specific user data
* associated with the object.
* @return builder
*/
@ -191,7 +190,9 @@ public final class Location implements HasIndex, HasId {
return coordinate;
}
public String getName() { return name; }
public String getName() {
return name;
}
@Override
public boolean equals(Object o) {

View file

@ -72,6 +72,7 @@ public interface Vehicle extends HasId, HasIndex {
public abstract VehicleTypeKey getVehicleTypeIdentifier();
public abstract Skills getSkills();
/**
* @return User-specific domain data associated with the vehicle
*/

View file

@ -17,13 +17,12 @@
*/
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.Location;
import com.graphhopper.jsprit.core.problem.Skills;
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.
*
* <p>
* <p>
* The user data is a black box for the framework, it only stores it,
* but never interacts with it in any way.
* </p>
*
* @param userData
* any object holding the domain specific user data
* @param userData any object holding the domain specific user data
* associated with the object.
* @return builder
*/

View file

@ -138,9 +138,10 @@ public class UnassignedJobReasonTracker implements JobUnassignedListener {
public String getHumanReadableReason(String failedConstraintName) {
return getCodesToReason().get(getCode(failedConstraintName));
}
/**
* Returns the most likely reason code i.e. the reason (failed constraint) being observed most often.
*
* <p>
* 1 --> "cannot serve required skill
* 2 --> "cannot be visited within time window"
* 3 --> "does not fit into any vehicle due to capacity"

View file

@ -18,17 +18,14 @@
package com.graphhopper.jsprit.core.problem;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import com.graphhopper.jsprit.core.util.Coordinate;
import org.junit.Assert;
import org.junit.Test;
import java.util.HashMap;
import java.util.Map;
import org.junit.Assert;
import org.junit.Test;
import com.graphhopper.jsprit.core.util.Coordinate;
import static org.junit.Assert.*;
/**
* Created by schroeder on 16.12.14.

View file

@ -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.VehicleImpl;
import com.graphhopper.jsprit.core.util.ManhattanCosts;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import java.util.*;
import static org.mockito.Mockito.mock;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
/**
* Created by schroeder on 18/05/16.

View file

@ -17,18 +17,14 @@
*/
package com.graphhopper.jsprit.core.problem.job;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import com.graphhopper.jsprit.core.problem.Location;
import org.junit.Assert;
import org.junit.Test;
import java.util.HashMap;
import java.util.Map;
import org.junit.Assert;
import org.junit.Test;
import com.graphhopper.jsprit.core.problem.Location;
import static org.junit.Assert.*;
public class DeliveryTest {

View file

@ -17,18 +17,14 @@
*/
package com.graphhopper.jsprit.core.problem.job;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import com.graphhopper.jsprit.core.problem.Location;
import org.junit.Assert;
import org.junit.Test;
import java.util.HashMap;
import java.util.Map;
import org.junit.Assert;
import org.junit.Test;
import com.graphhopper.jsprit.core.problem.Location;
import static org.junit.Assert.*;
public class PickupTest {

View file

@ -17,25 +17,19 @@
*/
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 com.graphhopper.jsprit.core.problem.Location;
import com.graphhopper.jsprit.core.problem.solution.route.activity.TimeWindow;
import org.junit.Assert;
import org.junit.Test;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.junit.Assert;
import org.junit.Test;
import com.graphhopper.jsprit.core.problem.Location;
import com.graphhopper.jsprit.core.problem.solution.route.activity.TimeWindow;
import static org.hamcrest.core.Is.is;
import static org.hamcrest.core.IsCollectionContaining.hasItem;
import static org.junit.Assert.*;
public class ServiceTest {

View file

@ -17,25 +17,19 @@
*/
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.solution.route.activity.TimeWindow;
import com.graphhopper.jsprit.core.util.Coordinate;
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 {

View file

@ -18,20 +18,15 @@
package com.graphhopper.jsprit.core.problem.vehicle;
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.assertTrue;
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;
import org.junit.Test;
import java.util.HashMap;
import java.util.Map;
import org.junit.Test;
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;
import static org.junit.Assert.*;
public class VehicleImplTest {

View file

@ -17,15 +17,12 @@
*/
package com.graphhopper.jsprit.core.problem.vehicle;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import org.junit.Test;
import java.util.HashMap;
import java.util.Map;
import org.junit.Test;
import static org.junit.Assert.*;
public class VehicleTypeImplTest {