Skip to content

Commit 0abeed6

Browse files
committed
Update machine sepa
1 parent 307bacd commit 0abeed6

2 files changed

Lines changed: 23 additions & 29 deletions

File tree

highs/mip/HighsMachineSchedSeparator.cpp

Lines changed: 23 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@
1010

1111
#include "mip/HighsMachineSchedSeparator.h"
1212

13-
#include "../extern/pdqsort/pdqsort.h"
13+
#include <unordered_map>
14+
1415
#include "mip/HighsCutGeneration.h"
1516
#include "mip/HighsLpRelaxation.h"
1617
#include "mip/HighsMipSolverData.h"
@@ -137,6 +138,7 @@ bool HighsMachineSchedSeparator::findSingleMachineScheduleClique(
137138
if (numRows > maxRows) break;
138139
}
139140

141+
// A clique of size 3 needs at least 6 arcs
140142
if (numRows <= 5) return false;
141143

142144
// Greedily search neighbours of largest degree column for a double-sided
@@ -149,24 +151,19 @@ bool HighsMachineSchedSeparator::findSingleMachineScheduleClique(
149151
potentialNeighbours.emplace_back(std::get<0>(arc.first));
150152
}
151153
}
152-
inds.reserve(std::min(largestDegree, 50));
153-
inds.emplace_back();
154-
inds.back().reserve(std::min(largestDegree, 50));
155-
rhss.resize(largestDegree + 1, 0);
156154
std::vector<HighsInt> neighbours;
157155
neighbours.reserve(largestDegree + 1);
158156
neighbours.emplace_back(largestDegreeCol);
159157
releasedate = mipsolver.mipdata_->domain.col_lower_[largestDegreeCol];
160158
std::vector<double> processingTimes;
161159
processingTimes.resize(largestDegree + 1, kHighsInf);
162-
// Iterate over potential neighbours, check validity, and build inequalities
160+
// Iterate over potential neighbours and check validity
163161
for (HighsInt col : potentialNeighbours) {
164162
bool valid_neighbour = true;
165163
for (HighsInt neighbour : neighbours) {
166164
auto fromArc = adjacency.find({col, neighbour});
167165
auto toArc = adjacency.find({neighbour, col});
168-
// Need to actually verify that the to and fromArc are opposites (or
169-
// can't exist together)
166+
// Need to verify that the to and fromArc exist and are opposites
170167
if (toArc == adjacency.end() || fromArc == adjacency.end() ||
171168
std::get<1>(fromArc->second) != std::get<1>(toArc->second) ||
172169
std::get<2>(fromArc->second) == std::get<2>(toArc->second)) {
@@ -176,46 +173,44 @@ bool HighsMachineSchedSeparator::findSingleMachineScheduleClique(
176173
}
177174
if (!valid_neighbour) continue;
178175
size_t newNeighbourIndex = neighbours.size();
179-
inds.emplace_back();
180-
inds.back().reserve(std::min(largestDegree, 50));
176+
// Extract the processing times from the arcs
181177
for (size_t i = 0; i != neighbours.size(); ++i) {
182178
HighsInt neighbour = neighbours[i];
183179
const auto fromArc = adjacency.find({col, neighbour});
184180
const auto toArc = adjacency.find({neighbour, col});
185-
inds[i].emplace_back(std::get<1>(toArc->second));
186181
processingTimes[newNeighbourIndex] = std::min(
187-
processingTimes[newNeighbourIndex], std::get<0>(toArc->second));
188-
inds[newNeighbourIndex].emplace_back(std::get<1>(fromArc->second));
182+
processingTimes[newNeighbourIndex], std::get<0>(fromArc->second));
189183
processingTimes[i] =
190-
std::min(processingTimes[i], std::get<0>(fromArc->second));
184+
std::min(processingTimes[i], std::get<0>(toArc->second));
191185
}
192186
releasedate =
193187
std::min(mipsolver.mipdata_->domain.col_lower_[col], releasedate);
194188
neighbours.emplace_back(col);
195189
}
196-
if (neighbours.size() <= 3) return false;
190+
if (neighbours.size() < 3) return false;
197191

198-
// Now populate the actual cut coefficients
199-
// Currently we only have the cut indices (processing times, i.e.,
200-
// coefficients, were not available before this point)
201-
vals.resize(neighbours.size());
192+
// Now populate the actual inequalities
193+
vals.resize(neighbours.size(), std::vector<double>(neighbours.size()));
194+
inds.resize(neighbours.size(), std::vector<HighsInt>(neighbours.size()));
195+
rhss.resize(neighbours.size());
202196
for (size_t i = 0; i != neighbours.size(); ++i) {
203197
rhss[i] -= releasedate;
204198
HighsInt col = neighbours[i];
205-
vals[i].resize(inds[i].size() + 1);
206-
for (size_t j = 0; j != inds[i].size(); ++j) {
199+
for (size_t j = 0; j != neighbours.size(); ++j) {
207200
size_t jj = j >= i ? j + 1 : j;
201+
if (jj >= neighbours.size()) continue;
208202
HighsInt neighbour = neighbours[jj];
209-
const auto arc = adjacency.find({neighbour, col});
210-
assert (arc != adjacency.end());
203+
const auto toArc = adjacency.find({neighbour, col});
204+
assert(toArc != adjacency.end());
205+
inds[i][j] = std::get<1>(toArc->second);
211206
vals[i][j] = processingTimes[jj];
212-
if (std::get<2>(arc->second) == ArcType::kIfBinZero) {
207+
if (std::get<2>(toArc->second) == ArcType::kIfBinZero) {
213208
rhss[i] -= vals[i][j];
214209
vals[i][j] *= -1;
215210
}
216211
}
217212
// Put the job start time on the LHS
218-
inds[i].emplace_back(neighbours[i]);
213+
inds[i].back() = col;
219214
vals[i].back() = -1;
220215
}
221216

@@ -232,7 +227,7 @@ void HighsMachineSchedSeparator::separateLpSolution(
232227
std::vector<double> rhss;
233228
double releasedate;
234229
has_single_machine_schedule =
235-
findSingleMachineScheduleClique(vals, inds, rhss, releasedate, mip);
230+
findSingleMachineScheduleClique(vals, inds, rhss, releasedate, mip);
236231
if (!has_single_machine_schedule) {
237232
separated = true;
238233
return;
@@ -246,7 +241,8 @@ void HighsMachineSchedSeparator::separateLpSolution(
246241
viol += lpSolution[inds[i][j]] * vals[i][j];
247242
}
248243
if (viol >= 10 * mip.mipdata_->feastol)
249-
cutpool.addCut(mip, inds[i].data(), vals[i].data(), inds[i].size(), rhss[i]);
244+
cutpool.addCut(mip, inds[i].data(), vals[i].data(), inds[i].size(),
245+
rhss[i]);
250246
}
251247
separated = true;
252248
}

highs/mip/HighsMachineSchedSeparator.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,6 @@
2424
#ifndef MIP_HIGHS_MACHINE_SCHED_SEPARATOR_H_
2525
#define MIP_HIGHS_MACHINE_SCHED_SEPARATOR_H_
2626

27-
#include <unordered_map>
28-
2927
#include "mip/HighsMipSolver.h"
3028
#include "mip/HighsMipSolverData.h"
3129
#include "mip/HighsSeparator.h"

0 commit comments

Comments
 (0)