store variables per subproblem

This commit is contained in:
chriseth 2022-03-23 23:45:09 +01:00
parent 4235933124
commit 5993cfa732
2 changed files with 23 additions and 16 deletions

View File

@ -817,11 +817,14 @@ LPResult LPSolver::setState(SolvingState _state)
while (splitter) while (splitter)
{ {
auto&& [variables, constraints] = splitter.next(); auto&& [variables, constraints] = splitter.next();
m_subProblems.emplace_back(SubProblem()); SubProblem& problem = *m_subProblems.emplace_back(SubProblem());
solAssert(m_subProblems.back()->dirty); solAssert(problem.dirty);
for (auto&& [i, included]: variables | ranges::views::enumerate) for (auto&& [i, included]: variables | ranges::views::enumerate)
if (included) if (included)
{
m_subProblemsPerVariable[i] = m_subProblems.size() - 1; m_subProblemsPerVariable[i] = m_subProblems.size() - 1;
problem.variables.emplace(i);
}
for (auto&& [i, included]: constraints | ranges::views::enumerate) for (auto&& [i, included]: constraints | ranges::views::enumerate)
if (included) if (included)
m_subProblemsPerConstraint[i] = m_subProblems.size() - 1; m_subProblemsPerConstraint[i] = m_subProblems.size() - 1;
@ -933,20 +936,23 @@ void LPSolver::combineSubProblems(size_t _combineInto, size_t _combineFrom)
for (size_t& item: m_subProblemsPerConstraint) for (size_t& item: m_subProblemsPerConstraint)
if (item == _combineFrom) if (item == _combineFrom)
item = _combineInto; item = _combineInto;
m_subProblems[_combineInto]->variables += move(m_subProblems[_combineFrom]->variables);
m_subProblems[_combineFrom].reset(); m_subProblems[_combineFrom].reset();
} }
void LPSolver::addConstraintToSubProblem(size_t _subProblem, Constraint _constraint) void LPSolver::addConstraintToSubProblem(size_t _subProblem, Constraint _constraint)
{ {
SubProblem& problem = *m_subProblems[_subProblem];
for (auto const& [index, entry]: _constraint.data.enumerateTail()) for (auto const& [index, entry]: _constraint.data.enumerateTail())
if (entry) if (entry)
{ {
solAssert(m_subProblemsPerVariable[index] == static_cast<size_t>(-1) || m_subProblemsPerVariable[index] == _subProblem); solAssert(m_subProblemsPerVariable[index] == static_cast<size_t>(-1) || m_subProblemsPerVariable[index] == _subProblem);
m_subProblemsPerVariable[index] = _subProblem; m_subProblemsPerVariable[index] = _subProblem;
problem.variables.emplace(index);
} }
m_subProblems[_subProblem]->dirty = true; problem.dirty = true;
m_subProblems[_subProblem]->removableConstraints.emplace_back(move(_constraint)); problem.removableConstraints.emplace_back(move(_constraint));
} }
SolvingState LPSolver::stateFromSubProblem(size_t _index) const SolvingState LPSolver::stateFromSubProblem(size_t _index) const
@ -956,29 +962,29 @@ SolvingState LPSolver::stateFromSubProblem(size_t _index) const
split.variableNames.emplace_back(); split.variableNames.emplace_back();
split.bounds.emplace_back(); split.bounds.emplace_back();
for (auto&& item: m_subProblemsPerVariable | ranges::views::enumerate) SubProblem const& problem = *m_subProblems[_index];
if (item.second == _index) for (size_t varIndex: problem.variables)
{ {
split.variableNames.emplace_back(m_state.variableNames[item.first]); split.variableNames.emplace_back(m_state.variableNames[varIndex]);
split.bounds.emplace_back(m_state.bounds[item.first]); split.bounds.emplace_back(m_state.bounds[varIndex]);
} }
for (auto&& item: m_subProblemsPerConstraint | ranges::views::enumerate) for (auto&& item: m_subProblemsPerConstraint | ranges::views::enumerate)
if (item.second == _index) if (item.second == _index)
{ {
Constraint const& constraint = m_state.constraints[item.first]; Constraint const& constraint = m_state.constraints[item.first];
Constraint splitRow{{}, constraint.equality, constraint.reasons}; Constraint splitRow{{}, constraint.equality, constraint.reasons};
for (size_t j = 0; j < constraint.data.size(); j++) splitRow.data.push_back(constraint.data.get(0));
if (j == 0 || m_subProblemsPerVariable[j] == _index) for (size_t varIndex: problem.variables)
splitRow.data.push_back(constraint.data[j]); splitRow.data.push_back(constraint.data.get(varIndex));
split.constraints.push_back(move(splitRow)); split.constraints.push_back(move(splitRow));
} }
for (Constraint const& constraint: m_subProblems[_index]->removableConstraints) for (Constraint const& constraint: m_subProblems[_index]->removableConstraints)
{ {
Constraint splitRow{{}, constraint.equality, constraint.reasons}; Constraint splitRow{{}, constraint.equality, constraint.reasons};
for (size_t j = 0; j < constraint.data.size(); j++) splitRow.data.push_back(constraint.data.get(0));
if (j == 0 || m_subProblemsPerVariable[j] == _index) for (size_t varIndex: problem.variables)
splitRow.data.push_back(constraint.data[j]); splitRow.data.push_back(constraint.data.get(varIndex));
split.constraints.push_back(move(splitRow)); split.constraints.push_back(move(splitRow));
} }

View File

@ -197,6 +197,7 @@ private:
bool dirty = true; bool dirty = true;
LPResult result = LPResult::Unknown; LPResult result = LPResult::Unknown;
std::vector<boost::rational<bigint>> model = {}; std::vector<boost::rational<bigint>> model = {};
std::set<size_t> variables = {};
}; };
SolvingState stateFromSubProblem(size_t _index) const; SolvingState stateFromSubProblem(size_t _index) const;