Skip to content

Commit

Permalink
Exclusion TimeWindow and compute TimeWindow on job insertion
Browse files Browse the repository at this point in the history
  • Loading branch information
croooo committed Sep 19, 2023
1 parent 2aa40b3 commit fa2fdf6
Show file tree
Hide file tree
Showing 7 changed files with 91 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -135,11 +135,12 @@ public InsertionData getInsertionData(final VehicleRoute currentRoute, final Job
nextAct = end;
tourEnd = true;
}

ActivityContext activityContext = new ActivityContext();
activityContext.setInsertionIndex(actIndex);
insertionContext.setActivityContext(activityContext);
boolean not_fulfilled_break = true;
for(TimeWindow timeWindow : service.getTimeWindows()) {
ActivityContext activityContext = new ActivityContext();
activityContext.setInsertionIndex(actIndex);
insertionContext.setActivityContext(activityContext);
for(TimeWindow timeWindow : service.getTimeWindows(insertionContext)) {
if (!timeWindow.isApplicable(insertionContext)) {
timeWindow = defaultTimeWindow;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import com.graphhopper.jsprit.core.problem.Capacity;
import com.graphhopper.jsprit.core.problem.Location;
import com.graphhopper.jsprit.core.problem.Skills;
import com.graphhopper.jsprit.core.problem.misc.JobInsertionContext;
import com.graphhopper.jsprit.core.problem.solution.route.activity.TimeWindow;
import com.graphhopper.jsprit.core.problem.solution.route.activity.TimeWindows;
import com.graphhopper.jsprit.core.problem.solution.route.activity.TimeWindowsImpl;
Expand Down Expand Up @@ -87,7 +88,7 @@ public static Builder newInstance(String id) {

protected Location location;

protected TimeWindowsImpl timeWindows;
protected TimeWindows timeWindows;

private boolean twAdded = false;

Expand Down Expand Up @@ -310,6 +311,10 @@ public Collection<TimeWindow> getTimeWindows(){
return timeWindows.getTimeWindows();
}

public Collection<TimeWindow> getTimeWindows(JobInsertionContext insertionContext){
return timeWindows.getTimeWindows(insertionContext);
}

@Override
public String getId() {
return id;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import com.graphhopper.jsprit.core.problem.Location;
import com.graphhopper.jsprit.core.problem.Skills;
import com.graphhopper.jsprit.core.problem.solution.route.activity.TimeWindow;
import com.graphhopper.jsprit.core.problem.solution.route.activity.TimeWindows;
import com.graphhopper.jsprit.core.problem.solution.route.activity.TimeWindowsImpl;

import java.util.ArrayList;
Expand Down Expand Up @@ -76,13 +77,13 @@ public static class Builder {

private Location deliveryLocation_;

protected TimeWindowsImpl deliveryTimeWindows;
protected TimeWindows deliveryTimeWindows;

private boolean deliveryTimeWindowAdded = false;

private boolean pickupTimeWindowAdded = false;

private TimeWindowsImpl pickupTimeWindows;
private TimeWindows pickupTimeWindows;

private int priority = 2;

Expand Down Expand Up @@ -367,9 +368,9 @@ public Builder setMaxTimeInVehicle(double maxTimeInVehicle){

private final Location deliveryLocation_;

private final TimeWindowsImpl deliveryTimeWindows;
private final TimeWindows deliveryTimeWindows;

private final TimeWindowsImpl pickupTimeWindows;
private final TimeWindows pickupTimeWindows;

private final int priority;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
* @author stefan schroeder
*/

public class TimeWindow {
public class TimeWindow implements Comparable<TimeWindow> {

/**
* Returns new instance of TimeWindow.
Expand Down Expand Up @@ -126,4 +126,17 @@ public boolean equals(Object obj) {
public boolean isApplicable(JobInsertionContext insertionContext) {
return true;
}

/**
* When computing overlapping time window, return whether this time window will include or exclude the overlapping
* @return
*/
public boolean isExcluding() {
return false;
}

@Override
public int compareTo(TimeWindow tw) {
return (int)(this.getStart() - tw.getStart());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,10 @@ public TimeWindowConditionalOnVehicleType(double start, double end, String vehic
public boolean isApplicable(JobInsertionContext insertionContext) {
return insertionContext.getNewVehicle().getType().getTypeId().equals(vehicleTypeId);
}

@Override
public boolean isExcluding() {
return true;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,17 @@

import java.util.Collection;

import com.graphhopper.jsprit.core.problem.misc.JobInsertionContext;

/**
* Created by schroeder on 20/05/15.
*/
public interface TimeWindows {

public void add(TimeWindow timeWindow);

public Collection<TimeWindow> getTimeWindows();

public Collection<TimeWindow> getTimeWindows(JobInsertionContext insertionContext);

}
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,19 @@
import java.util.Collection;
import java.util.Collections;

import com.graphhopper.jsprit.core.problem.misc.JobInsertionContext;

/**
* Created by schroeder on 26/05/15.
*/
public class TimeWindowsImpl implements TimeWindows {

private Collection<TimeWindow> timeWindows = new ArrayList<TimeWindow>();

public void add(TimeWindow timeWindow){
@Override
public void add(TimeWindow timeWindow) {
// TODO : avoid overlaping for same type of TW ?
/*
for(TimeWindow tw : timeWindows){
if(timeWindow.getStart() > tw.getStart() && timeWindow.getStart() < tw.getEnd()){
throw new IllegalArgumentException("time-windows cannot overlap each other. overlap: " + tw + ", " + timeWindow);
Expand All @@ -41,13 +46,56 @@ public void add(TimeWindow timeWindow){
throw new IllegalArgumentException("time-windows cannot overlap each other. overlap: " + tw + ", " + timeWindow);
}
}
*/
timeWindows.add(timeWindow);
}

@Override
public Collection<TimeWindow> getTimeWindows() {
return Collections.unmodifiableCollection(timeWindows);
}

@Override
public Collection<TimeWindow> getTimeWindows(JobInsertionContext insertionContext) {
// Reorder by start time
ArrayList<TimeWindow> twList = new ArrayList<TimeWindow>(timeWindows);
Collections.sort(twList);

ArrayList<TimeWindow> result = new ArrayList<TimeWindow>();
int startIdx = 1;
boolean hasExcludingTW = false;
boolean hasNonExcludingTW = false;
for (TimeWindow timeWindow : twList) {
if (!timeWindow.isApplicable(insertionContext)) {
continue;
}
for (int i = startIdx; i < twList.size(); i++) {
if (!timeWindow.isApplicable(insertionContext) || timeWindow == twList.get(i)) {
continue;
}

// Check if overlap
if (twList.get(i).getStart() < timeWindow.getEnd()) {
// Which TW intersect
result.add(TimeWindow.newInstance(
timeWindow.isExcluding() ? timeWindow.getStart() : twList.get(i).getStart(),
timeWindow.isExcluding() ? timeWindow.getEnd() : twList.get(i).getEnd()));
}
}
startIdx++;
hasExcludingTW |= timeWindow.isExcluding();
hasNonExcludingTW |= !timeWindow.isExcluding();
}
if (result.isEmpty()) {
if (hasExcludingTW ^ hasNonExcludingTW) {
return twList;
} else {
result.add(TimeWindow.newInstance(0.0, Double.MAX_VALUE));
}
}
return result;
}

@Override
public String toString() {
StringBuffer sb = new StringBuffer(timeWindows.size() * 60);
Expand Down

0 comments on commit fa2fdf6

Please sign in to comment.