Skip to content

Commit

Permalink
Push finished LBs back for reevaluation
Browse files Browse the repository at this point in the history
  • Loading branch information
sebrockm committed Oct 14, 2023
1 parent 44bce02 commit 3c29d86
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 7 deletions.
34 changes: 30 additions & 4 deletions tsplp/src/BranchAndCutQueue.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,29 @@ void tsplp::BranchAndCutQueue::UpdateCurrentLowerBound(size_t threadId, double c
m_workedOnLowerBounds.at(threadId) = currentLowerBound;
}

void tsplp::BranchAndCutQueue::PushResult(double lowerBound)
{
bool needsNotify = false;

{
std::unique_lock lock { m_mutex };

if (m_isCleared)
return;

if (lowerBound < CalculateLowerBound())
throw std::logic_error("cannot push smaller lower bound");

needsNotify = m_heap.empty() && m_workedOnCount > 0;

m_heap.push_back({ lowerBound, {}, {}, true });
std::push_heap(begin(m_heap), end(m_heap), m_comparer);
}

if (needsNotify)
m_cv.notify_one();
}

void tsplp::BranchAndCutQueue::Push(
double lowerBound, std::vector<Variable> fixedVariables0, std::vector<Variable> fixedVariables1)
{
Expand All @@ -82,7 +105,8 @@ void tsplp::BranchAndCutQueue::Push(

needsNotify = m_heap.empty() && m_workedOnCount > 0;

m_heap.push_back({ lowerBound, std::move(fixedVariables0), std::move(fixedVariables1) });
m_heap.push_back(
{ lowerBound, std::move(fixedVariables0), std::move(fixedVariables1), false });
std::push_heap(begin(m_heap), end(m_heap), m_comparer);
}

Expand Down Expand Up @@ -116,11 +140,12 @@ void tsplp::BranchAndCutQueue::PushBranch(
copyFixedVariables0.insert(
copyFixedVariables0.end(), recursivelyFixed0.begin(), recursivelyFixed0.end());

m_heap.push_back({ lowerBound, std::move(fixedVariables0), std::move(fixedVariables1) });
m_heap.push_back(
{ lowerBound, std::move(fixedVariables0), std::move(fixedVariables1), false });
std::push_heap(begin(m_heap), end(m_heap), m_comparer);

m_heap.push_back(
{ lowerBound, std::move(copyFixedVariables0), std::move(copyFixedVariables1) });
{ lowerBound, std::move(copyFixedVariables0), std::move(copyFixedVariables1), false });
std::push_heap(begin(m_heap), end(m_heap), m_comparer);
}

Expand Down Expand Up @@ -173,14 +198,15 @@ void tsplp::BranchAndCutQueue::Print() const
std::unique_lock lock { m_mutex };

std::cout << "BranchAndCutQueue:\nHeap:";
for (const auto& [lb, v0, v1] : m_heap)
for (const auto& [lb, v0, v1, r] : m_heap)
{
std::cout << "LB:" << lb << ", v0:";
for (const auto& v : v0)
std::cout << v.GetId() << ",";
std::cout << " v1:";
for (const auto& v : v1)
std::cout << v.GetId() << ",";
std::cout << " is result: " << r;
std::cout << std::endl;
}

Expand Down
2 changes: 2 additions & 0 deletions tsplp/src/BranchAndCutQueue.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ struct SData
double LowerBound = -std::numeric_limits<double>::max();
std::vector<Variable> FixedVariables0 {};
std::vector<Variable> FixedVariables1 {};
bool IsResult = false;
bool operator>(SData const& sd) const { return LowerBound > sd.LowerBound; }
};

Expand Down Expand Up @@ -67,6 +68,7 @@ class BranchAndCutQueue

void ClearAll();
void UpdateCurrentLowerBound(size_t threadId, double currentLowerBound);
void PushResult(double lowerBound);
void Push(
double lowerBound, std::vector<Variable> fixedVariables0,
std::vector<Variable> fixedVariables1);
Expand Down
19 changes: 16 additions & 3 deletions tsplp/src/MtspModel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,20 @@ void tsplp::MtspModel::BranchAndCutSolve(

auto& [sdata, nodeDoneNotifier] = *top;

if (sdata.IsResult)
{
const auto globalLowerBound
= m_bestResult.UpdateLowerBound(queue.GetLowerBound()).Lower;
if (sdata.LowerBound > globalLowerBound)
{
// As this was just popped but is not the global LB, this means other threads
// are currently working on smaller LBs. Push it back to be reevaluated later.
queue.PushResult(sdata.LowerBound);
}

continue;
}

fixedVariables0 = std::move(sdata.FixedVariables0);
fixedVariables1 = std::move(sdata.FixedVariables1);

Expand Down Expand Up @@ -414,6 +428,7 @@ void tsplp::MtspModel::BranchAndCutSolve(
<< ": currentLowerBound=" << currentLowerBound
<< " >= currentUpperBound=" << currentUpperBound << " skipping"
<< std::endl;
queue.PushResult(currentLowerBound);
continue;
}

Expand Down Expand Up @@ -492,14 +507,12 @@ void tsplp::MtspModel::BranchAndCutSolve(
currentLowerBound, CreatePathsFromVariables(model));
}

// make sure the this lower bound is set if it is the global one
m_bestResult.UpdateLowerBound(queue.GetLowerBound());

{
std::unique_lock lock { print_mutex };
std::cout << m_name << ", thread " << threadId
<< ": non-fractional solution found: " << currentLowerBound
<< std::endl;
queue.PushResult(currentLowerBound);
continue;
}
}
Expand Down

0 comments on commit 3c29d86

Please sign in to comment.