Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
galabovaa committed Feb 21, 2025
1 parent 3caa540 commit 76f2b8a
Show file tree
Hide file tree
Showing 11 changed files with 155 additions and 69 deletions.
4 changes: 2 additions & 2 deletions src/mip/HighsCliqueTable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1086,8 +1086,8 @@ void HighsCliqueTable::extractCliquesFromCut(const HighsMipSolver& mipsolver,
double rhs) {
if (isFull()) return;

HighsImplications& implics = mipsolver.mipdata_->implications;
HighsDomain& globaldom = mipsolver.mipdata_->domain;
const HighsImplications& implics = mipsolver.mipdata_->implications;
const HighsDomain& globaldom = mipsolver.mipdata_->domain;

const double feastol = mipsolver.mipdata_->feastol;

Expand Down
2 changes: 1 addition & 1 deletion src/mip/HighsLpRelaxation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -846,7 +846,7 @@ bool HighsLpRelaxation::computeDualProof(const HighsDomain& globaldomain,

mipsolver.mipdata_->debugSolution.checkCut(inds.data(), vals.data(),
inds.size(), rhs);
if (extractCliques)
if (extractCliques && mipsolver.mipdata_->workers.size() <= 1)
mipsolver.mipdata_->cliquetable.extractCliquesFromCut(
mipsolver, inds.data(), vals.data(), inds.size(), rhs);

Expand Down
2 changes: 1 addition & 1 deletion src/mip/HighsMipSolver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -351,7 +351,7 @@ void HighsMipSolver::run() {
}

// sync goes with flush maybe
mipdata_->heuristics.flushStatistics();
mipdata_->heuristics.flushStatistics(master_worker);
analysis_.mipTimerStop(kMipClockPrimalHeuristics);
}
}
Expand Down
33 changes: 17 additions & 16 deletions src/mip/HighsMipSolverData.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,9 @@ HighsMipSolverData::HighsMipSolverData(HighsMipSolver& mipsolver)
pseudocost(),
cliquetable(mipsolver.numCol()),
implications(mipsolver),
heuristics_ptr(new HighsPrimalHeuristics(mipsolver)),
heuristics(*heuristics_ptr.get()),
// heuristics(mipsolver),
// heuristics_ptr(new HighsPrimalHeuristics(mipsolver)),
// heuristics(*heuristics_ptr.get()),
heuristics(mipsolver),
objectiveFunction(mipsolver),
presolve_status(HighsPresolveStatus::kNotSet),
cliquesExtracted(false),
Expand Down Expand Up @@ -88,6 +88,7 @@ HighsMipSolverData::HighsMipSolverData(HighsMipSolver& mipsolver)

// ig:here
// workers.emplace_back(std::move(HighsMipWorker(mipsolver, lp)));
workers.emplace_back(mipsolver, lp);

}

Expand Down Expand Up @@ -1781,7 +1782,7 @@ void HighsMipSolverData::printDisplayLine(const int solution_source) {
assert(!interrupt);
}

