Skip to content

Commit

Permalink
fix: Make Cbc MPS determinstic (#19)
Browse files Browse the repository at this point in the history
sebhoerl authored Sep 7, 2022

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
1 parent 3b61908 commit 238cf5e
Showing 5 changed files with 32 additions and 24 deletions.
Original file line number Diff line number Diff line change
@@ -130,8 +130,8 @@ protected void configureQSim() {
.getAssignmentSolverParameters();

return new CbcMpsAssignmentSolver(amConfig.getUnassignmentPenalty(), amConfig.getRejectionPenalty(),
solverParameters.getTimeLimit(), solverParameters.getOptimalityGap(), problemPath,
solutionPath);
solverParameters.getTimeLimit(), solverParameters.getOptimalityGap(), problemPath, solutionPath,
getConfig().global().getRandomSeed());
})).in(Singleton.class);

bindModal(GlpkMpsAssignmentSolver.class).toProvider(modalProvider(getter -> {
@@ -147,8 +147,7 @@ protected void configureQSim() {
.getAssignmentSolverParameters();

return new GlpkMpsAssignmentSolver(amConfig.getUnassignmentPenalty(), amConfig.getRejectionPenalty(),
solverParameters.getTimeLimit(), solverParameters.getOptimalityGap(), problemPath,
solutionPath);
solverParameters.getTimeLimit(), solverParameters.getOptimalityGap(), problemPath, solutionPath);
})).in(Singleton.class);

switch (amConfig.getAssignmentSolverParameters().getSolverType()) {
@@ -182,7 +181,8 @@ protected void configureQSim() {
CbcMpsRelocationParameters solverParameters = (CbcMpsRelocationParameters) amConfig
.getRelocationSolverParameters();

return new CbcMpsRelocationSolver(solverParameters.getRuntimeThreshold(), problemPath, solutionPath);
return new CbcMpsRelocationSolver(solverParameters.getRuntimeThreshold(), problemPath, solutionPath,
getConfig().global().getRandomSeed());
})).in(Singleton.class);

