From cd6f71b1b3e8374d7d529255bf473e83ddce02a6 Mon Sep 17 00:00:00 2001 From: Geoffrey De Smet Date: Sun, 5 Apr 2015 11:33:18 +0200 Subject: [PATCH] refactor to a simpler model: delete BusVisit and BusStartPoint --- .../coachshuttlegathering/domain/Bus.java | 29 ++++- .../coachshuttlegathering/domain/BusHub.java | 2 +- .../{BusStandstill.java => BusOrStop.java} | 10 +- .../domain/BusStartPoint.java | 72 ------------ .../coachshuttlegathering/domain/BusStop.java | 58 +++++++++- .../domain/BusVisit.java | 103 ------------------ .../coachshuttlegathering/domain/Coach.java | 11 ++ .../domain/CoachShuttleGatheringSolution.java | 57 ++++------ .../coachshuttlegathering/domain/Shuttle.java | 7 ++ .../domain/StopOrHub.java | 30 +++++ ...tAngleBusStopDifficultyWeightFactory.java} | 25 ++--- .../CoachShuttleGatheringImporter.java | 57 ++-------- .../CoachShuttleGatheringWorldPanel.java | 51 +++------ .../LatitudeLongitudeTranslator.java | 6 + .../coachShuttleGatheringScoreRules.drl | 9 +- .../coachShuttleGatheringSolverConfig.xml | 4 +- 16 files changed, 214 insertions(+), 317 deletions(-) rename optaplanner-examples/src/main/java/org/optaplanner/examples/coachshuttlegathering/domain/{BusStandstill.java => BusOrStop.java} (88%) delete mode 100644 optaplanner-examples/src/main/java/org/optaplanner/examples/coachshuttlegathering/domain/BusStartPoint.java delete mode 100644 optaplanner-examples/src/main/java/org/optaplanner/examples/coachshuttlegathering/domain/BusVisit.java create mode 100644 optaplanner-examples/src/main/java/org/optaplanner/examples/coachshuttlegathering/domain/StopOrHub.java rename optaplanner-examples/src/main/java/org/optaplanner/examples/coachshuttlegathering/domain/solver/{DepotAngleBusVisitDifficultyWeightFactory.java => DepotAngleBusStopDifficultyWeightFactory.java} (77%) diff --git a/optaplanner-examples/src/main/java/org/optaplanner/examples/coachshuttlegathering/domain/Bus.java b/optaplanner-examples/src/main/java/org/optaplanner/examples/coachshuttlegathering/domain/Bus.java index 0b67176b55..e4c3dea210 100644 --- a/optaplanner-examples/src/main/java/org/optaplanner/examples/coachshuttlegathering/domain/Bus.java +++ b/optaplanner-examples/src/main/java/org/optaplanner/examples/coachshuttlegathering/domain/Bus.java @@ -26,13 +26,16 @@ Coach.class, Shuttle.class }) -public abstract class Bus extends AbstractPersistable { +public abstract class Bus extends AbstractPersistable implements BusOrStop { protected String name; protected RoadLocation departureLocation; protected int capacity; protected int mileageCost; + // Shadow variables + protected BusStop nextStop; + public String getName() { return name; } @@ -65,10 +68,34 @@ public void setMileageCost(int mileageCost) { this.mileageCost = mileageCost; } + @Override + public BusStop getNextStop() { + return nextStop; + } + + @Override + public void setNextStop(BusStop nextStop) { + this.nextStop = nextStop; + } + // ************************************************************************ // Complex methods // ************************************************************************ + public abstract int getSetupCost(); + + @Override + public RoadLocation getLocation() { + return departureLocation; + } + + @Override + public Bus getBus() { + return this; + } + + public abstract int getDistanceFromTo(RoadLocation sourceLocation, RoadLocation targetLocation); + @Override public String toString() { return name; diff --git a/optaplanner-examples/src/main/java/org/optaplanner/examples/coachshuttlegathering/domain/BusHub.java b/optaplanner-examples/src/main/java/org/optaplanner/examples/coachshuttlegathering/domain/BusHub.java index 9926462746..ea52c5c6dd 100644 --- a/optaplanner-examples/src/main/java/org/optaplanner/examples/coachshuttlegathering/domain/BusHub.java +++ b/optaplanner-examples/src/main/java/org/optaplanner/examples/coachshuttlegathering/domain/BusHub.java @@ -21,7 +21,7 @@ import org.optaplanner.examples.common.domain.AbstractPersistable; @XStreamAlias("CsgBusHub") -public class BusHub extends AbstractPersistable { +public class BusHub extends AbstractPersistable implements StopOrHub { protected String name; protected RoadLocation location; diff --git a/optaplanner-examples/src/main/java/org/optaplanner/examples/coachshuttlegathering/domain/BusStandstill.java b/optaplanner-examples/src/main/java/org/optaplanner/examples/coachshuttlegathering/domain/BusOrStop.java similarity index 88% rename from optaplanner-examples/src/main/java/org/optaplanner/examples/coachshuttlegathering/domain/BusStandstill.java rename to optaplanner-examples/src/main/java/org/optaplanner/examples/coachshuttlegathering/domain/BusOrStop.java index 459c93eceb..38a1fa83a6 100644 --- a/optaplanner-examples/src/main/java/org/optaplanner/examples/coachshuttlegathering/domain/BusStandstill.java +++ b/optaplanner-examples/src/main/java/org/optaplanner/examples/coachshuttlegathering/domain/BusOrStop.java @@ -21,7 +21,7 @@ import org.optaplanner.examples.coachshuttlegathering.domain.location.RoadLocation; @PlanningEntity -public interface BusStandstill { +public interface BusOrStop { /** * @return never null @@ -31,13 +31,13 @@ public interface BusStandstill { /** * @return sometimes null */ - BusStartPoint getStartPoint(); + Bus getBus(); /** * @return sometimes null */ - @InverseRelationShadowVariable(sourceVariableName = "previousStandstill") - BusVisit getNextVisit(); - void setNextVisit(BusVisit nextVisit); + @InverseRelationShadowVariable(sourceVariableName = "previousBusOrStop") + BusStop getNextStop(); + void setNextStop(BusStop nextStop); } diff --git a/optaplanner-examples/src/main/java/org/optaplanner/examples/coachshuttlegathering/domain/BusStartPoint.java b/optaplanner-examples/src/main/java/org/optaplanner/examples/coachshuttlegathering/domain/BusStartPoint.java deleted file mode 100644 index 9ae34a885e..0000000000 --- a/optaplanner-examples/src/main/java/org/optaplanner/examples/coachshuttlegathering/domain/BusStartPoint.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright 2015 JBoss Inc - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.optaplanner.examples.coachshuttlegathering.domain; - -import com.thoughtworks.xstream.annotations.XStreamAlias; -import org.optaplanner.examples.coachshuttlegathering.domain.location.RoadLocation; -import org.optaplanner.examples.common.domain.AbstractPersistable; - -@XStreamAlias("CsgBusStartPoint") -public class BusStartPoint extends AbstractPersistable implements BusStandstill { - - protected Bus bus; - - // Shadow variables - protected BusVisit nextVisit; - - public Bus getBus() { - return bus; - } - - public void setBus(Bus bus) { - this.bus = bus; - } - - public BusVisit getNextVisit() { - return nextVisit; - } - - public void setNextVisit(BusVisit nextVisit) { - this.nextVisit = nextVisit; - } - - // ************************************************************************ - // Complex methods - // ************************************************************************ - - public BusStartPoint getStartPoint() { - return this; - } - - public RoadLocation getLocation() { - return bus.getDepartureLocation(); - } - - public boolean isCoach() { - return bus instanceof Coach; - } - - public int getSetupCost() { - return isCoach() ? 0 : ((Shuttle) bus).getSetupCost(); - } - - @Override - public String toString() { - return bus.toString(); - } - -} diff --git a/optaplanner-examples/src/main/java/org/optaplanner/examples/coachshuttlegathering/domain/BusStop.java b/optaplanner-examples/src/main/java/org/optaplanner/examples/coachshuttlegathering/domain/BusStop.java index 3c146a9ddf..735ad9de99 100644 --- a/optaplanner-examples/src/main/java/org/optaplanner/examples/coachshuttlegathering/domain/BusStop.java +++ b/optaplanner-examples/src/main/java/org/optaplanner/examples/coachshuttlegathering/domain/BusStop.java @@ -17,17 +17,30 @@ package org.optaplanner.examples.coachshuttlegathering.domain; import com.thoughtworks.xstream.annotations.XStreamAlias; +import org.optaplanner.core.api.domain.entity.PlanningEntity; +import org.optaplanner.core.api.domain.variable.AnchorShadowVariable; +import org.optaplanner.core.api.domain.variable.PlanningVariable; +import org.optaplanner.core.api.domain.variable.PlanningVariableGraphType; import org.optaplanner.examples.coachshuttlegathering.domain.location.RoadLocation; +import org.optaplanner.examples.coachshuttlegathering.domain.solver.DepotAngleBusStopDifficultyWeightFactory; import org.optaplanner.examples.common.domain.AbstractPersistable; +@PlanningEntity(difficultyWeightFactoryClass = DepotAngleBusStopDifficultyWeightFactory.class) @XStreamAlias("CsgBusStop") -public class BusStop extends AbstractPersistable { +public class BusStop extends AbstractPersistable implements BusOrStop, StopOrHub { protected String name; protected RoadLocation location; protected int passengerQuantity; protected int transportTimeLimit; + // Planning variables: changes during planning, between score calculations. + protected BusOrStop previousBusOrStop; + + // Shadow variables + protected BusStop nextStop; + protected Bus bus; + public String getName() { return name; } @@ -36,6 +49,7 @@ public void setName(String name) { this.name = name; } + @Override public RoadLocation getLocation() { return location; } @@ -59,10 +73,52 @@ public int getTransportTimeLimit() { public void setTransportTimeLimit(int transportTimeLimit) { this.transportTimeLimit = transportTimeLimit; } + + @PlanningVariable(valueRangeProviderRefs = {"coachRange", "shuttleRange", "stopRange"}, + graphType = PlanningVariableGraphType.CHAINED) + public BusOrStop getPreviousBusOrStop() { + return previousBusOrStop; + } + + public void setPreviousBusOrStop(BusOrStop previousBusOrStop) { + this.previousBusOrStop = previousBusOrStop; + } + + @Override + public BusStop getNextStop() { + return nextStop; + } + + @Override + public void setNextStop(BusStop nextStop) { + this.nextStop = nextStop; + } + + @AnchorShadowVariable(sourceVariableName = "previousBusOrStop") + @Override + public Bus getBus() { + return bus; + } + + public void setBus(Bus bus) { + this.bus = bus; + } + // ************************************************************************ // Complex methods // ************************************************************************ + public int getDistanceFromPreviousCost() { + if (previousBusOrStop == null) { + return 0; + } + return getDistanceFrom(previousBusOrStop) * bus.getMileageCost(); + } + + public int getDistanceFrom(BusOrStop busOrStop) { + return bus.getDistanceFromTo(busOrStop.getLocation(), location); + } + @Override public String toString() { return name; diff --git a/optaplanner-examples/src/main/java/org/optaplanner/examples/coachshuttlegathering/domain/BusVisit.java b/optaplanner-examples/src/main/java/org/optaplanner/examples/coachshuttlegathering/domain/BusVisit.java deleted file mode 100644 index 829b62549f..0000000000 --- a/optaplanner-examples/src/main/java/org/optaplanner/examples/coachshuttlegathering/domain/BusVisit.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright 2015 JBoss Inc - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.optaplanner.examples.coachshuttlegathering.domain; - -import com.thoughtworks.xstream.annotations.XStreamAlias; -import org.optaplanner.core.api.domain.entity.PlanningEntity; -import org.optaplanner.core.api.domain.variable.AnchorShadowVariable; -import org.optaplanner.core.api.domain.variable.PlanningVariable; -import org.optaplanner.core.api.domain.variable.PlanningVariableGraphType; -import org.optaplanner.examples.coachshuttlegathering.domain.location.RoadLocation; -import org.optaplanner.examples.coachshuttlegathering.domain.solver.DepotAngleBusVisitDifficultyWeightFactory; -import org.optaplanner.examples.common.domain.AbstractPersistable; - -@PlanningEntity(difficultyWeightFactoryClass = DepotAngleBusVisitDifficultyWeightFactory.class) -@XStreamAlias("CsgBusVisit") -public class BusVisit extends AbstractPersistable implements BusStandstill { - - protected BusStop busStop; - - // Planning variables: changes during planning, between score calculations. - protected BusStandstill previousStandstill; - - // Shadow variables - protected BusVisit nextVisit; - protected BusStartPoint startPoint; - - public BusStop getBusStop() { - return busStop; - } - - public void setBusStop(BusStop busStop) { - this.busStop = busStop; - } - - @PlanningVariable(valueRangeProviderRefs = {"startPointRange", "visitRange"}, - graphType = PlanningVariableGraphType.CHAINED) - public BusStandstill getPreviousStandstill() { - return previousStandstill; - } - - public void setPreviousStandstill(BusStandstill previousStandstill) { - this.previousStandstill = previousStandstill; - } - - public BusVisit getNextVisit() { - return nextVisit; - } - - public void setNextVisit(BusVisit nextVisit) { - this.nextVisit = nextVisit; - } - - @AnchorShadowVariable(sourceVariableName = "previousStandstill") - public BusStartPoint getStartPoint() { - return startPoint; - } - - public void setStartPoint(BusStartPoint startPoint) { - this.startPoint = startPoint; - } - - // ************************************************************************ - // Complex methods - // ************************************************************************ - - public RoadLocation getLocation() { - return busStop.getLocation(); - } - - public int getDistanceFromPreviousStandstillCost() { - if (previousStandstill == null) { - return 0; - } - return getDistanceFrom(previousStandstill) * startPoint.getBus().getMileageCost(); - } - - public int getDistanceFrom(BusStandstill standstill) { - RoadLocation sourceLocation = standstill.getLocation(); - RoadLocation targetLocation = getLocation(); - return startPoint.isCoach() ? sourceLocation.getCoachDistanceTo(targetLocation) - : sourceLocation.getShuttleDistanceTo(targetLocation); - } - - @Override - public String toString() { - return busStop.toString(); - } - -} diff --git a/optaplanner-examples/src/main/java/org/optaplanner/examples/coachshuttlegathering/domain/Coach.java b/optaplanner-examples/src/main/java/org/optaplanner/examples/coachshuttlegathering/domain/Coach.java index bf82cf8e88..20cf3701b2 100644 --- a/optaplanner-examples/src/main/java/org/optaplanner/examples/coachshuttlegathering/domain/Coach.java +++ b/optaplanner-examples/src/main/java/org/optaplanner/examples/coachshuttlegathering/domain/Coach.java @@ -17,6 +17,7 @@ package org.optaplanner.examples.coachshuttlegathering.domain; import com.thoughtworks.xstream.annotations.XStreamAlias; +import org.optaplanner.examples.coachshuttlegathering.domain.location.RoadLocation; import org.optaplanner.examples.common.domain.AbstractPersistable; @XStreamAlias("CsgCoach") @@ -36,4 +37,14 @@ public void setStopLimit(int stopLimit) { // Complex methods // ************************************************************************ + @Override + public int getSetupCost() { + return 0; + } + + @Override + public int getDistanceFromTo(RoadLocation sourceLocation, RoadLocation targetLocation) { + return sourceLocation.getCoachDistanceTo(targetLocation); + } + } diff --git a/optaplanner-examples/src/main/java/org/optaplanner/examples/coachshuttlegathering/domain/CoachShuttleGatheringSolution.java b/optaplanner-examples/src/main/java/org/optaplanner/examples/coachshuttlegathering/domain/CoachShuttleGatheringSolution.java index 1355a09efd..b1075eee66 100644 --- a/optaplanner-examples/src/main/java/org/optaplanner/examples/coachshuttlegathering/domain/CoachShuttleGatheringSolution.java +++ b/optaplanner-examples/src/main/java/org/optaplanner/examples/coachshuttlegathering/domain/CoachShuttleGatheringSolution.java @@ -40,11 +40,8 @@ public class CoachShuttleGatheringSolution extends AbstractPersistable implement protected List locationList; protected List coachList; protected List shuttleList; + protected List stopList; protected BusHub hub; - protected List busStopList; - - protected List startPointList; - protected List visitList; @XStreamConverter(value = XStreamScoreConverter.class, types = {HardSoftScoreDefinition.class}) protected HardSoftScore score; @@ -65,6 +62,8 @@ public void setLocationList(List locationList) { this.locationList = locationList; } + @PlanningEntityCollectionProperty + @ValueRangeProvider(id = "coachRange") public List getCoachList() { return coachList; } @@ -73,6 +72,8 @@ public void setCoachList(List coachList) { this.coachList = coachList; } + @PlanningEntityCollectionProperty + @ValueRangeProvider(id = "shuttleRange") public List getShuttleList() { return shuttleList; } @@ -81,40 +82,22 @@ public void setShuttleList(List shuttleList) { this.shuttleList = shuttleList; } - public BusHub getHub() { - return hub; - } - - public void setHub(BusHub hub) { - this.hub = hub; - } - - public List getBusStopList() { - return busStopList; - } - - public void setBusStopList(List busStopList) { - this.busStopList = busStopList; - } - @PlanningEntityCollectionProperty - @ValueRangeProvider(id = "startPointRange") - public List getStartPointList() { - return startPointList; + @ValueRangeProvider(id = "stopRange") + public List getStopList() { + return stopList; } - public void setStartPointList(List startPointList) { - this.startPointList = startPointList; + public void setStopList(List stopList) { + this.stopList = stopList; } - @PlanningEntityCollectionProperty - @ValueRangeProvider(id = "visitRange") - public List getVisitList() { - return visitList; + public BusHub getHub() { + return hub; } - public void setVisitList(List visitList) { - this.visitList = visitList; + public void setHub(BusHub hub) { + this.hub = hub; } public HardSoftScore getScore() { @@ -132,12 +115,16 @@ public void setScore(HardSoftScore score) { public Collection getProblemFacts() { List facts = new ArrayList(); facts.addAll(locationList); - facts.addAll(coachList); - facts.addAll(shuttleList); facts.add(hub); - facts.addAll(busStopList); - // Do not add the planning entities (startPointList, visitList) because that will be done automatically + // Do not add the planning entities (coachList, shuttleList, busStopList) because that will be done automatically return facts; } + public List getBusList() { + List busList = new ArrayList(coachList.size() + shuttleList.size()); + busList.addAll(coachList); + busList.addAll(shuttleList); + return busList; + } + } diff --git a/optaplanner-examples/src/main/java/org/optaplanner/examples/coachshuttlegathering/domain/Shuttle.java b/optaplanner-examples/src/main/java/org/optaplanner/examples/coachshuttlegathering/domain/Shuttle.java index 415936110a..80887e2b38 100644 --- a/optaplanner-examples/src/main/java/org/optaplanner/examples/coachshuttlegathering/domain/Shuttle.java +++ b/optaplanner-examples/src/main/java/org/optaplanner/examples/coachshuttlegathering/domain/Shuttle.java @@ -17,6 +17,7 @@ package org.optaplanner.examples.coachshuttlegathering.domain; import com.thoughtworks.xstream.annotations.XStreamAlias; +import org.optaplanner.examples.coachshuttlegathering.domain.location.RoadLocation; import org.optaplanner.examples.common.domain.AbstractPersistable; @XStreamAlias("CsgShuttle") @@ -24,6 +25,7 @@ public class Shuttle extends Bus { protected int setupCost; + @Override public int getSetupCost() { return setupCost; } @@ -36,4 +38,9 @@ public void setSetupCost(int setupCost) { // Complex methods // ************************************************************************ + @Override + public int getDistanceFromTo(RoadLocation sourceLocation, RoadLocation targetLocation) { + return sourceLocation.getShuttleDistanceTo(targetLocation); + } + } diff --git a/optaplanner-examples/src/main/java/org/optaplanner/examples/coachshuttlegathering/domain/StopOrHub.java b/optaplanner-examples/src/main/java/org/optaplanner/examples/coachshuttlegathering/domain/StopOrHub.java new file mode 100644 index 0000000000..8ca5d1c7cc --- /dev/null +++ b/optaplanner-examples/src/main/java/org/optaplanner/examples/coachshuttlegathering/domain/StopOrHub.java @@ -0,0 +1,30 @@ +/* + * Copyright 2015 JBoss Inc + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.optaplanner.examples.coachshuttlegathering.domain; + +import org.optaplanner.core.api.domain.entity.PlanningEntity; +import org.optaplanner.core.api.domain.variable.InverseRelationShadowVariable; +import org.optaplanner.examples.coachshuttlegathering.domain.location.RoadLocation; + +public interface StopOrHub { + + /** + * @return never null + */ + RoadLocation getLocation(); + +} diff --git a/optaplanner-examples/src/main/java/org/optaplanner/examples/coachshuttlegathering/domain/solver/DepotAngleBusVisitDifficultyWeightFactory.java b/optaplanner-examples/src/main/java/org/optaplanner/examples/coachshuttlegathering/domain/solver/DepotAngleBusStopDifficultyWeightFactory.java similarity index 77% rename from optaplanner-examples/src/main/java/org/optaplanner/examples/coachshuttlegathering/domain/solver/DepotAngleBusVisitDifficultyWeightFactory.java rename to optaplanner-examples/src/main/java/org/optaplanner/examples/coachshuttlegathering/domain/solver/DepotAngleBusStopDifficultyWeightFactory.java index b934dba528..911c9cb3f7 100644 --- a/optaplanner-examples/src/main/java/org/optaplanner/examples/coachshuttlegathering/domain/solver/DepotAngleBusVisitDifficultyWeightFactory.java +++ b/optaplanner-examples/src/main/java/org/optaplanner/examples/coachshuttlegathering/domain/solver/DepotAngleBusStopDifficultyWeightFactory.java @@ -19,33 +19,32 @@ import org.apache.commons.lang.builder.CompareToBuilder; import org.optaplanner.core.impl.heuristic.selector.common.decorator.SelectionSorterWeightFactory; import org.optaplanner.examples.coachshuttlegathering.domain.BusHub; -import org.optaplanner.examples.coachshuttlegathering.domain.BusVisit; +import org.optaplanner.examples.coachshuttlegathering.domain.BusStop; import org.optaplanner.examples.coachshuttlegathering.domain.CoachShuttleGatheringSolution; /** * On large datasets, the constructed solution looks like pizza slices. */ -public class DepotAngleBusVisitDifficultyWeightFactory - implements SelectionSorterWeightFactory { +public class DepotAngleBusStopDifficultyWeightFactory + implements SelectionSorterWeightFactory { - public Comparable createSorterWeight(CoachShuttleGatheringSolution solution, BusVisit visit) { + public Comparable createSorterWeight(CoachShuttleGatheringSolution solution, BusStop stop) { BusHub hub = solution.getHub(); - return new DepotAngleCustomerDifficultyWeight(visit, - visit.getLocation().getAngle(hub.getLocation()), - visit.getLocation().getMaximumDistanceTo(hub.getLocation()) - + hub.getLocation().getMaximumDistanceTo(visit.getLocation())); + return new DepotAngleCustomerDifficultyWeight(stop, + stop.getLocation().getAngle(hub.getLocation()), + stop.getLocation().getMaximumDistanceTo(hub.getLocation()) + + hub.getLocation().getMaximumDistanceTo(stop.getLocation())); } public static class DepotAngleCustomerDifficultyWeight implements Comparable { - private final BusVisit visit; + private final BusStop stop; private final double hubAngle; private final int hubRoundTripDistance; - public DepotAngleCustomerDifficultyWeight(BusVisit visit, - double hubAngle, int hubRoundTripDistance) { - this.visit = visit; + public DepotAngleCustomerDifficultyWeight(BusStop stop, double hubAngle, int hubRoundTripDistance) { + this.stop = stop; this.hubAngle = hubAngle; this.hubRoundTripDistance = hubRoundTripDistance; } @@ -54,7 +53,7 @@ public int compareTo(DepotAngleCustomerDifficultyWeight other) { return new CompareToBuilder() .append(hubAngle, other.hubAngle) .append(hubRoundTripDistance, other.hubRoundTripDistance) // Ascending (further from the depot are more difficult) - .append(visit.getId(), other.visit.getId()) + .append(stop.getId(), other.stop.getId()) .toComparison(); } diff --git a/optaplanner-examples/src/main/java/org/optaplanner/examples/coachshuttlegathering/persistence/CoachShuttleGatheringImporter.java b/optaplanner-examples/src/main/java/org/optaplanner/examples/coachshuttlegathering/persistence/CoachShuttleGatheringImporter.java index e7a9283f88..7cca5dd4fb 100644 --- a/optaplanner-examples/src/main/java/org/optaplanner/examples/coachshuttlegathering/persistence/CoachShuttleGatheringImporter.java +++ b/optaplanner-examples/src/main/java/org/optaplanner/examples/coachshuttlegathering/persistence/CoachShuttleGatheringImporter.java @@ -34,9 +34,7 @@ import org.optaplanner.core.api.domain.solution.Solution; import org.optaplanner.examples.coachshuttlegathering.domain.Bus; import org.optaplanner.examples.coachshuttlegathering.domain.BusHub; -import org.optaplanner.examples.coachshuttlegathering.domain.BusStartPoint; import org.optaplanner.examples.coachshuttlegathering.domain.BusStop; -import org.optaplanner.examples.coachshuttlegathering.domain.BusVisit; import org.optaplanner.examples.coachshuttlegathering.domain.Coach; import org.optaplanner.examples.coachshuttlegathering.domain.CoachShuttleGatheringSolution; import org.optaplanner.examples.coachshuttlegathering.domain.Shuttle; @@ -87,17 +85,18 @@ public static class CoachShuttleGatheringInputBuilder extends TxtInputBuilder { private CoachShuttleGatheringSolution solution; private Map, RoadLocation> latLongToLocationMap; + private long busOrStopOrHubId; public Solution readSolution() throws IOException { solution = new CoachShuttleGatheringSolution(); solution.setId(0L); readLocationList(); + busOrStopOrHubId = 0L; readBusList(); readBusStopList(); - createStartPointListAndVisitList(); int busListSize = solution.getCoachList().size() + solution.getShuttleList().size(); - int base = solution.getBusStopList().size() + solution.getShuttleList().size(); + int base = solution.getStopList().size() + solution.getShuttleList().size(); BigInteger possibleSolutionSize = factorial(base + busListSize - 1).divide(factorial(busListSize - 1)); logger.info("CoachShuttleGathering {} has {} road locations, {} coaches, {} shuttles and {} bus stops" + " with a search space of {}.", @@ -105,7 +104,7 @@ public Solution readSolution() throws IOException { solution.getLocationList().size(), solution.getCoachList().size(), solution.getShuttleList().size(), - solution.getBusStopList().size(), + solution.getStopList().size(), getFlooredPossibleSolutionSize(possibleSolutionSize)); return solution; } @@ -218,7 +217,6 @@ private void readBusList() throws IOException { File file = new File(inputFile.getParentFile(), "Fleet.csv"); List coachList = new ArrayList(); List shuttleList = new ArrayList(); - long busId = 0L; BufferedReader subBufferedReader = null; try { subBufferedReader = new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF-8")); @@ -241,8 +239,8 @@ private void readBusList() throws IOException { throw new IllegalArgumentException("The fleet vehicle with name (" + name + ") has an unsupported type (" + busType + ")."); } - bus.setId(busId); - busId++; + bus.setId(busOrStopOrHubId); + busOrStopOrHubId++; bus.setName(name); bus.setCapacity(Integer.parseInt(lineTokens[2])); int stopLimit = Integer.parseInt(lineTokens[3]); @@ -285,7 +283,6 @@ private void readBusList() throws IOException { private void readBusStopList() throws IOException { List busStopList = new ArrayList(); - long busStopId = 0L; bufferedReader.readLine(); // Ignore first line (comment) for (String line = bufferedReader.readLine(); line != null; line = bufferedReader.readLine()) { if (line.isEmpty()) { @@ -300,8 +297,8 @@ private void readBusStopList() throws IOException { + ") is not the only hub (" + solution.getHub().getName() + ")."); } BusHub hub = new BusHub(); - hub.setId(busStopId); - busStopId++; + hub.setId(busOrStopOrHubId); + busOrStopOrHubId++; hub.setName(name); // Ignore lineTokens[2] and lineTokens[3] double latitude = Double.parseDouble(lineTokens[4]); @@ -326,8 +323,8 @@ private void readBusStopList() throws IOException { solution.setHub(hub); } else if (busStopType.equalsIgnoreCase("BUSSTOP")) { BusStop busStop = new BusStop(); - busStop.setId(busStopId); - busStopId++; + busStop.setId(busOrStopOrHubId); + busOrStopOrHubId++; busStop.setName(name); // Ignore lineTokens[2] and lineTokens[3] double latitude = Double.parseDouble(lineTokens[4]); @@ -347,39 +344,7 @@ private void readBusStopList() throws IOException { + ") has an unsupported type (" + busStopType + ")."); } } - solution.setBusStopList(busStopList); - } - - private void createStartPointListAndVisitList() { - List coachList = solution.getCoachList(); - List shuttleList = solution.getShuttleList(); - List startPointList = new ArrayList(coachList.size() + shuttleList.size()); - long entityId = 0L; - for (Coach coach : coachList) { - BusStartPoint startPoint = new BusStartPoint(); - startPoint.setId(entityId); - entityId++; - startPoint.setBus(coach); - startPointList.add(startPoint); - } - for (Shuttle shuttle : shuttleList) { - BusStartPoint startPoint = new BusStartPoint(); - startPoint.setId(entityId); - entityId++; - startPoint.setBus(shuttle); - startPointList.add(startPoint); - } - solution.setStartPointList(startPointList); - List busStopList = solution.getBusStopList(); - List visitList = new ArrayList(busStopList.size()); - for (BusStop busStop : busStopList) { - BusVisit visit = new BusVisit(); - visit.setId(entityId); - entityId++; - visit.setBusStop(busStop); - visitList.add(visit); - } - solution.setVisitList(visitList); + solution.setStopList(busStopList); } } diff --git a/optaplanner-examples/src/main/java/org/optaplanner/examples/coachshuttlegathering/swingui/CoachShuttleGatheringWorldPanel.java b/optaplanner-examples/src/main/java/org/optaplanner/examples/coachshuttlegathering/swingui/CoachShuttleGatheringWorldPanel.java index febd7a7e58..f22f76d8da 100644 --- a/optaplanner-examples/src/main/java/org/optaplanner/examples/coachshuttlegathering/swingui/CoachShuttleGatheringWorldPanel.java +++ b/optaplanner-examples/src/main/java/org/optaplanner/examples/coachshuttlegathering/swingui/CoachShuttleGatheringWorldPanel.java @@ -18,31 +18,21 @@ import java.awt.Color; import java.awt.Dimension; -import java.awt.Font; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.event.ComponentAdapter; import java.awt.event.ComponentEvent; -import java.awt.event.MouseAdapter; -import java.awt.event.MouseEvent; import java.awt.image.BufferedImage; +import java.util.List; import javax.swing.JPanel; -import org.optaplanner.core.api.score.buildin.hardsoft.HardSoftScore; -import org.optaplanner.core.api.score.buildin.simplelong.SimpleLongScore; +import org.optaplanner.examples.coachshuttlegathering.domain.Bus; import org.optaplanner.examples.coachshuttlegathering.domain.BusHub; -import org.optaplanner.examples.coachshuttlegathering.domain.BusStartPoint; -import org.optaplanner.examples.coachshuttlegathering.domain.BusVisit; +import org.optaplanner.examples.coachshuttlegathering.domain.BusStop; import org.optaplanner.examples.coachshuttlegathering.domain.CoachShuttleGatheringSolution; import org.optaplanner.examples.coachshuttlegathering.domain.location.RoadLocation; import org.optaplanner.examples.common.swingui.TangoColorFactory; import org.optaplanner.examples.common.swingui.latitudelongitude.LatitudeLongitudeTranslator; -import org.optaplanner.examples.tsp.domain.Domicile; -import org.optaplanner.examples.tsp.domain.location.AirLocation; -import org.optaplanner.examples.tsp.domain.location.Location; -import org.optaplanner.examples.vehiclerouting.domain.VehicleRoutingSolution; -import org.optaplanner.examples.vehiclerouting.swingui.VehicleRoutingPanel; -import org.optaplanner.examples.vehiclerouting.swingui.VehicleRoutingSolutionPainter; public class CoachShuttleGatheringWorldPanel extends JPanel { @@ -78,30 +68,25 @@ public void resetPanel(CoachShuttleGatheringSolution solution) { Graphics2D g = createCanvas(width, height); g.setColor(TangoColorFactory.ALUMINIUM_6); - BusHub hub = solution.getHub(); - int hubX = translator.translateLongitudeToX(hub.getLocation().getLongitude()); - int hubY = translator.translateLatitudeToY(hub.getLocation().getLatitude()); - g.fillRect(hubX - 2, hubY - 2, 5, 5); - for (BusVisit visit : solution.getVisitList()) { - RoadLocation location = visit.getLocation(); - int x = translator.translateLongitudeToX(location.getLongitude()); - int y = translator.translateLatitudeToY(location.getLatitude()); - g.setColor(TangoColorFactory.ALUMINIUM_4); - g.fillRect(x - 1, y - 1, 3, 3); + RoadLocation hubLocation = solution.getHub().getLocation(); + translator.drawSquare(g, hubLocation.getLongitude(), hubLocation.getLatitude(), 5); + g.setColor(TangoColorFactory.ALUMINIUM_4); + for (BusStop stop : solution.getStopList()) { + RoadLocation location = stop.getLocation(); + translator.drawSquare(g, location.getLongitude(), location.getLatitude(), 3); } - for (BusStartPoint startPoint : solution.getStartPointList()) { - RoadLocation location = startPoint.getLocation(); - int x = translator.translateLongitudeToX(location.getLongitude()); - int y = translator.translateLatitudeToY(location.getLatitude()); - g.setColor(TangoColorFactory.ALUMINIUM_2); - g.fillRect(x - 1, y - 1, 3, 3); + List busList = solution.getBusList(); + g.setColor(TangoColorFactory.ALUMINIUM_2); + for (Bus bus : busList) { + RoadLocation location = bus.getLocation(); + translator.drawSquare(g, location.getLongitude(), location.getLatitude(), 3); } int colorIndex = 0; - for (BusStartPoint startPoint : solution.getStartPointList()) { + for (Bus bus : busList) { g.setColor(TangoColorFactory.SEQUENCE_2[colorIndex]); - for (BusVisit visit = startPoint.getNextVisit(); visit != null; visit = visit.getNextVisit()) { - RoadLocation previousLocation = visit.getPreviousStandstill().getLocation(); - RoadLocation location = visit.getLocation(); + for (BusStop stop = bus.getNextStop(); stop != null; stop = stop.getNextStop()) { + RoadLocation previousLocation = stop.getPreviousBusOrStop().getLocation(); + RoadLocation location = stop.getLocation(); translator.drawRoute(g, previousLocation.getLongitude(), previousLocation.getLatitude(), location.getLongitude(), location.getLatitude(), false, false); diff --git a/optaplanner-examples/src/main/java/org/optaplanner/examples/common/swingui/latitudelongitude/LatitudeLongitudeTranslator.java b/optaplanner-examples/src/main/java/org/optaplanner/examples/common/swingui/latitudelongitude/LatitudeLongitudeTranslator.java index 9a58873ada..da870093a0 100644 --- a/optaplanner-examples/src/main/java/org/optaplanner/examples/common/swingui/latitudelongitude/LatitudeLongitudeTranslator.java +++ b/optaplanner-examples/src/main/java/org/optaplanner/examples/common/swingui/latitudelongitude/LatitudeLongitudeTranslator.java @@ -95,6 +95,12 @@ public int getImageHeight() { return imageHeight; } + public void drawSquare(Graphics2D g, double lon, double lat, int diameter) { + int x = translateLongitudeToX(lon); + int y = translateLatitudeToY(lat); + g.fillRect(x - (diameter / 2), y - (diameter / 2), diameter, diameter); + } + public void drawRoute(Graphics2D g, double lon1, double lat1, double lon2, double lat2, boolean straight, boolean dashed) { int x1 = translateLongitudeToX(lon1); int y1 = translateLatitudeToY(lat1); diff --git a/optaplanner-examples/src/main/resources/org/optaplanner/examples/coachshuttlegathering/solver/coachShuttleGatheringScoreRules.drl b/optaplanner-examples/src/main/resources/org/optaplanner/examples/coachshuttlegathering/solver/coachShuttleGatheringScoreRules.drl index 8b732eab0b..56b4cf2ba6 100644 --- a/optaplanner-examples/src/main/resources/org/optaplanner/examples/coachshuttlegathering/solver/coachShuttleGatheringScoreRules.drl +++ b/optaplanner-examples/src/main/resources/org/optaplanner/examples/coachshuttlegathering/solver/coachShuttleGatheringScoreRules.drl @@ -21,13 +21,12 @@ import org.optaplanner.core.api.score.buildin.hardsoft.HardSoftScoreHolder; import org.optaplanner.examples.coachshuttlegathering.domain.Bus; import org.optaplanner.examples.coachshuttlegathering.domain.BusHub; -import org.optaplanner.examples.coachshuttlegathering.domain.BusStartPoint; import org.optaplanner.examples.coachshuttlegathering.domain.BusStop; -import org.optaplanner.examples.coachshuttlegathering.domain.BusVisit; import org.optaplanner.examples.coachshuttlegathering.domain.Coach; import org.optaplanner.examples.coachshuttlegathering.domain.CoachShuttleGatheringSolution; import org.optaplanner.examples.coachshuttlegathering.domain.Shuttle; import org.optaplanner.examples.coachshuttlegathering.domain.location.RoadLocation; +import org.optaplanner.examples.coachshuttlegathering.domain.location.RoadLocationArc; global HardSoftScoreHolder scoreHolder; @@ -54,14 +53,14 @@ global HardSoftScoreHolder scoreHolder; rule "shuttleSetupCost" when - BusStartPoint(nextVisit != null, $cost : setupCost) + Bus(nextStop != null, $cost : setupCost) then scoreHolder.addSoftConstraintMatch(kcontext, - $cost); end -rule "distanceToPreviousStandstill" +rule "distanceToPrevious" when - BusVisit(previousStandstill != null, $cost : distanceFromPreviousStandstillCost) + BusStop(previousBusOrStop != null, $cost : distanceFromPreviousCost) then scoreHolder.addSoftConstraintMatch(kcontext, - $cost); end diff --git a/optaplanner-examples/src/main/resources/org/optaplanner/examples/coachshuttlegathering/solver/coachShuttleGatheringSolverConfig.xml b/optaplanner-examples/src/main/resources/org/optaplanner/examples/coachshuttlegathering/solver/coachShuttleGatheringSolverConfig.xml index ed069e804c..a0f52c4149 100644 --- a/optaplanner-examples/src/main/resources/org/optaplanner/examples/coachshuttlegathering/solver/coachShuttleGatheringSolverConfig.xml +++ b/optaplanner-examples/src/main/resources/org/optaplanner/examples/coachshuttlegathering/solver/coachShuttleGatheringSolverConfig.xml @@ -2,8 +2,8 @@ org.optaplanner.examples.coachshuttlegathering.domain.CoachShuttleGatheringSolution - org.optaplanner.examples.coachshuttlegathering.domain.BusStandstill - org.optaplanner.examples.coachshuttlegathering.domain.BusVisit + org.optaplanner.examples.coachshuttlegathering.domain.BusOrStop + org.optaplanner.examples.coachshuttlegathering.domain.BusStop HARD_SOFT