bool HighsMipSolverData::rootSeparationRound(
bool HighsMipSolverData::rootSeparationRound(HighsMipWorker& worker,
HighsSeparation& sepa, HighsInt& ncuts, HighsLpRelaxation::Status& status) {
int64_t tmpLpIters = -lp.getNumLpIterations();
ncuts = sepa.separationRound(domain, status);
Expand All @@ -1797,7 +1798,7 @@ bool HighsMipSolverData::rootSeparationRound(

if (mipsolver.submip || incumbent.empty()) {
heuristics.randomizedRounding(solvals);
heuristics.flushStatistics();
heuristics.flushStatistics(worker);
status = evaluateRootLp();
if (status == HighsLpRelaxation::Status::kInfeasible) return true;
}
Expand Down Expand Up @@ -2042,7 +2043,7 @@ void HighsMipSolverData::evaluateRootNode(HighsMipWorker& worker) {
mipsolver.analysis_.mipTimerStart(kMipClockRandomizedRounding1);
heuristics.randomizedRounding(firstlpsol);
mipsolver.analysis_.mipTimerStop(kMipClockRandomizedRounding1);
heuristics.flushStatistics();
heuristics.flushStatistics(worker);

mipsolver.analysis_.mipTimerStart(kMipClockEvaluateRootLp);
status = evaluateRootLp();
Expand Down Expand Up @@ -2120,7 +2121,7 @@ void HighsMipSolverData::evaluateRootNode(HighsMipWorker& worker) {

mipsolver.analysis_.mipTimerStart(kMipClockSeparationRootSeparationRound);
const bool root_separation_round_result =
rootSeparationRound(sepa, ncuts, status);
rootSeparationRound(worker, sepa, ncuts, status);
mipsolver.analysis_.mipTimerStop(kMipClockSeparationRootSeparationRound);
if (root_separation_round_result) {
mipsolver.analysis_.mipTimerStop(kMipClockSeparation);
Expand All @@ -2142,7 +2143,7 @@ void HighsMipSolverData::evaluateRootNode(HighsMipWorker& worker) {
heuristics.centralRounding();
mipsolver.analysis_.mipTimerStop(kMipClockSeparationCentralRounding);

heuristics.flushStatistics();
heuristics.flushStatistics(worker);

if (checkLimits()) {
mipsolver.analysis_.mipTimerStop(kMipClockSeparation);
Expand Down Expand Up @@ -2233,7 +2234,7 @@ void HighsMipSolverData::evaluateRootNode(HighsMipWorker& worker) {
heuristics.centralRounding();
mipsolver.analysis_.mipTimerStop(kMipClockCentralRounding);

heuristics.flushStatistics();
heuristics.flushStatistics(worker);

// if there are new global bound changes we reevaluate the LP and do one
// more separation round
Expand All @@ -2245,7 +2246,7 @@ void HighsMipSolverData::evaluateRootNode(HighsMipWorker& worker) {
HighsInt ncuts;
mipsolver.analysis_.mipTimerStart(kMipClockRootSeparationRound);
const bool root_separation_round_result =
rootSeparationRound(sepa, ncuts, status);
rootSeparationRound(worker, sepa, ncuts, status);
mipsolver.analysis_.mipTimerStop(kMipClockRootSeparationRound);
if (root_separation_round_result) return;
++nseparounds;
Expand All @@ -2265,7 +2266,7 @@ void HighsMipSolverData::evaluateRootNode(HighsMipWorker& worker) {
if (upper_limit != kHighsInf && !moreHeuristicsAllowed()) break;

heuristics.rootReducedCost();
heuristics.flushStatistics();
heuristics.flushStatistics(worker);

if (checkLimits()) return;

Expand All @@ -2276,7 +2277,7 @@ void HighsMipSolverData::evaluateRootNode(HighsMipWorker& worker) {
if (status == HighsLpRelaxation::Status::kInfeasible) return;
if (separate && lp.scaledOptimal(status)) {
HighsInt ncuts;
if (rootSeparationRound(sepa, ncuts, status)) return;
if (rootSeparationRound(worker, sepa, ncuts, status)) return;

++nseparounds;
printDisplayLine();
Expand All @@ -2286,7 +2287,7 @@ void HighsMipSolverData::evaluateRootNode(HighsMipWorker& worker) {

if (checkLimits()) return;
heuristics.RENS(worker, rootlpsol);
heuristics.flushStatistics();
heuristics.flushStatistics(worker);

if (checkLimits()) return;
// if there are new global bound changes we reevaluate the LP and do one
Expand All @@ -2296,7 +2297,7 @@ void HighsMipSolverData::evaluateRootNode(HighsMipWorker& worker) {
if (status == HighsLpRelaxation::Status::kInfeasible) return;
if (separate && lp.scaledOptimal(status)) {
HighsInt ncuts;
if (rootSeparationRound(sepa, ncuts, status)) return;
if (rootSeparationRound(worker, sepa, ncuts, status)) return;

++nseparounds;

Expand All @@ -2307,7 +2308,7 @@ void HighsMipSolverData::evaluateRootNode(HighsMipWorker& worker) {

if (checkLimits()) return;
heuristics.feasibilityPump();
heuristics.flushStatistics();
heuristics.flushStatistics(worker);

if (checkLimits()) return;
status = evaluateRootLp();
Expand All @@ -2329,7 +2330,7 @@ void HighsMipSolverData::evaluateRootNode(HighsMipWorker& worker) {
if (status == HighsLpRelaxation::Status::kInfeasible) return;
if (separate && lp.scaledOptimal(status)) {
HighsInt ncuts;
if (rootSeparationRound(sepa, ncuts, status)) return;
if (rootSeparationRound(worker, sepa, ncuts, status)) return;

++nseparounds;
printDisplayLine();
Expand Down
6 changes: 4 additions & 2 deletions src/mip/HighsMipSolverData.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ enum MipSolutionSource : int {

struct HighsMipSolverData {
HighsMipSolver& mipsolver;

HighsCutPool cutpool;
HighsConflictPool conflictPool;
HighsDomain domain;
Expand All @@ -78,7 +79,8 @@ struct HighsMipSolverData {

HighsLpRelaxation& lp;

std::unique_ptr<HighsPrimalHeuristics> heuristics_ptr;
// std::unique_ptr<HighsPrimalHeuristics> heuristics_ptr;
// HighsPrimalHeuristics heuristics;
HighsPrimalHeuristics heuristics;

HighsPseudocost pseudocost;
Expand Down Expand Up @@ -211,7 +213,7 @@ struct HighsMipSolverData {
bool checkSolution(const std::vector<double>& solution) const;
bool trySolution(const std::vector<double>& solution,
const int solution_source = kSolutionSourceNone);
bool rootSeparationRound(HighsSeparation& sepa, HighsInt& ncuts,
bool rootSeparationRound(HighsMipWorker& worker, HighsSeparation& sepa, HighsInt& ncuts,
HighsLpRelaxation::Status& status);
HighsLpRelaxation::Status evaluateRootLp();

Expand Down
62 changes: 57 additions & 5 deletions src/mip/HighsMipWorker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@ HighsMipWorker::HighsMipWorker(const HighsMipSolver& mipsolver__,
: mipsolver_(mipsolver__),
mipdata_(*mipsolver_.mipdata_.get()),
lprelaxation_(lprelax_),
cutpool_(mipsolver__.numCol(),
mipsolver__.options_mip_->mip_pool_age_limit,
mipsolver__.options_mip_->mip_pool_soft_limit),
conflictpool_(5 * mipsolver__.options_mip_->mip_pool_age_limit,
mipsolver__.options_mip_->mip_pool_soft_limit),
cutpool_(mipsolver_.numCol(),
mipsolver_.options_mip_->mip_pool_age_limit,
mipsolver_.options_mip_->mip_pool_soft_limit),
conflictpool_(5 * mipsolver_.options_mip_->mip_pool_age_limit,
mipsolver_.options_mip_->mip_pool_soft_limit),
// cliquetable_(mipsolver__.numCol()),
pseudocost_(mipsolver__),
pscostinit_(pseudocost_, 1),
Expand Down Expand Up @@ -62,6 +62,58 @@ HighsMipWorker::HighsMipWorker(const HighsMipSolver& mipsolver__,
int(search_ptr_->lp->getLpSolver().getNumRow()));
}

// HighsMipWorker::HighsMipWorker(const HighsMipWorker& worker)
// : mipsolver_(worker.mipsolver_),
// mipdata_(worker.mipdata_),
// lprelaxation_(worker.lprelaxation_),
// cutpool_(mipsolver_.numCol(),
// mipsolver_.options_mip_->mip_pool_age_limit,
// mipsolver_.options_mip_->mip_pool_soft_limit),
// conflictpool_(5 * mipsolver_.options_mip_->mip_pool_age_limit,
// mipsolver_.options_mip_->mip_pool_soft_limit),
// // cliquetable_(mipsolver__.numCol()),
// pseudocost_(mipsolver_),
// pscostinit_(pseudocost_, 1),
// // clqtableinit_(mipsolver_.numCol()),
// implicinit_(mipsolver_),
// pscostinit(pscostinit_),
// implicinit(implicinit_)
// // clqtableinit(clqtableinit_)
// {

// search_ptr_ =
// std::unique_ptr<HighsSearch>(new HighsSearch(*this, pseudocost_));

// // Register cutpool and conflict pool in local search domain.
// // Add global cutpool.
// search_ptr_->getLocalDomain().addCutpool(mipsolver_.mipdata_->cutpool);
// search_ptr_->getLocalDomain().addConflictPool(
// mipsolver_.mipdata_->conflictPool);

// // cutpool_.matrix_.AheadNeg_.assign(mipsolver__.numCol(), -1);
// // cutpool_.matrix_.AheadPos_.assign(mipsolver__.numCol(), -1);

// // std::vector<HighsInt> AheadPos_;
// // std::vector<HighsInt> AheadNeg_;

// // add local cutpool
// search_ptr_->getLocalDomain().addCutpool(cutpool_);
// search_ptr_->getLocalDomain().addConflictPool(conflictpool_);
// search_ptr_->setLpRelaxation(&lprelaxation_);

// printf(
// "lprelaxation_ address in constructor of mipworker %p, %d columns, and "
// "%d rows\n",
// (void*)&lprelaxation_, int(lprelaxation_.getLpSolver().getNumCol()),
// int(lprelaxation_.getLpSolver().getNumRow()));

// printf(
// "Search has lp member in constructor of mipworker with address %p, %d "
// "columns, and %d rows\n",
// (void*)&search_ptr_->lp, int(search_ptr_->lp->getLpSolver().getNumCol()),
// int(search_ptr_->lp->getLpSolver().getNumRow()));
// }

// HighsMipWorker::~HighsMipWorker() {
// delete search_ptr;
// };
Expand Down
23 changes: 13 additions & 10 deletions src/mip/HighsMipWorker.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ class HighsMipWorker {

// HighsMipWorker(const HighsMipSolver& mipsolver__);
HighsMipWorker(const HighsMipSolver& mipsolver__, const HighsLpRelaxation& lprelax_);

// HighsMipWorker(const HighsMipWorker& mipworker);

const HighsMipSolver& getMipSolver();

Expand All @@ -49,17 +51,10 @@ class HighsMipWorker {
HighsConflictPool conflictpool_;

// members for worker threads.
HighsPseudocostInitialization pscostinit_;
HighsPseudocost pscost_;
// HighsCliqueTable clqtableinit_;
HighsImplications implicinit_;

// References to members, initialized to local objects for worker threads,
// modify to mip solver for main worker.
HighsPseudocostInitialization& pscostinit;
// HighsCliqueTable& clqtableinit;
HighsImplications& implicinit;
/// HighsImplications implicinit_;

// Solution information.
struct Solution {
double row_violation_;
double bound_violation_;
Expand All @@ -73,9 +68,17 @@ class HighsMipWorker {
// ... implement necessary methods for HighsSearch

~HighsMipWorker() {
search_ptr_.release();
// search_ptr_.release();
search_ptr_.reset();
}

HighsPrimalHeuristics::Statistics heur_stats;

// todo:
// timer_
// sync too
// or name times differently for workers in the same timer instance in mipsolver.

};

#endif
34 changes: 15 additions & 19 deletions src/mip/HighsPrimalHeuristics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,16 +33,12 @@
#endif

HighsPrimalHeuristics::HighsPrimalHeuristics(HighsMipSolver& mipsolver)
: mipsolver(mipsolver),
total_repair_lp(0),
total_repair_lp_feasible(0),
total_repair_lp_iterations(0),
lp_iterations(0),
randgen(mipsolver.options_mip_->random_seed) {
successObservations = 0;
numSuccessObservations = 0;
infeasObservations = 0;
numInfeasObservations = 0;
// HighsPrimalHeuristics::HighsPrimalHeuristics(HighsMipWorker& mipworker)
// : mipworker(mipworker),
// mipsolver(mipworker.mipsolver_),
: mipsolver(mipsolver)
{

}

void HighsPrimalHeuristics::setupIntCols() {
Expand Down Expand Up @@ -155,19 +151,19 @@ bool HighsPrimalHeuristics::solveSubMip(
// (double)mipsolver.orig_model_->a_matrix_.value_.size();
int64_t adjusted_lp_iterations =
(size_t)(adjustmentfactor * submipsolver.mipdata_->total_lp_iterations);
lp_iterations += adjusted_lp_iterations;
total_repair_lp += submipsolver.mipdata_->total_repair_lp;
total_repair_lp_feasible += submipsolver.mipdata_->total_repair_lp_feasible;
total_repair_lp_iterations +=
worker.heur_stats.lp_iterations += adjusted_lp_iterations;
worker.heur_stats.total_repair_lp += submipsolver.mipdata_->total_repair_lp;
worker.heur_stats.total_repair_lp_feasible += submipsolver.mipdata_->total_repair_lp_feasible;
worker.heur_stats.total_repair_lp_iterations +=
submipsolver.mipdata_->total_repair_lp_iterations;
if (mipsolver.submip)
mipsolver.mipdata_->num_nodes += std::max(
int64_t{1}, int64_t(adjustmentfactor * submipsolver.node_count_));
}

if (submipsolver.modelstatus_ == HighsModelStatus::kInfeasible) {
infeasObservations += fixingRate;
++numInfeasObservations;
worker.heur_stats.infeasObservations += fixingRate;
++worker.heur_stats.numInfeasObservations;
}
if (submipsolver.node_count_ <= 1 &&
submipsolver.modelstatus_ == HighsModelStatus::kInfeasible)
Expand All @@ -181,8 +177,8 @@ bool HighsPrimalHeuristics::solveSubMip(

if (mipsolver.mipdata_->numImprovingSols != oldNumImprovingSols) {
// remember fixing rate as good
successObservations += fixingRate;
++numSuccessObservations;
worker.heur_stats.successObservations += fixingRate;
++worker.heur_stats.numSuccessObservations;
}

return true;
Expand Down Expand Up @@ -1243,7 +1239,7 @@ void HighsPrimalHeuristics::clique() {
}
#endif

void HighsPrimalHeuristics::flushStatistics() {
void HighsPrimalHeuristics::flushStatistics(HighsMipWorker& mipworker) {
mipsolver.mipdata_->total_repair_lp += total_repair_lp;
mipsolver.mipdata_->total_repair_lp_feasible += total_repair_lp_feasible;
mipsolver.mipdata_->total_repair_lp_iterations += total_repair_lp_iterations;
Expand Down
Loading

0 comments on commit 76f2b8a

Please sign in to comment.