bindModal(GlpkMpsRelocationSolver.class).toProvider(modalProvider(getter -> {
@@ -230,7 +230,7 @@ protected void configureQSim() {
TravelTimeMatrix matrix = getter.getModal(TravelTimeMatrix.class);
TravelTime travelTime = getter.getModal(TravelTime.class);
double speedFactor = 1.0;

return new DrtDetourTravelTimeEstimator((from, to, departureTime) -> {
if (from == to) {
return 0;
Original file line number Diff line number Diff line change
@@ -37,9 +37,10 @@ public class CbcMpsAssignmentSolver implements AssignmentSolver {

private final double timeLimit;
private final double optimalityGap;
private final long randomSeed;

public CbcMpsAssignmentSolver(double unassignmentPenalty, double rejectionPenalty, double timeLimit,
double optimalityGap, File problemPath, File solutionPath) {
double optimalityGap, File problemPath, File solutionPath, long randomSeed) {
this.unassignmentPenalty = unassignmentPenalty;
this.rejectionPenalty = rejectionPenalty;

@@ -48,6 +49,8 @@ public CbcMpsAssignmentSolver(double unassignmentPenalty, double rejectionPenalt

this.timeLimit = timeLimit;
this.optimalityGap = optimalityGap;

this.randomSeed = randomSeed;
}

@Override
@@ -56,8 +59,10 @@ public Solution solve(Stream<AlonsoMoraTrip> candidates) {
List<AlonsoMoraTrip> tripList = candidates.collect(Collectors.toList());
new MpsAssignmentWriter(tripList, unassignmentPenalty, rejectionPenalty).write(problemPath);

new ProcessBuilder("cbc", problemPath.toString(), "ratio", String.valueOf(optimalityGap), "sec",
String.valueOf(timeLimit), "solve", "solution", solutionPath.toString()).start().waitFor();
new ProcessBuilder("cbc", problemPath.toString(), "-randomSeed", String.valueOf(randomSeed),
"-randomCbcSeed", String.valueOf(randomSeed), "-ratio", String.valueOf(optimalityGap), "-seconds",
String.valueOf(timeLimit), "-threads", "1", "-solve", "-solution", solutionPath.toString()).start()
.waitFor();

BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(solutionPath)));

Original file line number Diff line number Diff line change
@@ -30,12 +30,14 @@ public class CbcMpsRelocationSolver implements RelocationSolver {
private final File solutionPath;

private final int timeLimit;
private final long randomSeed;

public CbcMpsRelocationSolver(int timeLimit, File problemPath, File solutionPath) {
public CbcMpsRelocationSolver(int timeLimit, File problemPath, File solutionPath, long randomSeed) {
this.problemPath = problemPath;
this.solutionPath = solutionPath;

this.timeLimit = timeLimit;
this.randomSeed = randomSeed;
}

@Override
@@ -44,8 +46,9 @@ public Collection<Relocation> solve(List<Relocation> candidates) {
List<Relocation> relocations = new ArrayList<>(candidates);
new MpsRelocationWriter(relocations).write(problemPath);

new ProcessBuilder("cbc", problemPath.toString(), "sec", String.valueOf(1e-3 * timeLimit), "solve",
"solution", solutionPath.toString()).start().waitFor();
new ProcessBuilder("cbc", problemPath.toString(), "-randomSeed", String.valueOf(randomSeed),
"-randomCbcSeed", String.valueOf(randomSeed), "-seconds", String.valueOf(1e-3 * timeLimit),
"-threads", "1", "-solve", "-solution", solutionPath.toString()).start().waitFor();

BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(solutionPath)));

Original file line number Diff line number Diff line change
@@ -50,7 +50,7 @@ private AlonsoMoraTrip mockTrip(AlonsoMoraVehicle vehicle, double cost, AlonsoMo
@Test
public void testOneVehicleOneRequestExample() throws IOException {
AssignmentSolver solver = new CbcMpsAssignmentSolver(9000.0, 9000.0, 1000, 0.1,
temporaryFolder.newFile("problem"), temporaryFolder.newFile("solution"));
temporaryFolder.newFile("problem"), temporaryFolder.newFile("solution"), 0);

AlonsoMoraVehicle vehicle = mockVehicle();
AlonsoMoraRequest request = mockRequest();
@@ -66,7 +66,7 @@ public void testOneVehicleOneRequestExample() throws IOException {
@Test
public void testTwoIndependentRequests() throws IOException {
AssignmentSolver solver = new CbcMpsAssignmentSolver(9000.0, 9000.0, 1000, 0.1,
temporaryFolder.newFile("problem"), temporaryFolder.newFile("solution"));
temporaryFolder.newFile("problem"), temporaryFolder.newFile("solution"), 0);

AlonsoMoraVehicle vehicle1 = mockVehicle();
AlonsoMoraRequest request1 = mockRequest();
@@ -87,7 +87,7 @@ public void testTwoIndependentRequests() throws IOException {
@Test
public void testTwoRequestsWithOneVehicle() throws IOException {
AssignmentSolver solver = new CbcMpsAssignmentSolver(9000.0, 9000.0, 1000, 0.1,
temporaryFolder.newFile("problem"), temporaryFolder.newFile("solution"));
temporaryFolder.newFile("problem"), temporaryFolder.newFile("solution"), 0);

AlonsoMoraVehicle vehicle = mockVehicle();
AlonsoMoraRequest request1 = mockRequest();
@@ -112,7 +112,7 @@ public void testTwoRequestsWithOneVehicle() throws IOException {
@Test
public void testTwoRequestsWithOneVehicleLowPenalty() throws IOException {
AssignmentSolver solver = new CbcMpsAssignmentSolver(250.0, 250.0, 1000, 0.1,
temporaryFolder.newFile("problem"), temporaryFolder.newFile("solution"));
temporaryFolder.newFile("problem"), temporaryFolder.newFile("solution"), 0);

AlonsoMoraVehicle vehicle = mockVehicle();
AlonsoMoraRequest request1 = mockRequest();
Original file line number Diff line number Diff line change
@@ -34,7 +34,7 @@ public void checkSolver() {
public void testTwoVehicesOneDestination() throws IOException {
CbcMpsRelocationSolver solver = new CbcMpsRelocationSolver(1000, //
temporaryFolder.newFile("problem"), //
temporaryFolder.newFile("solution"));
temporaryFolder.newFile("solution"), 0);

AlonsoMoraVehicle vehicle = Mockito.mock(AlonsoMoraVehicle.class);

@@ -52,7 +52,7 @@ public void testTwoVehicesOneDestination() throws IOException {
public void testOneVehicesTwoDestinations() throws IOException {
CbcMpsRelocationSolver solver = new CbcMpsRelocationSolver(1000, //
temporaryFolder.newFile("problem"), //
temporaryFolder.newFile("solution"));
temporaryFolder.newFile("solution"), 0);

Link link = Mockito.mock(Link.class);

@@ -65,16 +65,16 @@ public void testOneVehicesTwoDestinations() throws IOException {
assertEquals(1, solution.size());
assertEquals(relocations.get(0), solution.iterator().next());
}

@Test
public void testComplex() throws IOException {
CbcMpsRelocationSolver solver = new CbcMpsRelocationSolver(1000, //
temporaryFolder.newFile("problem"), //
temporaryFolder.newFile("solution"));
temporaryFolder.newFile("solution"), 0);

Link linkA = Mockito.mock(Link.class);
Link linkB = Mockito.mock(Link.class);

AlonsoMoraVehicle vehicle1 = Mockito.mock(AlonsoMoraVehicle.class);
AlonsoMoraVehicle vehicle2 = Mockito.mock(AlonsoMoraVehicle.class);
AlonsoMoraVehicle vehicle3 = Mockito.mock(AlonsoMoraVehicle.class);
@@ -89,7 +89,7 @@ public void testComplex() throws IOException {
Collection<Relocation> solution = solver.solve(relocations);

assertEquals(2, solution.size());

List<Relocation> expected = new ArrayList<>(Arrays.asList(relocations.get(0), relocations.get(4)));
expected.removeAll(relocations);
assertEquals(0, expected.size());
@@ -99,7 +99,7 @@ public void testComplex() throws IOException {
public void testEmpty() throws IOException {
CbcMpsRelocationSolver solver = new CbcMpsRelocationSolver(1000, //
temporaryFolder.newFile("problem"), //
temporaryFolder.newFile("solution"));
temporaryFolder.newFile("solution"), 0);

Collection<Relocation> solution = solver.solve(Collections.emptyList());

0 comments on commit 238cf5e

Please sign in to comment.