Skip to content

Commit 1ef2295

Browse files
committed
Thread-safety fix from PR review
1 parent ebb406a commit 1ef2295

File tree

2 files changed

+27
-18
lines changed

2 files changed

+27
-18
lines changed

highs/mip/HighsFeasibilityJump.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,11 @@ HighsModelStatus HighsMipSolverData::feasibilityJump() {
2828
double objective_function_value;
2929

3030
// Configure Feasibility Jump and pass it the problem
31-
external_feasibilityjump::equalityTolerance = epsilon;
32-
external_feasibilityjump::violationTolerance = feastol;
33-
3431
int verbosity = mipsolver.submip ? 0 : mipsolver.options_mip_->log_dev_level;
3532
auto solver = external_feasibilityjump::FeasibilityJumpSolver(
36-
/* seed = */ 0, /* verbosity = */ verbosity);
33+
/* seed = */ 0, /* verbosity = */ verbosity,
34+
/* equalityTolerance = */ epsilon,
35+
/* violationTolerance = */ feastol);
3736

3837
for (HighsInt col = 0; col < model->num_col_; ++col) {
3938
double lower = model->col_lower_[col];

highs/mip/feasibilityjump.hh

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,8 @@ struct FJStatus {
3333
double* solution;
3434
};
3535

36-
double violationTolerance = 1.0e-5;
37-
double equalityTolerance = 1.0e-5;
38-
39-
// Measures if two doubles are equal within a tolerance of 1.0e-5.
40-
bool eq(double a, double b) { return fabs(a - b) < equalityTolerance; }
36+
// Measures if two doubles are equal within a tolerance
37+
bool eq(double a, double b, double tol) { return fabs(a - b) < tol; }
4138

4239
struct IdxCoeff {
4340
uint32_t idx;
@@ -102,7 +99,14 @@ struct LhsModification {
10299
// Stores the MIP problem, an incumbent assignment, and the set of constraints
103100
// that are violated in the current incumbent assignment. This set is maintained
104101
// when changes are given to the incumbent assignment using `setValue`.
105-
struct Problem {
102+
class Problem {
103+
const double equalityTolerance;
104+
const double violationTolerance;
105+
106+
public:
107+
Problem(double equalityTolerance, double violationTolerance)
108+
: equalityTolerance(equalityTolerance),
109+
violationTolerance(violationTolerance) {}
106110
std::vector<Var> vars;
107111
std::vector<Constraint> constraints;
108112
std::vector<double> incumbentAssignment;
@@ -168,7 +172,7 @@ struct Problem {
168172
else if (sense == RowType::Gte)
169173
ok = 0 + equalityTolerance >= rhs;
170174
else
171-
ok = eq(0, rhs);
175+
ok = eq(0, rhs, equalityTolerance);
172176

173177
return ok ? INT_MAX : INT_MIN;
174178
}
@@ -297,10 +301,12 @@ void modifyMove(LhsModification mod, Problem& problem, Move& move) {
297301
// Stores current moves and computes updated jump values for
298302
// the "Jump" move type.
299303
class JumpMove {
304+
const double equalityTolerance;
300305
std::vector<Move> moves;
301306
std::vector<std::pair<double, double>> bestShiftBuffer;
302307

303308
public:
309+
JumpMove(double equalityTolerance) : equalityTolerance(equalityTolerance) {}
304310
void init(Problem& problem) { moves.resize(problem.vars.size()); }
305311

306312
template <typename F>
@@ -396,16 +402,19 @@ class JumpMove {
396402
// %g\n", currentScore,currentSlope, currentValue, bestScore, bestValue
397403
// );
398404

399-
if (eq(bestValue, varIncumbentValue) ||
400-
(!eq(currentValue, varIncumbentValue) && currentScore < bestScore)) {
405+
if (eq(bestValue, varIncumbentValue, equalityTolerance) ||
406+
(!eq(currentValue, varIncumbentValue, equalityTolerance) &&
407+
currentScore < bestScore)) {
401408
bestScore = currentScore;
402409
bestValue = currentValue;
403410
}
404411

405412
// Slope is always increasing, so if we have a valid value, we can quit
406413
// as soon as the slope turns nonnegative, since we must already have
407414
// visited the minimum.
408-
if (!eq(bestValue, varIncumbentValue) && currentSlope >= 0.) break;
415+
if (!eq(bestValue, varIncumbentValue, equalityTolerance) &&
416+
currentSlope >= 0.)
417+
break;
409418
}
410419

411420
// printf("Setting jump for %d to from %g to %g\n", varIdx,
@@ -458,7 +467,11 @@ class FeasibilityJumpSolver {
458467

459468
public:
460469
FeasibilityJumpSolver(int seed = 0, int _verbosity = 0,
461-
double _weightUpdateDecay = 1.0) {
470+
double _weightUpdateDecay = 1.0,
471+
double equalityTolerance = 1e-5,
472+
double violationTolerance = 1e-5)
473+
: problem(equalityTolerance, violationTolerance),
474+
jumpMove(equalityTolerance) {
462475
verbosity = _verbosity;
463476
weightUpdateDecay = _weightUpdateDecay;
464477
rng = std::mt19937(seed);
@@ -572,10 +585,7 @@ class FeasibilityJumpSolver {
572585
for (size_t i = 0; i < sampleSize; i++) {
573586
auto setidx = rng() % goodVarsSet.size();
574587
auto varIdx = goodVarsSet[setidx];
575-
// assert(goodVarsSetIdx[varIdx] >= 0 && goodVarsSetIdx[varIdx] ==
576-
// setidx);
577588
Move move = bestMove(varIdx);
578-
// assert(move.score > equalityTolerance);
579589
if (move.score > bestScore) {
580590
bestScore = move.score;
581591
bestVar = varIdx;

0 commit comments

Comments
 (0)