Skip to content

Instantly share code, notes, and snippets.

@briandilley
Created July 18, 2019 23:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save briandilley/33a36feef99b5fa3608db25c902d29b0 to your computer and use it in GitHub Desktop.
Save briandilley/33a36feef99b5fa3608db25c902d29b0 to your computer and use it in GitHub Desktop.
import java.util.Collection;
import com.graphhopper.jsprit.core.algorithm.recreate.listener.InsertionStartsListener;
import com.graphhopper.jsprit.core.algorithm.recreate.listener.JobInsertedListener;
import com.graphhopper.jsprit.core.algorithm.state.StateId;
import com.graphhopper.jsprit.core.algorithm.state.StateManager;
import com.graphhopper.jsprit.core.algorithm.state.StateUpdater;
import com.graphhopper.jsprit.core.problem.Capacity;
import com.graphhopper.jsprit.core.problem.Location;
import com.graphhopper.jsprit.core.problem.job.Delivery;
import com.graphhopper.jsprit.core.problem.job.Job;
import com.graphhopper.jsprit.core.problem.solution.route.VehicleRoute;
import com.graphhopper.jsprit.core.problem.solution.route.activity.ActivityVisitor;
import com.graphhopper.jsprit.core.problem.solution.route.activity.DeliveryActivity;
import com.graphhopper.jsprit.core.problem.solution.route.activity.PickupActivity;
import com.graphhopper.jsprit.core.problem.solution.route.activity.TourActivity;
public class PendingDeliveriesUpdater
implements ActivityVisitor,
InsertionStartsListener,
JobInsertedListener,
StateUpdater {
public static final int DIM_PENDING_DEPOT_DELIVERIES = 0;
public static final int DIM_PENDING_EXTERNAL_DELIVERIES = 1;
public static final Capacity DEFAULT_VALUE = Capacity.Builder.newInstance()
.addDimension(DIM_PENDING_DEPOT_DELIVERIES, 0)
.addDimension(DIM_PENDING_EXTERNAL_DELIVERIES, 0)
.build();
private StateManager stateManager;
private Capacity currentValue;
private Location depotLocation;
private final StateId STATE_ID;
public PendingDeliveriesUpdater(StateManager stateManager, Location depotLocation) {
this.stateManager = stateManager;
this.depotLocation = depotLocation;
this.STATE_ID = stateManager.createStateId("pending_deliveries");
}
public StateId getStateId() {
return STATE_ID;
}
@Override
public void begin(VehicleRoute route) {
currentValue = stateManager.getRouteState(route, STATE_ID, Capacity.class);
if (currentValue == null) currentValue = DEFAULT_VALUE;
}
@Override
public void visit(TourActivity act) {
boolean locationIsDepot = isDepot(act.getLocation());
boolean pickup = act instanceof PickupActivity;
boolean delivery = act instanceof DeliveryActivity;
if (pickup && locationIsDepot) {
currentValue = addPendingExternalDelivery(currentValue);
} else if (pickup) {
currentValue = addPendingDepotDelivery(currentValue);
} else if (delivery && locationIsDepot) {
currentValue = removePendingDepotDelivery(currentValue);
} else if (delivery) {
currentValue = removePendingExternalDelivery(currentValue);
}
stateManager.putActivityState(act, STATE_ID, currentValue);
}
@Override
public void finish() {
currentValue = DEFAULT_VALUE;
}
@Override
public void informInsertionStarts(Collection<VehicleRoute> vehicleRoutes, Collection<Job> unassignedJobs) {
for (VehicleRoute route : vehicleRoutes) {
insertionStarts(route);
}
}
@Override
public void informJobInserted(Job job2insert, VehicleRoute inRoute, double additionalCosts, double additionalTime) {
if (!(job2insert instanceof Delivery)) {
return;
}
Delivery delivery = (Delivery)job2insert;
Capacity routeState = stateManager.getRouteState(inRoute, STATE_ID, Capacity.class);
if (routeState == null) {
routeState = DEFAULT_VALUE;
}
if (!isDepot(delivery.getLocation())) {
routeState = addPendingExternalDelivery(routeState);
} else {
routeState = addPendingDepotDelivery(routeState);
}
stateManager.putRouteState(inRoute, STATE_ID, routeState);
}
private void insertionStarts(VehicleRoute route) {
Capacity startPending = DEFAULT_VALUE;
for (Job j : route.getTourActivities().getJobs()) {
if (j instanceof Delivery) {
if (!isDepot(((Delivery)j).getLocation())) {
startPending = addPendingExternalDelivery(startPending);
} else {
startPending = addPendingDepotDelivery(startPending);
}
}
}
stateManager.putRouteState(route, STATE_ID, startPending);
}
private boolean isDepot(Location location) {
// TODO: is close
return location.equals(depotLocation);
}
public static Capacity addPendingExternalDelivery(Capacity capacity) {
return Capacity.addup(capacity, Capacity.Builder.newInstance()
.addDimension(DIM_PENDING_EXTERNAL_DELIVERIES, 1)
.build());
}
public static Capacity removePendingExternalDelivery(Capacity capacity) {
return Capacity.addup(capacity, Capacity.Builder.newInstance()
.addDimension(DIM_PENDING_EXTERNAL_DELIVERIES, -1)
.build());
}
public static Capacity addPendingDepotDelivery(Capacity capacity) {
return Capacity.addup(capacity, Capacity.Builder.newInstance()
.addDimension(DIM_PENDING_DEPOT_DELIVERIES, 1)
.build());
}
public static Capacity removePendingDepotDelivery(Capacity capacity) {
return Capacity.addup(capacity, Capacity.Builder.newInstance()
.addDimension(DIM_PENDING_DEPOT_DELIVERIES, -1)
.build());
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment