From f733587b2b3d3627dc27a98cc5ad346f5bc0cb85 Mon Sep 17 00:00:00 2001 From: oblonski <4sschroeder@gmail.com> Date: Mon, 6 Oct 2014 16:47:15 +0200 Subject: [PATCH] add and test removeActivity(act) and hasActivity(act) in TourActivities --- .../route/activity/TourActivities.java | 113 ++++++--- .../solution/route/activity/TestTour.java | 118 --------- .../route/activity/TestTourActivities.java | 230 ++++++++++++++++++ 3 files changed, 315 insertions(+), 146 deletions(-) delete mode 100644 jsprit-core/src/test/java/jsprit/core/problem/solution/route/activity/TestTour.java create mode 100644 jsprit-core/src/test/java/jsprit/core/problem/solution/route/activity/TestTourActivities.java diff --git a/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/TourActivities.java b/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/TourActivities.java index e888bb5c..c543475c 100644 --- a/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/TourActivities.java +++ b/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/TourActivities.java @@ -1,16 +1,16 @@ /******************************************************************************* - * Copyright (C) 2013 Stefan Schroeder - * + * Copyright (C) 2014 Stefan Schroeder + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either + * License as published by the Free Software Foundation; either * version 3.0 of the License, or (at your option) any later version. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see . ******************************************************************************/ @@ -34,8 +34,8 @@ public class TourActivities { public static TourActivities copyOf(TourActivities tourActivities){ return new TourActivities(tourActivities); } - - public static class ReverseActivityIterator implements Iterator { + + public static class ReverseActivityIterator implements Iterator { private List acts; private int currentIndex; @@ -78,19 +78,28 @@ public class TourActivities { private final Set jobs = new HashSet(); - private final Map> job2activityIndeces = new HashMap>(); - + private final Set activities = new HashSet(); + private ReverseActivityIterator backward; private TourActivities(TourActivities tour2copy) { for (TourActivity tourAct : tour2copy.getActivities()) { TourActivity newAct = tourAct.duplicate(); this.tourActivities.add(newAct); - addJob(newAct); + addToActivitySet(newAct); + addJob(newAct); } } - - public TourActivities(){ + + private void addToActivitySet(TourActivity newAct) { + activities.add(newAct); + } + + private void removeFromActivitySet(TourActivity act) { + activities.remove(act); + } + + public TourActivities(){ } @@ -111,10 +120,8 @@ public class TourActivities { } /** - * Returns true if job is in jobList, otherwise false. - * - * @param job - * @return + * @param job that needs to be looked up + * @return true if job is in jobList, otherwise false. */ public boolean servesJob(Job job) { return jobs.contains(job); @@ -126,10 +133,10 @@ public class TourActivities { } /** - * Removes job AND belonging activity from tour and returns true if job has been removed, otherwise false. + * Removes job AND belonging activity from tour. * - * @param job - * @return + * @param job to be removed + * @return true if job has been removed, otherwise false. */ public boolean removeJob(Job job){ boolean jobRemoved = false; @@ -145,7 +152,8 @@ public class TourActivities { if(c instanceof JobActivity){ if(job.equals(((JobActivity) c).getJob())){ tourActivities.remove(c); - activityRemoved = true; + removeFromActivitySet(c); + activityRemoved = true; } } } @@ -153,14 +161,61 @@ public class TourActivities { return activityRemoved; } - /** + /** + * Returns true if this contains specified activity. + * + * @param activity to be looked up + * @return true if this contains specified activity, false otherwise + */ + public boolean hasActivity(TourActivity activity){ + return activities.contains(activity); + } + + /** + * Removes activity from this activity sequence. Removes its corresponding job as well, if there are no other activities + * related to this job. + * + * @param activity to be removed + * @return true if activity has been removed, false otherwise + */ + public boolean removeActivity(TourActivity activity) { + Job job = null; + if(activity instanceof JobActivity){ + job = ((JobActivity) activity).getJob(); + } + boolean jobIsAlsoAssociateToOtherActs = false; + boolean actRemoved = false; + List acts = new ArrayList(tourActivities); + for(TourActivity act : acts){ + if(act == activity){ + tourActivities.remove(act); + removeFromActivitySet(act); + actRemoved = true; + } + else{ + if(act instanceof JobActivity && job != null){ + if(((JobActivity) act).getJob().equals(job)){ + jobIsAlsoAssociateToOtherActs = true; + } + } + } + } + if(!jobIsAlsoAssociateToOtherActs && actRemoved){ + jobs.remove(job); + } + return actRemoved; + } + + + + /** * Inserts the specified activity add the specified insertionIndex. Shifts the element currently at that position (if any) and * any subsequent elements to the right (adds one to their indices). *

If specified activity instanceof JobActivity, it adds job to jobList. *

If insertionIndex > tourActivitiies.size(), it just adds the specified act at the end. * - * @param insertionIndex - * @param act + * @param insertionIndex index where activity needs to be inserted + * @param act activity to be inserted * @throws IndexOutOfBoundsException if insertionIndex < 0; */ public void addActivity(int insertionIndex, TourActivity act) { @@ -180,19 +235,21 @@ public class TourActivities { else if(insertionIndex >= tourActivities.size()) { tourActivities.add(act); } - addJob(act); + addToActivitySet(act); + addJob(act); } /** * Adds specified activity at the end of activity-list. *

If act instanceof JobActivity, it adds underlying job also. * @throws IllegalStateException if activity-list already contains act. - * @param act + * @param act to be added */ public void addActivity(TourActivity act){ if(tourActivities.contains(act)) throw new IllegalStateException("act " + act + " already in tour. cannot add act twice."); tourActivities.add(act); - addJob(act); + addToActivitySet(act); + addJob(act); } private void addJob(TourActivity act) { @@ -203,9 +260,9 @@ public class TourActivities { } /** - * Returns number of jobs. + * Returns number of jobs assiciated to activities in this activity sequence. * - * @return + * @return no. of jobs */ public int jobSize() { return jobs.size(); diff --git a/jsprit-core/src/test/java/jsprit/core/problem/solution/route/activity/TestTour.java b/jsprit-core/src/test/java/jsprit/core/problem/solution/route/activity/TestTour.java deleted file mode 100644 index d3aa8a17..00000000 --- a/jsprit-core/src/test/java/jsprit/core/problem/solution/route/activity/TestTour.java +++ /dev/null @@ -1,118 +0,0 @@ -/******************************************************************************* - * Copyright (C) 2014 Stefan Schroeder - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - ******************************************************************************/ -package jsprit.core.problem.solution.route.activity; - -import jsprit.core.problem.job.Service; -import jsprit.core.problem.job.Shipment; -import org.junit.Before; -import org.junit.Test; - -import static org.junit.Assert.*; - - - -public class TestTour { - - private Service service; - private ServiceActivity act; - private TourActivities tour; - - @Before - public void doBefore(){ - service = Service.Builder.newInstance("yo").addSizeDimension(0, 10).setLocationId("loc").build(); - act = ServiceActivity.newInstance(service); - tour = new TourActivities(); - } - - @Test - public void whenAddingServiceAct_serviceActIsAdded(){ - assertFalse(tour.servesJob(service)); - tour.addActivity(act); - assertTrue(tour.servesJob(service)); - } - - @Test(expected=IllegalStateException.class) - public void whenAddingServiceActTwice_anExceptionIsThrown(){ - assertFalse(tour.servesJob(service)); - tour.addActivity(act); - tour.addActivity(act); - } - - @Test - public void whenAddingServiceAndRemovingItImmediately_tourShouldNotServeServiceAnymore(){ - assertFalse(tour.servesJob(service)); - tour.addActivity(act); - assertTrue(tour.servesJob(service)); - tour.removeJob(service); - assertFalse(tour.servesJob(service)); - } - - @Test - public void whenAddingAServiceAndThenRemovingTheServiceAgain_tourShouldNotServeItAnymore(){ - assertEquals(0, tour.getActivities().size()); - tour.addActivity(act); - assertEquals(1, tour.getActivities().size()); - Service anotherServiceInstance = Service.Builder.newInstance("yo").addSizeDimension(0, 10).setLocationId("loc").build(); - assertTrue(service.equals(anotherServiceInstance)); - boolean removed = tour.removeJob(anotherServiceInstance); - assertTrue(removed); - assertEquals(0, tour.getActivities().size()); - } - - @Test - public void whenAddingAShipmentActivity_tourShouldServeShipment(){ - Shipment s = Shipment.Builder.newInstance("s").addSizeDimension(0, 1).setDeliveryLocationId("delLoc").setPickupLocationId("pickLoc").build(); - TourShipmentActivityFactory fac = new DefaultShipmentActivityFactory(); - TourActivity pickupShipment = fac.createPickup(s); - TourActivity deliverShipment = fac.createDelivery(s); - tour.addActivity(pickupShipment); - tour.addActivity(deliverShipment); - assertTrue(tour.servesJob(s)); - assertEquals(2,tour.getActivities().size()); - } - - - - @Test - public void whenRemovingShipment_tourShouldNotServiceItAnymore(){ - Shipment s = Shipment.Builder.newInstance("s").addSizeDimension(0, 1).setDeliveryLocationId("delLoc").setPickupLocationId("pickLoc").build(); - TourShipmentActivityFactory fac = new DefaultShipmentActivityFactory(); - TourActivity pickupShipment = fac.createPickup(s); - TourActivity deliverShipment = fac.createDelivery(s); - tour.addActivity(pickupShipment); - tour.addActivity(deliverShipment); - - tour.removeJob(s); - assertFalse(tour.servesJob(s)); - } - - - @Test - public void whenRemovingShipment_theirCorrespondingActivitiesShouldBeRemoved(){ - Shipment s = Shipment.Builder.newInstance("s").addSizeDimension(0, 1).setDeliveryLocationId("delLoc").setPickupLocationId("pickLoc").build(); - TourShipmentActivityFactory fac = new DefaultShipmentActivityFactory(); - TourActivity pickupShipment = fac.createPickup(s); - TourActivity deliverShipment = fac.createDelivery(s); - tour.addActivity(pickupShipment); - tour.addActivity(deliverShipment); - - assertEquals(2, tour.getActivities().size()); - tour.removeJob(s); - assertEquals(0, tour.getActivities().size()); - } - -} diff --git a/jsprit-core/src/test/java/jsprit/core/problem/solution/route/activity/TestTourActivities.java b/jsprit-core/src/test/java/jsprit/core/problem/solution/route/activity/TestTourActivities.java new file mode 100644 index 00000000..e8bfad99 --- /dev/null +++ b/jsprit-core/src/test/java/jsprit/core/problem/solution/route/activity/TestTourActivities.java @@ -0,0 +1,230 @@ +/******************************************************************************* + * Copyright (C) 2014 Stefan Schroeder + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + ******************************************************************************/ +package jsprit.core.problem.solution.route.activity; + +import jsprit.core.problem.job.Service; +import jsprit.core.problem.job.Shipment; +import org.junit.Before; +import org.junit.Test; + +import static org.junit.Assert.*; + + + +public class TestTourActivities { + + private Service service; + private ServiceActivity act; + private TourActivities tour; + + @Before + public void doBefore(){ + service = Service.Builder.newInstance("yo").addSizeDimension(0, 10).setLocationId("loc").build(); + act = ServiceActivity.newInstance(service); + tour = new TourActivities(); + } + + @Test + public void whenAddingServiceAct_serviceActIsAdded(){ + assertFalse(tour.servesJob(service)); + tour.addActivity(act); + assertTrue(tour.servesJob(service)); + } + + @Test(expected=IllegalStateException.class) + public void whenAddingServiceActTwice_anExceptionIsThrown(){ + assertFalse(tour.servesJob(service)); + tour.addActivity(act); + tour.addActivity(act); + } + + @Test + public void whenAddingServiceAndRemovingItImmediately_tourShouldNotServeServiceAnymore(){ + assertFalse(tour.servesJob(service)); + tour.addActivity(act); + assertTrue(tour.servesJob(service)); + tour.removeJob(service); + assertFalse(tour.servesJob(service)); + } + + @Test + public void whenAddingAServiceAndThenRemovingTheServiceAgain_tourShouldNotServeItAnymore(){ + assertEquals(0, tour.getActivities().size()); + tour.addActivity(act); + assertEquals(1, tour.getActivities().size()); + Service anotherServiceInstance = Service.Builder.newInstance("yo").addSizeDimension(0, 10).setLocationId("loc").build(); + assertTrue(service.equals(anotherServiceInstance)); + boolean removed = tour.removeJob(anotherServiceInstance); + assertTrue(removed); + assertEquals(0, tour.getActivities().size()); + } + + @Test + public void whenAddingAShipmentActivity_tourShouldServeShipment(){ + Shipment s = Shipment.Builder.newInstance("s").addSizeDimension(0, 1).setDeliveryLocationId("delLoc").setPickupLocationId("pickLoc").build(); + TourShipmentActivityFactory fac = new DefaultShipmentActivityFactory(); + TourActivity pickupShipment = fac.createPickup(s); + TourActivity deliverShipment = fac.createDelivery(s); + tour.addActivity(pickupShipment); + tour.addActivity(deliverShipment); + assertTrue(tour.servesJob(s)); + assertEquals(2,tour.getActivities().size()); + } + + + + @Test + public void whenRemovingShipment_tourShouldNotServiceItAnymore(){ + Shipment s = Shipment.Builder.newInstance("s").addSizeDimension(0, 1).setDeliveryLocationId("delLoc").setPickupLocationId("pickLoc").build(); + TourShipmentActivityFactory fac = new DefaultShipmentActivityFactory(); + TourActivity pickupShipment = fac.createPickup(s); + TourActivity deliverShipment = fac.createDelivery(s); + tour.addActivity(pickupShipment); + tour.addActivity(deliverShipment); + + tour.removeJob(s); + assertFalse(tour.servesJob(s)); + } + + + @Test + public void whenRemovingShipment_theirCorrespondingActivitiesShouldBeRemoved(){ + Shipment s = Shipment.Builder.newInstance("s").addSizeDimension(0, 1).setDeliveryLocationId("delLoc").setPickupLocationId("pickLoc").build(); + TourShipmentActivityFactory fac = new DefaultShipmentActivityFactory(); + TourActivity pickupShipment = fac.createPickup(s); + TourActivity deliverShipment = fac.createDelivery(s); + tour.addActivity(pickupShipment); + tour.addActivity(deliverShipment); + + assertEquals(2, tour.getActivities().size()); + tour.removeJob(s); + assertEquals(0, tour.getActivities().size()); + } + + @Test + public void removingActivityShouldWork(){ + tour.addActivity(act); + assertTrue(tour.servesJob(service)); + assertTrue(tour.hasActivity(act)); + + tour.removeActivity(act); + + assertTrue(tour.isEmpty()); + assertFalse(tour.hasActivity(act)); + assertFalse(tour.servesJob(service)); + assertEquals(0,tour.jobSize()); + } + + @Test + public void copyingSeqShouldWork(){ + tour.addActivity(act); + + assertTrue(tour.servesJob(service)); + assertTrue(tour.hasActivity(act)); + + TourActivities acts = TourActivities.copyOf(tour); + + assertTrue(acts.servesJob(service)); + assertTrue(acts.hasActivity(act)); + } + + @Test + public void removingShipmentActivityShouldWork(){ + Shipment s = Shipment.Builder.newInstance("s").addSizeDimension(0, 1).setDeliveryLocationId("delLoc").setPickupLocationId("pickLoc").build(); + TourShipmentActivityFactory fac = new DefaultShipmentActivityFactory(); + TourActivity pickupShipment = fac.createPickup(s); + TourActivity deliverShipment = fac.createDelivery(s); + tour.addActivity(pickupShipment); + tour.addActivity(deliverShipment); + + assertEquals(1,tour.jobSize()); + assertEquals(2,tour.getActivities().size()); + assertTrue(tour.getActivities().contains(pickupShipment)); + assertTrue(tour.hasActivity(pickupShipment)); + assertTrue(tour.hasActivity(deliverShipment)); + + tour.removeActivity(pickupShipment); + + assertEquals(1,tour.jobSize()); + assertEquals(1, tour.getActivities().size()); + assertTrue(tour.hasActivity(deliverShipment)); + assertFalse(tour.hasActivity(pickupShipment)); + assertFalse(tour.getActivities().contains(pickupShipment)); + + } + + @Test + public void whenCopyingShipmentActivitySeq_jobSizeShouldBeCorrect(){ + Shipment s = Shipment.Builder.newInstance("s").addSizeDimension(0, 1).setDeliveryLocationId("delLoc").setPickupLocationId("pickLoc").build(); + TourShipmentActivityFactory fac = new DefaultShipmentActivityFactory(); + TourActivity pickupShipment = fac.createPickup(s); + TourActivity deliverShipment = fac.createDelivery(s); + tour.addActivity(pickupShipment); + tour.addActivity(deliverShipment); + + assertEquals(1,tour.jobSize()); + assertEquals(2,tour.getActivities().size()); + assertTrue(tour.getActivities().contains(pickupShipment)); + assertTrue(tour.hasActivity(pickupShipment)); + assertTrue(tour.hasActivity(deliverShipment)); + + TourActivities copiedTour = TourActivities.copyOf(tour); + + assertEquals(1,copiedTour.jobSize()); + } + + @Test + public void whenCopyingShipmentActivitySeq_noActivitiesShouldBeCorrect(){ + Shipment s = Shipment.Builder.newInstance("s").addSizeDimension(0, 1).setDeliveryLocationId("delLoc").setPickupLocationId("pickLoc").build(); + TourShipmentActivityFactory fac = new DefaultShipmentActivityFactory(); + TourActivity pickupShipment = fac.createPickup(s); + TourActivity deliverShipment = fac.createDelivery(s); + tour.addActivity(pickupShipment); + tour.addActivity(deliverShipment); + + assertEquals(1,tour.jobSize()); + assertEquals(2,tour.getActivities().size()); + assertTrue(tour.getActivities().contains(pickupShipment)); + assertTrue(tour.hasActivity(pickupShipment)); + assertTrue(tour.hasActivity(deliverShipment)); + + TourActivities copiedTour = TourActivities.copyOf(tour); + + assertEquals(2,copiedTour.getActivities().size()); + } + + @Test + public void whenCopyingShipmentActivitySeq_itShouldContaintPickupAct(){ + Shipment s = Shipment.Builder.newInstance("s").addSizeDimension(0, 1).setDeliveryLocationId("delLoc").setPickupLocationId("pickLoc").build(); + TourShipmentActivityFactory fac = new DefaultShipmentActivityFactory(); + TourActivity pickupShipment = fac.createPickup(s); + TourActivity deliverShipment = fac.createDelivery(s); + tour.addActivity(pickupShipment); + tour.addActivity(deliverShipment); + + assertEquals(1,tour.jobSize()); + assertEquals(2,tour.getActivities().size()); + assertTrue(tour.getActivities().contains(pickupShipment)); + assertTrue(tour.hasActivity(pickupShipment)); + assertTrue(tour.hasActivity(deliverShipment)); + + TourActivities copiedTour = TourActivities.copyOf(tour); + + assertTrue(copiedTour.servesJob(s)); + } + +}