From 2d2fc341a6c86b8cf249546bb6045af3a66a42d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20H=C3=B6rl?= Date: Mon, 12 Feb 2024 13:18:52 +0100 Subject: [PATCH] feat: allow custom rejection penalties through an interface (#36) --- .../alonso_mora/AlonsoMoraModeQSimModule.java | 14 ++++++---- .../assignment/AssignmentSolver.java | 20 ++++++++++++++ .../assignment/CbcMpsAssignmentSolver.java | 10 +++---- .../assignment/GlpkMpsAssignmentSolver.java | 12 ++++----- .../assignment/MpsAssignmentWriter.java | 9 +++---- .../CbcMpsAssignmentSolverTest.java | 14 +++++++--- .../GlpkMpsAssignmentSolverTest.java | 26 ++++++++++--------- .../gurobi/CplexAssignmentSolver.java | 10 +++---- .../alonso_mora/gurobi/CplexModule.java | 5 ++-- .../gurobi/CplexAssignmentSolverTest.java | 14 +++++++--- .../glpk/GlpkJniAssignmentSolver.java | 9 +++---- .../matsim/alonso_mora/glpk/GlpkModule.java | 5 ++-- .../glpk/GlpkJniAssignmentSolverTest.java | 14 +++++++--- .../gurobi/GurobiAssignmentSolver.java | 10 +++---- .../alonso_mora/gurobi/GurobiModule.java | 3 ++- .../gurobi/GurobiAssignmentSolverTest.java | 14 +++++++--- 16 files changed, 115 insertions(+), 74 deletions(-) diff --git a/core/src/main/java/org/matsim/alonso_mora/AlonsoMoraModeQSimModule.java b/core/src/main/java/org/matsim/alonso_mora/AlonsoMoraModeQSimModule.java index e7054c5..5055a55 100644 --- a/core/src/main/java/org/matsim/alonso_mora/AlonsoMoraModeQSimModule.java +++ b/core/src/main/java/org/matsim/alonso_mora/AlonsoMoraModeQSimModule.java @@ -20,6 +20,8 @@ import org.matsim.alonso_mora.algorithm.DefaultAlonsoMoraRequestFactory; import org.matsim.alonso_mora.algorithm.DefaultAlonsoMoraVehicle; import org.matsim.alonso_mora.algorithm.assignment.AssignmentSolver; +import org.matsim.alonso_mora.algorithm.assignment.AssignmentSolver.DefaultRejectionPenalty; +import org.matsim.alonso_mora.algorithm.assignment.AssignmentSolver.RejectionPenalty; import org.matsim.alonso_mora.algorithm.assignment.CbcMpsAssignmentSolver; import org.matsim.alonso_mora.algorithm.assignment.GlpkMpsAssignmentSolver; import org.matsim.alonso_mora.algorithm.assignment.GreedyTripFirstSolver; @@ -122,6 +124,9 @@ protected void configureQSim() { return new GreedyVehicleFirstSolver(); })).in(Singleton.class); + bindModal(RejectionPenalty.class) + .toInstance(new DefaultRejectionPenalty(amConfig.unassignmentPenalty, amConfig.rejectionPenalty)); + bindModal(CbcMpsAssignmentSolver.class).toProvider(modalProvider(getter -> { if (!CbcMpsAssignmentSolver.checkAvailability()) { throw new IllegalStateException("Cbc solver is not available on this system!"); @@ -133,9 +138,8 @@ protected void configureQSim() { CbcMpsAssignmentParameters solverParameters = (CbcMpsAssignmentParameters) amConfig.assignmentSolver; - return new CbcMpsAssignmentSolver(amConfig.unassignmentPenalty, amConfig.rejectionPenalty, - solverParameters.timeLimit, solverParameters.optimalityGap, problemPath, solutionPath, - getConfig().global().getRandomSeed()); + return new CbcMpsAssignmentSolver(getter.getModal(RejectionPenalty.class), solverParameters.timeLimit, + solverParameters.optimalityGap, problemPath, solutionPath, getConfig().global().getRandomSeed()); })).in(Singleton.class); bindModal(GlpkMpsAssignmentSolver.class).toProvider(modalProvider(getter -> { @@ -149,8 +153,8 @@ protected void configureQSim() { GlpkMpsAssignmentParameters solverParameters = (GlpkMpsAssignmentParameters) amConfig.assignmentSolver; - return new GlpkMpsAssignmentSolver(amConfig.unassignmentPenalty, amConfig.rejectionPenalty, - solverParameters.timeLimit, solverParameters.optimalityGap, problemPath, solutionPath); + return new GlpkMpsAssignmentSolver(getter.getModal(RejectionPenalty.class), solverParameters.timeLimit, + solverParameters.optimalityGap, problemPath, solutionPath); })).in(Singleton.class); switch (amConfig.assignmentSolver.getSolverType()) { diff --git a/core/src/main/java/org/matsim/alonso_mora/algorithm/assignment/AssignmentSolver.java b/core/src/main/java/org/matsim/alonso_mora/algorithm/assignment/AssignmentSolver.java index 0fc0750..67f06e5 100644 --- a/core/src/main/java/org/matsim/alonso_mora/algorithm/assignment/AssignmentSolver.java +++ b/core/src/main/java/org/matsim/alonso_mora/algorithm/assignment/AssignmentSolver.java @@ -3,6 +3,7 @@ import java.util.Collection; import java.util.stream.Stream; +import org.matsim.alonso_mora.algorithm.AlonsoMoraRequest; import org.matsim.alonso_mora.algorithm.AlonsoMoraTrip; /** @@ -26,4 +27,23 @@ public Solution(Status status, Collection trips) { this.trips = trips; } } + + static public interface RejectionPenalty { + double getPenalty(AlonsoMoraRequest request); + } + + static public class DefaultRejectionPenalty implements RejectionPenalty { + private final double unassignmentPenalty; + private final double rejectionPenalty; + + public DefaultRejectionPenalty(double unassignmentPenalty, double rejectionPenalty) { + this.unassignmentPenalty = unassignmentPenalty; + this.rejectionPenalty = rejectionPenalty; + } + + @Override + public double getPenalty(AlonsoMoraRequest request) { + return request.isAssigned() ? unassignmentPenalty : rejectionPenalty; + } + } } diff --git a/core/src/main/java/org/matsim/alonso_mora/algorithm/assignment/CbcMpsAssignmentSolver.java b/core/src/main/java/org/matsim/alonso_mora/algorithm/assignment/CbcMpsAssignmentSolver.java index 5498e60..b0ce4c3 100644 --- a/core/src/main/java/org/matsim/alonso_mora/algorithm/assignment/CbcMpsAssignmentSolver.java +++ b/core/src/main/java/org/matsim/alonso_mora/algorithm/assignment/CbcMpsAssignmentSolver.java @@ -30,8 +30,7 @@ public class CbcMpsAssignmentSolver implements AssignmentSolver { private final static Logger logger = LogManager.getLogger(CbcMpsAssignmentSolver.class); - private final double rejectionPenalty; - private final double unassignmentPenalty; + private final RejectionPenalty rejectionPenalty; private final File problemPath; private final File solutionPath; @@ -40,9 +39,8 @@ public class CbcMpsAssignmentSolver implements AssignmentSolver { private final double optimalityGap; private final long randomSeed; - public CbcMpsAssignmentSolver(double unassignmentPenalty, double rejectionPenalty, double timeLimit, - double optimalityGap, File problemPath, File solutionPath, long randomSeed) { - this.unassignmentPenalty = unassignmentPenalty; + public CbcMpsAssignmentSolver(RejectionPenalty rejectionPenalty, double timeLimit, double optimalityGap, + File problemPath, File solutionPath, long randomSeed) { this.rejectionPenalty = rejectionPenalty; this.problemPath = problemPath; @@ -58,7 +56,7 @@ public CbcMpsAssignmentSolver(double unassignmentPenalty, double rejectionPenalt public Solution solve(Stream candidates) { try { List tripList = candidates.collect(Collectors.toList()); - new MpsAssignmentWriter(tripList, unassignmentPenalty, rejectionPenalty).write(problemPath); + new MpsAssignmentWriter(tripList, rejectionPenalty).write(problemPath); new ProcessBuilder("cbc", problemPath.toString(), "-randomSeed", String.valueOf(randomSeed), "-randomCbcSeed", String.valueOf(randomSeed), "-ratio", String.valueOf(optimalityGap), "-seconds", diff --git a/core/src/main/java/org/matsim/alonso_mora/algorithm/assignment/GlpkMpsAssignmentSolver.java b/core/src/main/java/org/matsim/alonso_mora/algorithm/assignment/GlpkMpsAssignmentSolver.java index c33c47e..017bf41 100644 --- a/core/src/main/java/org/matsim/alonso_mora/algorithm/assignment/GlpkMpsAssignmentSolver.java +++ b/core/src/main/java/org/matsim/alonso_mora/algorithm/assignment/GlpkMpsAssignmentSolver.java @@ -30,8 +30,7 @@ public class GlpkMpsAssignmentSolver implements AssignmentSolver { private static final Logger logger = LogManager.getLogger(GlpkMpsAssignmentSolver.class); - private final double unassignmentPenalty; - private final double rejectionPenalty; + private final RejectionPenalty rejectionPenalty; private final File problemPath; private final File solutionPath; @@ -39,9 +38,8 @@ public class GlpkMpsAssignmentSolver implements AssignmentSolver { private final double timeLimit; private final double optimalityGap; - public GlpkMpsAssignmentSolver(double unassignmentPenalty, double rejectionPenalty, double timeLimit, - double optimalityGap, File problemPath, File solutionPath) { - this.unassignmentPenalty = unassignmentPenalty; + public GlpkMpsAssignmentSolver(RejectionPenalty rejectionPenalty, double timeLimit, double optimalityGap, + File problemPath, File solutionPath) { this.rejectionPenalty = rejectionPenalty; this.problemPath = problemPath; @@ -55,11 +53,11 @@ public GlpkMpsAssignmentSolver(double unassignmentPenalty, double rejectionPenal public Solution solve(Stream candidates) { try { List tripList = candidates.collect(Collectors.toList()); - new MpsAssignmentWriter(tripList, unassignmentPenalty, rejectionPenalty).write(problemPath); + new MpsAssignmentWriter(tripList, rejectionPenalty).write(problemPath); new ProcessBuilder("glpsol", "--mipgap", String.valueOf(optimalityGap), "--tmlim", String.valueOf((int) (timeLimit * 1e3)), "-w", solutionPath.toString(), problemPath.toString()) - .start().waitFor(); + .start().waitFor(); BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(solutionPath))); diff --git a/core/src/main/java/org/matsim/alonso_mora/algorithm/assignment/MpsAssignmentWriter.java b/core/src/main/java/org/matsim/alonso_mora/algorithm/assignment/MpsAssignmentWriter.java index e56cceb..8ffdfaa 100644 --- a/core/src/main/java/org/matsim/alonso_mora/algorithm/assignment/MpsAssignmentWriter.java +++ b/core/src/main/java/org/matsim/alonso_mora/algorithm/assignment/MpsAssignmentWriter.java @@ -13,6 +13,7 @@ import org.matsim.alonso_mora.algorithm.AlonsoMoraRequest; import org.matsim.alonso_mora.algorithm.AlonsoMoraTrip; import org.matsim.alonso_mora.algorithm.AlonsoMoraVehicle; +import org.matsim.alonso_mora.algorithm.assignment.AssignmentSolver.RejectionPenalty; /** * Writes the assignment problem from Alonso-Mora et al. in MPS format which can @@ -23,13 +24,11 @@ public class MpsAssignmentWriter { private final List tripList; - private final double unassignmentPenalty; - private final double rejectionPenalty; + private final RejectionPenalty rejectionPenalty; - public MpsAssignmentWriter(List tripList, double unassignmentPenalty, double rejectionPenalty) { + public MpsAssignmentWriter(List tripList, RejectionPenalty rejectionPenalty) { this.tripList = tripList; this.rejectionPenalty = rejectionPenalty; - this.unassignmentPenalty = unassignmentPenalty; } public void write(File path) throws IOException { @@ -83,7 +82,7 @@ public void write(File path) throws IOException { // Request influences for (int i = 0; i < numberOfRequests; i++) { - double penalty = requestList.get(i).isAssigned() ? unassignmentPenalty : rejectionPenalty; + double penalty = rejectionPenalty.getPenalty(requestList.get(i)); writer.write(String.format(Locale.US, " x%d R%07d %f R%07d 1\n", i, 0, penalty, i + numberOfVehicles + 1)); } diff --git a/core/src/test/java/org/matsim/alonso_mora/algorithm/assignment/CbcMpsAssignmentSolverTest.java b/core/src/test/java/org/matsim/alonso_mora/algorithm/assignment/CbcMpsAssignmentSolverTest.java index 5634dbf..7e6edc5 100644 --- a/core/src/test/java/org/matsim/alonso_mora/algorithm/assignment/CbcMpsAssignmentSolverTest.java +++ b/core/src/test/java/org/matsim/alonso_mora/algorithm/assignment/CbcMpsAssignmentSolverTest.java @@ -15,6 +15,8 @@ import org.matsim.alonso_mora.algorithm.AlonsoMoraRequest; import org.matsim.alonso_mora.algorithm.AlonsoMoraTrip; import org.matsim.alonso_mora.algorithm.AlonsoMoraVehicle; +import org.matsim.alonso_mora.algorithm.assignment.AssignmentSolver.DefaultRejectionPenalty; +import org.matsim.alonso_mora.algorithm.assignment.AssignmentSolver.RejectionPenalty; import org.matsim.alonso_mora.algorithm.function.AlonsoMoraFunction.Result; import org.mockito.Mockito; @@ -50,7 +52,8 @@ public void testOneVehicleOneRequestExample(@TempDir File temporaryFolder) throw File problemFile = new File(temporaryFolder, "problem"); File solutionFile = new File(temporaryFolder, "problem"); - AssignmentSolver solver = new CbcMpsAssignmentSolver(9000.0, 9000.0, 1000, 0.1, problemFile, solutionFile, 0); + RejectionPenalty rejectionPenalty = new DefaultRejectionPenalty(9000.0, 9000.0); + AssignmentSolver solver = new CbcMpsAssignmentSolver(rejectionPenalty, 1000, 0.1, problemFile, solutionFile, 0); AlonsoMoraVehicle vehicle = mockVehicle(); AlonsoMoraRequest request = mockRequest(); @@ -68,7 +71,8 @@ public void testTwoIndependentRequests(@TempDir File temporaryFolder) throws IOE File problemFile = new File(temporaryFolder, "problem"); File solutionFile = new File(temporaryFolder, "problem"); - AssignmentSolver solver = new CbcMpsAssignmentSolver(9000.0, 9000.0, 1000, 0.1, problemFile, solutionFile, 0); + RejectionPenalty rejectionPenalty = new DefaultRejectionPenalty(9000.0, 9000.0); + AssignmentSolver solver = new CbcMpsAssignmentSolver(rejectionPenalty, 1000, 0.1, problemFile, solutionFile, 0); AlonsoMoraVehicle vehicle1 = mockVehicle(); AlonsoMoraRequest request1 = mockRequest(); @@ -91,7 +95,8 @@ public void testTwoRequestsWithOneVehicle(@TempDir File temporaryFolder) throws File problemFile = new File(temporaryFolder, "problem"); File solutionFile = new File(temporaryFolder, "problem"); - AssignmentSolver solver = new CbcMpsAssignmentSolver(9000.0, 9000.0, 1000, 0.1, problemFile, solutionFile, 0); + RejectionPenalty rejectionPenalty = new DefaultRejectionPenalty(9000.0, 9000.0); + AssignmentSolver solver = new CbcMpsAssignmentSolver(rejectionPenalty, 1000, 0.1, problemFile, solutionFile, 0); AlonsoMoraVehicle vehicle = mockVehicle(); AlonsoMoraRequest request1 = mockRequest(); @@ -118,7 +123,8 @@ public void testTwoRequestsWithOneVehicleLowPenalty(@TempDir File temporaryFolde File problemFile = new File(temporaryFolder, "problem"); File solutionFile = new File(temporaryFolder, "problem"); - AssignmentSolver solver = new CbcMpsAssignmentSolver(250.0, 250.0, 1000, 0.1, problemFile, solutionFile, 0); + RejectionPenalty rejectionPenalty = new DefaultRejectionPenalty(250.0, 250.0); + AssignmentSolver solver = new CbcMpsAssignmentSolver(rejectionPenalty, 1000, 0.1, problemFile, solutionFile, 0); AlonsoMoraVehicle vehicle = mockVehicle(); AlonsoMoraRequest request1 = mockRequest(); diff --git a/core/src/test/java/org/matsim/alonso_mora/algorithm/assignment/GlpkMpsAssignmentSolverTest.java b/core/src/test/java/org/matsim/alonso_mora/algorithm/assignment/GlpkMpsAssignmentSolverTest.java index f0beff4..40b2792 100644 --- a/core/src/test/java/org/matsim/alonso_mora/algorithm/assignment/GlpkMpsAssignmentSolverTest.java +++ b/core/src/test/java/org/matsim/alonso_mora/algorithm/assignment/GlpkMpsAssignmentSolverTest.java @@ -15,6 +15,8 @@ import org.matsim.alonso_mora.algorithm.AlonsoMoraRequest; import org.matsim.alonso_mora.algorithm.AlonsoMoraTrip; import org.matsim.alonso_mora.algorithm.AlonsoMoraVehicle; +import org.matsim.alonso_mora.algorithm.assignment.AssignmentSolver.DefaultRejectionPenalty; +import org.matsim.alonso_mora.algorithm.assignment.AssignmentSolver.RejectionPenalty; import org.matsim.alonso_mora.algorithm.function.AlonsoMoraFunction.Result; import org.mockito.Mockito; @@ -49,9 +51,9 @@ private AlonsoMoraTrip mockTrip(AlonsoMoraVehicle vehicle, double cost, AlonsoMo public void testOneVehicleOneRequestExample(@TempDir File temporaryFolder) throws IOException { File problemFile = new File(temporaryFolder, "problem"); File solutionFile = new File(temporaryFolder, "solution"); - - AssignmentSolver solver = new GlpkMpsAssignmentSolver(9000.0, 9000.0, 1000, 0.1, - problemFile, solutionFile); + + RejectionPenalty rejectionPenalty = new DefaultRejectionPenalty(9000.0, 9000.0); + AssignmentSolver solver = new GlpkMpsAssignmentSolver(rejectionPenalty, 1000, 0.1, problemFile, solutionFile); AlonsoMoraVehicle vehicle = mockVehicle(); AlonsoMoraRequest request = mockRequest(); @@ -68,9 +70,9 @@ public void testOneVehicleOneRequestExample(@TempDir File temporaryFolder) throw public void testTwoIndependentRequests(@TempDir File temporaryFolder) throws IOException { File problemFile = new File(temporaryFolder, "problem"); File solutionFile = new File(temporaryFolder, "solution"); - - AssignmentSolver solver = new GlpkMpsAssignmentSolver(9000.0, 9000.0, 1000, 0.1, - problemFile, solutionFile); + + RejectionPenalty rejectionPenalty = new DefaultRejectionPenalty(9000.0, 9000.0); + AssignmentSolver solver = new GlpkMpsAssignmentSolver(rejectionPenalty, 1000, 0.1, problemFile, solutionFile); AlonsoMoraVehicle vehicle1 = mockVehicle(); AlonsoMoraRequest request1 = mockRequest(); @@ -92,9 +94,9 @@ public void testTwoIndependentRequests(@TempDir File temporaryFolder) throws IOE public void testTwoRequestsWithOneVehicle(@TempDir File temporaryFolder) throws IOException { File problemFile = new File(temporaryFolder, "problem"); File solutionFile = new File(temporaryFolder, "solution"); - - AssignmentSolver solver = new GlpkMpsAssignmentSolver(9000.0, 9000.0, 1000, 0.1, - problemFile, solutionFile); + + RejectionPenalty rejectionPenalty = new DefaultRejectionPenalty(9000.0, 9000.0); + AssignmentSolver solver = new GlpkMpsAssignmentSolver(rejectionPenalty, 1000, 0.1, problemFile, solutionFile); AlonsoMoraVehicle vehicle = mockVehicle(); AlonsoMoraRequest request1 = mockRequest(); @@ -120,9 +122,9 @@ public void testTwoRequestsWithOneVehicle(@TempDir File temporaryFolder) throws public void testTwoRequestsWithOneVehicleLowPenalty(@TempDir File temporaryFolder) throws IOException { File problemFile = new File(temporaryFolder, "problem"); File solutionFile = new File(temporaryFolder, "solution"); - - AssignmentSolver solver = new GlpkMpsAssignmentSolver(250.0, 250.0, 1000, 0.1, - problemFile, solutionFile); + + RejectionPenalty rejectionPenalty = new DefaultRejectionPenalty(250.0, 250.0); + AssignmentSolver solver = new GlpkMpsAssignmentSolver(rejectionPenalty, 1000, 0.1, problemFile, solutionFile); AlonsoMoraVehicle vehicle = mockVehicle(); AlonsoMoraRequest request1 = mockRequest(); diff --git a/cplex/src/main/java/org/matsim/alonso_mora/gurobi/CplexAssignmentSolver.java b/cplex/src/main/java/org/matsim/alonso_mora/gurobi/CplexAssignmentSolver.java index f6b7c19..f0ab88b 100644 --- a/cplex/src/main/java/org/matsim/alonso_mora/gurobi/CplexAssignmentSolver.java +++ b/cplex/src/main/java/org/matsim/alonso_mora/gurobi/CplexAssignmentSolver.java @@ -34,16 +34,14 @@ public class CplexAssignmentSolver implements AssignmentSolver { private static final Logger logger = LogManager.getLogger(CplexAssignmentSolver.class); - private final double unassignmentPenalty; - private final double rejectionPenalty; + private final RejectionPenalty rejectionPenalty; private final int numberOfThreads; private final double timeLimit; private final double optimalityGap; - public CplexAssignmentSolver(double unassignmentPenalty, double rejectionPenalty, int numberOfThreads, - double timeLimit, double optimalityGap) { - this.unassignmentPenalty = unassignmentPenalty; + public CplexAssignmentSolver(RejectionPenalty rejectionPenalty, int numberOfThreads, double timeLimit, + double optimalityGap) { this.rejectionPenalty = rejectionPenalty; this.numberOfThreads = numberOfThreads; this.timeLimit = timeLimit; @@ -129,7 +127,7 @@ public Solution solve(Stream candidates) { for (int k = 0; k < requestVariables.size(); k++) { AlonsoMoraRequest request = requestList.get(k); - double penalty = request.isAssigned() ? unassignmentPenalty : rejectionPenalty; + double penalty = rejectionPenalty.getPenalty(request); objective.addTerm(penalty, requestVariables.get(k)); } diff --git a/cplex/src/main/java/org/matsim/alonso_mora/gurobi/CplexModule.java b/cplex/src/main/java/org/matsim/alonso_mora/gurobi/CplexModule.java index 0c75c06..443cdc6 100644 --- a/cplex/src/main/java/org/matsim/alonso_mora/gurobi/CplexModule.java +++ b/cplex/src/main/java/org/matsim/alonso_mora/gurobi/CplexModule.java @@ -3,6 +3,7 @@ import org.matsim.alonso_mora.AlonsoMoraConfigGroup; import org.matsim.alonso_mora.MultiModeAlonsoMoraConfigGroup; import org.matsim.alonso_mora.algorithm.assignment.AssignmentSolver; +import org.matsim.alonso_mora.algorithm.assignment.AssignmentSolver.RejectionPenalty; import org.matsim.alonso_mora.algorithm.relocation.RelocationSolver; import org.matsim.contrib.drt.run.DrtConfigGroup; import org.matsim.contrib.dvrp.run.AbstractDvrpModeQSimModule; @@ -37,8 +38,8 @@ protected void configureQSim() { CplexAssignmentParameters solverParameters = (CplexAssignmentParameters) amConfig.assignmentSolver; - return new CplexAssignmentSolver(amConfig.unassignmentPenalty, amConfig.rejectionPenalty, - globalConfig.getNumberOfThreads(), solverParameters.timeLimit, solverParameters.optimalityGap); + return new CplexAssignmentSolver(getter.getModal(RejectionPenalty.class), globalConfig.getNumberOfThreads(), + solverParameters.timeLimit, solverParameters.optimalityGap); })).in(Singleton.class); if (amConfig.assignmentSolver.getSolverType().equals(CplexAssignmentSolver.TYPE)) { diff --git a/cplex/src/test/java/org/matsim/alonso_mora/gurobi/CplexAssignmentSolverTest.java b/cplex/src/test/java/org/matsim/alonso_mora/gurobi/CplexAssignmentSolverTest.java index d53970d..9d4ef70 100644 --- a/cplex/src/test/java/org/matsim/alonso_mora/gurobi/CplexAssignmentSolverTest.java +++ b/cplex/src/test/java/org/matsim/alonso_mora/gurobi/CplexAssignmentSolverTest.java @@ -13,6 +13,8 @@ import org.matsim.alonso_mora.algorithm.AlonsoMoraTrip; import org.matsim.alonso_mora.algorithm.AlonsoMoraVehicle; import org.matsim.alonso_mora.algorithm.assignment.AssignmentSolver; +import org.matsim.alonso_mora.algorithm.assignment.AssignmentSolver.DefaultRejectionPenalty; +import org.matsim.alonso_mora.algorithm.assignment.AssignmentSolver.RejectionPenalty; import org.matsim.alonso_mora.algorithm.function.AlonsoMoraFunction.Result; import org.matsim.api.core.v01.Id; import org.matsim.contrib.dvrp.fleet.DvrpVehicle; @@ -52,7 +54,8 @@ private AlonsoMoraTrip mockTrip(AlonsoMoraVehicle vehicle, double cost, AlonsoMo @Test public void testOneVehicleOneRequestExample() { - AssignmentSolver solver = new CplexAssignmentSolver(9000.0, 9000.0, 1000, 10.0, 0.1); + RejectionPenalty rejectionPenalty = new DefaultRejectionPenalty(9000.0, 9000.0); + AssignmentSolver solver = new CplexAssignmentSolver(rejectionPenalty, 1000, 10.0, 0.1); AlonsoMoraVehicle vehicle = mockVehicle(0); AlonsoMoraRequest request = mockRequest(); @@ -67,7 +70,8 @@ public void testOneVehicleOneRequestExample() { @Test public void testTwoIndependentRequests() { - AssignmentSolver solver = new CplexAssignmentSolver(9000.0, 9000.0, 1000, 10.0, 0.1); + RejectionPenalty rejectionPenalty = new DefaultRejectionPenalty(9000.0, 9000.0); + AssignmentSolver solver = new CplexAssignmentSolver(rejectionPenalty, 1000, 10.0, 0.1); AlonsoMoraVehicle vehicle1 = mockVehicle(1); AlonsoMoraRequest request1 = mockRequest(); @@ -87,7 +91,8 @@ public void testTwoIndependentRequests() { @Test public void testTwoRequestsWithOneVehicle() { - AssignmentSolver solver = new CplexAssignmentSolver(9000.0, 9000.0, 1000, 10.0, 0.1); + RejectionPenalty rejectionPenalty = new DefaultRejectionPenalty(9000.0, 9000.0); + AssignmentSolver solver = new CplexAssignmentSolver(rejectionPenalty, 1000, 10.0, 0.1); AlonsoMoraVehicle vehicle = mockVehicle(0); AlonsoMoraRequest request1 = mockRequest(); @@ -111,7 +116,8 @@ public void testTwoRequestsWithOneVehicle() { @Test public void testTwoRequestsWithOneVehicleLowPenalty() { - AssignmentSolver solver = new CplexAssignmentSolver(250.0, 250.0, 1000, 10.0, 0.1); + RejectionPenalty rejectionPenalty = new DefaultRejectionPenalty(250.0, 250.0); + AssignmentSolver solver = new CplexAssignmentSolver(rejectionPenalty, 1000, 10.0, 0.1); AlonsoMoraVehicle vehicle = mockVehicle(0); AlonsoMoraRequest request1 = mockRequest(); diff --git a/glpk/src/main/java/org/matsim/alonso_mora/glpk/GlpkJniAssignmentSolver.java b/glpk/src/main/java/org/matsim/alonso_mora/glpk/GlpkJniAssignmentSolver.java index d493427..8ab84b0 100644 --- a/glpk/src/main/java/org/matsim/alonso_mora/glpk/GlpkJniAssignmentSolver.java +++ b/glpk/src/main/java/org/matsim/alonso_mora/glpk/GlpkJniAssignmentSolver.java @@ -35,14 +35,11 @@ public class GlpkJniAssignmentSolver implements AssignmentSolver { private static final Logger logger = LogManager.getLogger(GlpkJniAssignmentSolver.class); - private final double unassignmentPenalty; - private final double rejectionPenalty; + private final RejectionPenalty rejectionPenalty; private final double timeLimit; private final double optimalityGap; - public GlpkJniAssignmentSolver(double unassignmentPenalty, double rejectionPenalty, double timeLimit, - double optimalityGap) { - this.unassignmentPenalty = unassignmentPenalty; + public GlpkJniAssignmentSolver(RejectionPenalty rejectionPenalty, double timeLimit, double optimalityGap) { this.rejectionPenalty = rejectionPenalty; this.timeLimit = timeLimit; this.optimalityGap = optimalityGap; @@ -161,7 +158,7 @@ public Solution solve(Stream candidates) { } for (int i = 0; i < numberOfRequests; i++) { - double penalty = requestList.get(i).isAssigned() ? unassignmentPenalty : rejectionPenalty; + double penalty = rejectionPenalty.getPenalty(requestList.get(i)); GLPK.glp_set_obj_coef(problem, i + numberOfTrips + 1, penalty); } diff --git a/glpk/src/main/java/org/matsim/alonso_mora/glpk/GlpkModule.java b/glpk/src/main/java/org/matsim/alonso_mora/glpk/GlpkModule.java index 5c84470..ea0334f 100644 --- a/glpk/src/main/java/org/matsim/alonso_mora/glpk/GlpkModule.java +++ b/glpk/src/main/java/org/matsim/alonso_mora/glpk/GlpkModule.java @@ -3,6 +3,7 @@ import org.matsim.alonso_mora.AlonsoMoraConfigGroup; import org.matsim.alonso_mora.MultiModeAlonsoMoraConfigGroup; import org.matsim.alonso_mora.algorithm.assignment.AssignmentSolver; +import org.matsim.alonso_mora.algorithm.assignment.AssignmentSolver.RejectionPenalty; import org.matsim.alonso_mora.algorithm.relocation.RelocationSolver; import org.matsim.contrib.drt.run.DrtConfigGroup; import org.matsim.contrib.dvrp.run.AbstractDvrpModeQSimModule; @@ -38,8 +39,8 @@ protected void configureQSim() { GlpkJniAssignmentParameters solverParameters = (GlpkJniAssignmentParameters) amConfig.assignmentSolver; - return new GlpkJniAssignmentSolver(amConfig.unassignmentPenalty, amConfig.rejectionPenalty, - solverParameters.timeLimit, solverParameters.optimalityGap); + return new GlpkJniAssignmentSolver(getter.getModal(RejectionPenalty.class), solverParameters.timeLimit, + solverParameters.optimalityGap); })).in(Singleton.class); if (amConfig.assignmentSolver.getSolverType().equals(GlpkJniAssignmentSolver.TYPE)) { diff --git a/glpk/src/test/java/org/matsim/alonso_mora/glpk/GlpkJniAssignmentSolverTest.java b/glpk/src/test/java/org/matsim/alonso_mora/glpk/GlpkJniAssignmentSolverTest.java index 138ac0f..eb6fcd1 100644 --- a/glpk/src/test/java/org/matsim/alonso_mora/glpk/GlpkJniAssignmentSolverTest.java +++ b/glpk/src/test/java/org/matsim/alonso_mora/glpk/GlpkJniAssignmentSolverTest.java @@ -13,6 +13,8 @@ import org.matsim.alonso_mora.algorithm.AlonsoMoraTrip; import org.matsim.alonso_mora.algorithm.AlonsoMoraVehicle; import org.matsim.alonso_mora.algorithm.assignment.AssignmentSolver; +import org.matsim.alonso_mora.algorithm.assignment.AssignmentSolver.DefaultRejectionPenalty; +import org.matsim.alonso_mora.algorithm.assignment.AssignmentSolver.RejectionPenalty; import org.matsim.alonso_mora.algorithm.function.AlonsoMoraFunction.Result; import org.mockito.Mockito; @@ -45,7 +47,8 @@ private AlonsoMoraTrip mockTrip(AlonsoMoraVehicle vehicle, double cost, AlonsoMo @Test public void testOneVehicleOneRequestExample() { - AssignmentSolver solver = new GlpkJniAssignmentSolver(9000.0, 9000.0, 1000, 0.1); + RejectionPenalty rejectionPenalty = new DefaultRejectionPenalty(9000.0, 9000.0); + AssignmentSolver solver = new GlpkJniAssignmentSolver(rejectionPenalty, 1000, 0.1); AlonsoMoraVehicle vehicle = mockVehicle(); AlonsoMoraRequest request = mockRequest(); @@ -60,7 +63,8 @@ public void testOneVehicleOneRequestExample() { @Test public void testTwoIndependentRequests() { - AssignmentSolver solver = new GlpkJniAssignmentSolver(9000.0, 9000.0, 1000, 0.1); + RejectionPenalty rejectionPenalty = new DefaultRejectionPenalty(9000.0, 9000.0); + AssignmentSolver solver = new GlpkJniAssignmentSolver(rejectionPenalty, 1000, 0.1); AlonsoMoraVehicle vehicle1 = mockVehicle(); AlonsoMoraRequest request1 = mockRequest(); @@ -80,7 +84,8 @@ public void testTwoIndependentRequests() { @Test public void testTwoRequestsWithOneVehicle() { - AssignmentSolver solver = new GlpkJniAssignmentSolver(9000.0, 9000.0, 1000, 0.1); + RejectionPenalty rejectionPenalty = new DefaultRejectionPenalty(9000.0, 9000.0); + AssignmentSolver solver = new GlpkJniAssignmentSolver(rejectionPenalty, 1000, 0.1); AlonsoMoraVehicle vehicle = mockVehicle(); AlonsoMoraRequest request1 = mockRequest(); @@ -104,7 +109,8 @@ public void testTwoRequestsWithOneVehicle() { @Test public void testTwoRequestsWithOneVehicleLowPenalty() { - AssignmentSolver solver = new GlpkJniAssignmentSolver(250.0, 250.0, 1000, 0.1); + RejectionPenalty rejectionPenalty = new DefaultRejectionPenalty(250.0, 250.0); + AssignmentSolver solver = new GlpkJniAssignmentSolver(rejectionPenalty, 1000, 0.1); AlonsoMoraVehicle vehicle = mockVehicle(); AlonsoMoraRequest request1 = mockRequest(); diff --git a/gurobi/src/main/java/org/matsim/alonso_mora/gurobi/GurobiAssignmentSolver.java b/gurobi/src/main/java/org/matsim/alonso_mora/gurobi/GurobiAssignmentSolver.java index e739ae1..f8c2736 100644 --- a/gurobi/src/main/java/org/matsim/alonso_mora/gurobi/GurobiAssignmentSolver.java +++ b/gurobi/src/main/java/org/matsim/alonso_mora/gurobi/GurobiAssignmentSolver.java @@ -36,16 +36,14 @@ public class GurobiAssignmentSolver implements AssignmentSolver { private static final Logger logger = LogManager.getLogger(GurobiAssignmentSolver.class); - private final double unassignmentPenalty; - private final double rejectionPenalty; + private final RejectionPenalty rejectionPenalty; private final int numberOfThreads; private final double timeLimit; private final double optimalityGap; - public GurobiAssignmentSolver(double unassignmentPenalty, double rejectionPenalty, int numberOfThreads, - double timeLimit, double optimalityGap) { - this.unassignmentPenalty = unassignmentPenalty; + public GurobiAssignmentSolver(RejectionPenalty rejectionPenalty, int numberOfThreads, double timeLimit, + double optimalityGap) { this.rejectionPenalty = rejectionPenalty; this.numberOfThreads = numberOfThreads; this.timeLimit = timeLimit; @@ -132,7 +130,7 @@ public Solution solve(Stream candidates) { for (int k = 0; k < requestVariables.size(); k++) { AlonsoMoraRequest request = requestList.get(k); - double penalty = request.isAssigned() ? unassignmentPenalty : rejectionPenalty; + double penalty = rejectionPenalty.getPenalty(request); objective.addTerm(penalty, requestVariables.get(k)); } diff --git a/gurobi/src/main/java/org/matsim/alonso_mora/gurobi/GurobiModule.java b/gurobi/src/main/java/org/matsim/alonso_mora/gurobi/GurobiModule.java index fef72ae..05d632b 100644 --- a/gurobi/src/main/java/org/matsim/alonso_mora/gurobi/GurobiModule.java +++ b/gurobi/src/main/java/org/matsim/alonso_mora/gurobi/GurobiModule.java @@ -3,6 +3,7 @@ import org.matsim.alonso_mora.AlonsoMoraConfigGroup; import org.matsim.alonso_mora.MultiModeAlonsoMoraConfigGroup; import org.matsim.alonso_mora.algorithm.assignment.AssignmentSolver; +import org.matsim.alonso_mora.algorithm.assignment.AssignmentSolver.RejectionPenalty; import org.matsim.alonso_mora.algorithm.relocation.RelocationSolver; import org.matsim.contrib.drt.run.DrtConfigGroup; import org.matsim.contrib.dvrp.run.AbstractDvrpModeQSimModule; @@ -37,7 +38,7 @@ protected void configureQSim() { GurobiAssignmentParameters solverParameters = (GurobiAssignmentParameters) amConfig.assignmentSolver; - return new GurobiAssignmentSolver(amConfig.unassignmentPenalty, amConfig.rejectionPenalty, + return new GurobiAssignmentSolver(getter.getModal(RejectionPenalty.class), globalConfig.getNumberOfThreads(), solverParameters.timeLimit, solverParameters.optimalityGap); })).in(Singleton.class); diff --git a/gurobi/src/test/java/org/matsim/alonso_mora/gurobi/GurobiAssignmentSolverTest.java b/gurobi/src/test/java/org/matsim/alonso_mora/gurobi/GurobiAssignmentSolverTest.java index b9c4179..1b60b30 100644 --- a/gurobi/src/test/java/org/matsim/alonso_mora/gurobi/GurobiAssignmentSolverTest.java +++ b/gurobi/src/test/java/org/matsim/alonso_mora/gurobi/GurobiAssignmentSolverTest.java @@ -13,6 +13,8 @@ import org.matsim.alonso_mora.algorithm.AlonsoMoraTrip; import org.matsim.alonso_mora.algorithm.AlonsoMoraVehicle; import org.matsim.alonso_mora.algorithm.assignment.AssignmentSolver; +import org.matsim.alonso_mora.algorithm.assignment.AssignmentSolver.DefaultRejectionPenalty; +import org.matsim.alonso_mora.algorithm.assignment.AssignmentSolver.RejectionPenalty; import org.matsim.alonso_mora.algorithm.function.AlonsoMoraFunction.Result; import org.matsim.api.core.v01.Id; import org.matsim.contrib.dvrp.fleet.DvrpVehicle; @@ -52,7 +54,8 @@ private AlonsoMoraTrip mockTrip(AlonsoMoraVehicle vehicle, double cost, AlonsoMo @Test public void testOneVehicleOneRequestExample() { - AssignmentSolver solver = new GurobiAssignmentSolver(9000.0, 9000.0, 1000, 10.0, 0.1); + RejectionPenalty rejectionPenalty = new DefaultRejectionPenalty(9000.0, 9000.0); + AssignmentSolver solver = new GurobiAssignmentSolver(rejectionPenalty, 1000, 10.0, 0.1); AlonsoMoraVehicle vehicle = mockVehicle(0); AlonsoMoraRequest request = mockRequest(); @@ -67,7 +70,8 @@ public void testOneVehicleOneRequestExample() { @Test public void testTwoIndependentRequests() { - AssignmentSolver solver = new GurobiAssignmentSolver(9000.0, 9000.0, 1000, 10.0, 0.1); + RejectionPenalty rejectionPenalty = new DefaultRejectionPenalty(9000.0, 9000.0); + AssignmentSolver solver = new GurobiAssignmentSolver(rejectionPenalty, 1000, 10.0, 0.1); AlonsoMoraVehicle vehicle1 = mockVehicle(1); AlonsoMoraRequest request1 = mockRequest(); @@ -87,7 +91,8 @@ public void testTwoIndependentRequests() { @Test public void testTwoRequestsWithOneVehicle() { - AssignmentSolver solver = new GurobiAssignmentSolver(9000.0, 9000.0, 1000, 10.0, 0.1); + RejectionPenalty rejectionPenalty = new DefaultRejectionPenalty(9000.0, 9000.0); + AssignmentSolver solver = new GurobiAssignmentSolver(rejectionPenalty, 1000, 10.0, 0.1); AlonsoMoraVehicle vehicle = mockVehicle(0); AlonsoMoraRequest request1 = mockRequest(); @@ -111,7 +116,8 @@ public void testTwoRequestsWithOneVehicle() { @Test public void testTwoRequestsWithOneVehicleLowPenalty() { - AssignmentSolver solver = new GurobiAssignmentSolver(250.0, 250.0, 1000, 10.0, 0.1); + RejectionPenalty rejectionPenalty = new DefaultRejectionPenalty(250.0, 250.0); + AssignmentSolver solver = new GurobiAssignmentSolver(rejectionPenalty, 1000, 10.0, 0.1); AlonsoMoraVehicle vehicle = mockVehicle(0); AlonsoMoraRequest request1 = mockRequest();