1
0
Fork 0
mirror of https://github.com/graphhopper/jsprit.git synced 2020-01-24 07:45:05 +01:00

Merge pull request #477 from einride/master

enhancements in TourActivities
This commit is contained in:
Stefan Schröder 2019-09-12 11:28:49 +02:00 committed by GitHub
commit 74c3c6839b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 58 additions and 17 deletions

View file

@ -4,6 +4,7 @@ matrix:
fast_finish: true fast_finish: true
include: include:
- jdk: oraclejdk8 - jdk: oraclejdk8
dist: trusty
# Java 9 needs to be manually installed/upgraded # Java 9 needs to be manually installed/upgraded
# see: https://github.com/travis-ci/travis-ci/issues/2968#issuecomment-149164058 # see: https://github.com/travis-ci/travis-ci/issues/2968#issuecomment-149164058
- jdk: oraclejdk9 - jdk: oraclejdk9

View file

@ -45,8 +45,6 @@ public class BreakScheduling implements InsertionStartsListener,JobInsertedListe
private final EventListeners eventListeners; private final EventListeners eventListeners;
private Set<VehicleRoute> modifiedRoutes = new HashSet<VehicleRoute>();
public BreakScheduling(VehicleRoutingProblem vrp, StateManager stateManager, ConstraintManager constraintManager) { public BreakScheduling(VehicleRoutingProblem vrp, StateManager stateManager, ConstraintManager constraintManager) {
this.stateManager = stateManager; this.stateManager = stateManager;
this.breakInsertionCalculator = new BreakInsertionCalculator(vrp.getTransportCosts(), vrp.getActivityCosts(), new LocalActivityInsertionCostsCalculator(vrp.getTransportCosts(), vrp.getActivityCosts(), stateManager), constraintManager, vrp.getJobActivityFactory()); this.breakInsertionCalculator = new BreakInsertionCalculator(vrp.getTransportCosts(), vrp.getActivityCosts(), new LocalActivityInsertionCostsCalculator(vrp.getTransportCosts(), vrp.getActivityCosts(), stateManager), constraintManager, vrp.getJobActivityFactory());
@ -78,7 +76,6 @@ public class BreakScheduling implements InsertionStartsListener,JobInsertedListe
@Override @Override
public void ruinStarts(Collection<VehicleRoute> routes) { public void ruinStarts(Collection<VehicleRoute> routes) {
} }
@Override @Override
@ -88,7 +85,7 @@ public class BreakScheduling implements InsertionStartsListener,JobInsertedListe
boolean removed = route.getTourActivities().removeJob(aBreak); boolean removed = route.getTourActivities().removeJob(aBreak);
if(removed) logger.trace("ruin: {}", aBreak.getId()); if(removed) logger.trace("ruin: {}", aBreak.getId());
} }
List<Break> breaks = new ArrayList<Break>(); List<Break> breaks = new ArrayList<>();
for (Job j : unassignedJobs) { for (Job j : unassignedJobs) {
if (j instanceof Break) { if (j instanceof Break) {
breaks.add((Break) j); breaks.add((Break) j);
@ -99,7 +96,6 @@ public class BreakScheduling implements InsertionStartsListener,JobInsertedListe
@Override @Override
public void removed(Job job, VehicleRoute fromRoute) { public void removed(Job job, VehicleRoute fromRoute) {
if(fromRoute.getVehicle().getBreak() != null) modifiedRoutes.add(fromRoute);
} }
@Override @Override
@ -119,6 +115,5 @@ public class BreakScheduling implements InsertionStartsListener,JobInsertedListe
} }
} }
} }
} }
} }

View file

@ -81,7 +81,6 @@ public class TourActivities {
} }
public TourActivities() { public TourActivities() {
} }
public List<TourActivity> getActivities() { public List<TourActivity> getActivities() {
@ -89,7 +88,30 @@ public class TourActivities {
} }
public Iterator<TourActivity> iterator() { public Iterator<TourActivity> iterator() {
return tourActivities.iterator(); final Iterator<TourActivity> iterator = tourActivities.iterator();
return new Iterator<TourActivity>() {
private TourActivity lastReturned = null;
@Override
public boolean hasNext() {
return iterator.hasNext();
}
@Override
public TourActivity next() {
return lastReturned = iterator.next();
}
@Override
public void remove() {
if (lastReturned instanceof JobActivity) {
throw new IllegalStateException("Cannot remove JobActivities via iterator. "
+ "Use TourActivities.removeActivity(), or alternatively, consider TourActivities.removeJob()");
} else {
iterator.remove();
}
}
};
} }
public boolean isEmpty() { public boolean isEmpty() {
@ -154,26 +176,35 @@ public class TourActivities {
* @return true if activity has been removed, false otherwise * @return true if activity has been removed, false otherwise
*/ */
public boolean removeActivity(TourActivity activity) { public boolean removeActivity(TourActivity activity) {
Job job = null; if (!(activity instanceof JobActivity)) {
if (activity instanceof JobActivity) { //assumes that an activity can be added only once to tourActivities
job = ((JobActivity) activity).getJob(); return tourActivities.remove(activity);
} }
Job job = ((JobActivity) activity).getJob();
boolean jobIsAlsoAssociateToOtherActs = false; boolean jobIsAlsoAssociateToOtherActs = false;
boolean actRemoved = false; boolean actRemoved = false;
List<TourActivity> acts = new ArrayList<>(tourActivities); for (TourActivity act : new ArrayList<>(tourActivities)) {
for (TourActivity act : acts) {
if (act == activity) { if (act == activity) {
tourActivities.remove(act); tourActivities.remove(act);
if (jobIsAlsoAssociateToOtherActs) {
// other activities also refer to job --> do not remove job
// thus no need to iterate any further
return true;
}
actRemoved = true; actRemoved = true;
} else { } else {
if (act instanceof JobActivity && job != null) { if (act instanceof JobActivity && ((JobActivity) act).getJob().equals(job)) {
if (((JobActivity) act).getJob().equals(job)) { if (actRemoved) {
jobIsAlsoAssociateToOtherActs = true; // other activities also refer to job --> do not remove job
// thus no need to iterate any further
return true;
} }
jobIsAlsoAssociateToOtherActs = true;
} }
} }
} }
if (!jobIsAlsoAssociateToOtherActs && actRemoved) { if (actRemoved) {
jobs.remove(job); jobs.remove(job);
} }
return actRemoved; return actRemoved;

View file

@ -22,6 +22,7 @@ import com.graphhopper.jsprit.core.problem.job.Service;
import com.graphhopper.jsprit.core.problem.job.Shipment; import com.graphhopper.jsprit.core.problem.job.Shipment;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.mockito.Mockito;
import static org.junit.Assert.*; import static org.junit.Assert.*;
@ -118,6 +119,19 @@ public class TestTourActivities {
assertEquals(0, tour.getActivities().size()); assertEquals(0, tour.getActivities().size());
} }
@Test
public void removingNonJobActivityShouldWork() {
TourActivity nonJobAct = Mockito.mock(TourActivity.class);
tour.addActivity(nonJobAct);
assertTrue(tour.getActivities().contains(nonJobAct));
tour.removeActivity(nonJobAct);
assertTrue(tour.isEmpty());
assertFalse(tour.getActivities().contains(nonJobAct));
}
@Test @Test
public void removingActivityShouldWork() { public void removingActivityShouldWork() {
tour.addActivity(act); tour.addActivity(act);