From a0ad88e0020787e69b41080af9d707db42aad924 Mon Sep 17 00:00:00 2001 From: Clemens Zeidler Date: Wed, 26 Jan 2011 22:06:02 +0000 Subject: [PATCH] Fix min/ max calculation by removing all soft constraints before doing so. Smaller fixes. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@40297 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- headers/libs/linprog/LinearSpec.h | 1 + headers/libs/linprog/Variable.h | 4 +++ src/libs/alm/Area.cpp | 7 ++--- src/libs/linprog/ActiveSetSolver.cpp | 40 +++++++++++++++++++++++++++- src/libs/linprog/ActiveSetSolver.h | 3 +++ src/libs/linprog/LayoutOptimizer.cpp | 1 - src/libs/linprog/LinearSpec.cpp | 23 +++++++++++++--- src/libs/linprog/Variable.cpp | 19 ++++++++++++- 8 files changed, 89 insertions(+), 9 deletions(-) diff --git a/headers/libs/linprog/LinearSpec.h b/headers/libs/linprog/LinearSpec.h index 7cc2db1d94..3d7ce5ab56 100644 --- a/headers/libs/linprog/LinearSpec.h +++ b/headers/libs/linprog/LinearSpec.h @@ -148,6 +148,7 @@ private: double penaltyNeg, double penaltyPos); VariableList fVariables; + VariableList fUsedVariables; ConstraintList fConstraints; ResultType fResult; bigtime_t fSolvingTime; diff --git a/headers/libs/linprog/Variable.h b/headers/libs/linprog/Variable.h index 6bb0ff2a5d..6be58a3a88 100644 --- a/headers/libs/linprog/Variable.h +++ b/headers/libs/linprog/Variable.h @@ -58,6 +58,9 @@ public: protected: Variable(LinearSpec* ls); + //! returns the ref count + int32 AddReference(); + int32 RemoveReference(); private: LinearSpec* fLS; @@ -68,6 +71,7 @@ private: bool fIsValid; + int32 fReferenceCount; public: friend class LinearSpec; }; diff --git a/src/libs/alm/Area.cpp b/src/libs/alm/Area.cpp index 4d3c2a6ede..05b50e9d3e 100644 --- a/src/libs/alm/Area.cpp +++ b/src/libs/alm/Area.cpp @@ -635,15 +635,16 @@ Area::_Init(LinearSpec* ls, XTab* left, YTab* top, XTab* right, YTab* bottom) fScaleHeight, kEQ, 0, fShrinkPenalties.Height(), fGrowPenalties.Height()); #else - BSize preferredSize = fLayoutItem->PreferredSize(); fPreferredContentWidth = fLS->AddConstraint(-1.0, fLeft, 1.0, fRight, kEQ, 0, fShrinkPenalties.Width(), fGrowPenalties.Width()); - _UpdatePreferredWidthConstraint(preferredSize); fPreferredContentHeight = fLS->AddConstraint(-1.0, fTop, 1.0, fBottom, kEQ, 0, fShrinkPenalties.Height(), fGrowPenalties.Height()); - _UpdatePreferredHeightConstraint(preferredSize); #endif + BSize preferredSize = fLayoutItem->PreferredSize(); + _UpdatePreferredWidthConstraint(preferredSize); + _UpdatePreferredHeightConstraint(preferredSize); + fConstraints.AddItem(fPreferredContentWidth); fConstraints.AddItem(fPreferredContentHeight); } diff --git a/src/libs/linprog/ActiveSetSolver.cpp b/src/libs/linprog/ActiveSetSolver.cpp index b75256e0ce..66e9d1f05a 100644 --- a/src/libs/linprog/ActiveSetSolver.cpp +++ b/src/libs/linprog/ActiveSetSolver.cpp @@ -504,6 +504,9 @@ ActiveSetSolver::SaveModel(const char* fileName) BSize ActiveSetSolver::MinSize(Variable* width, Variable* height) { + ConstraintList softConstraints; + _RemoveSoftConstraint(softConstraints); + Constraint* heightConstraint = fLinearSpec->AddConstraint(1, height, kEQ, 0, 5, 5); Constraint* widthConstraint = fLinearSpec->AddConstraint(1, width, @@ -512,6 +515,8 @@ ActiveSetSolver::MinSize(Variable* width, Variable* height) fLinearSpec->RemoveConstraint(heightConstraint); fLinearSpec->RemoveConstraint(widthConstraint); + _AddSoftConstraint(softConstraints); + if (result == kUnbounded) return kMinSize; if (result != kOptimal) @@ -524,6 +529,9 @@ ActiveSetSolver::MinSize(Variable* width, Variable* height) BSize ActiveSetSolver::MaxSize(Variable* width, Variable* height) { + ConstraintList softConstraints; + _RemoveSoftConstraint(softConstraints); + const double kHugeValue = 32000; Constraint* heightConstraint = fLinearSpec->AddConstraint(1, height, kEQ, kHugeValue, 5, 5); @@ -533,10 +541,40 @@ ActiveSetSolver::MaxSize(Variable* width, Variable* height) fLinearSpec->RemoveConstraint(heightConstraint); fLinearSpec->RemoveConstraint(widthConstraint); + _AddSoftConstraint(softConstraints); + if (result == kUnbounded) - return kMinSize; + return kMaxSize; if (result != kOptimal) printf("Could not solve the layout specification (%d). ", result); return BSize(width->Value(), height->Value()); } + + +void +ActiveSetSolver::_RemoveSoftConstraint(ConstraintList& list) +{ + ConstraintList allConstraints = fLinearSpec->Constraints(); + for (int i = 0; i < allConstraints.CountItems(); i++) { + Constraint* constraint = allConstraints.ItemAt(i); + if (!constraint->IsSoft()) + continue; + + if (fLinearSpec->RemoveConstraint(constraint, false) == true) + list.AddItem(constraint); + } +} + + +void +ActiveSetSolver::_AddSoftConstraint(const ConstraintList& list) +{ + for (int i = 0; i < list.CountItems(); i++) { + Constraint* constraint = list.ItemAt(i); + // at least don't leak it + if (fLinearSpec->AddConstraint(constraint) == false) + delete constraint; + } +} + diff --git a/src/libs/linprog/ActiveSetSolver.h b/src/libs/linprog/ActiveSetSolver.h index aee37b0319..3c0cc17bb3 100644 --- a/src/libs/linprog/ActiveSetSolver.h +++ b/src/libs/linprog/ActiveSetSolver.h @@ -71,6 +71,9 @@ public: BSize MaxSize(Variable* width, Variable* height); public: + void _RemoveSoftConstraint(ConstraintList& list); + void _AddSoftConstraint(const ConstraintList& list); + const VariableList& fVariables; const ConstraintList& fConstraints; diff --git a/src/libs/linprog/LayoutOptimizer.cpp b/src/libs/linprog/LayoutOptimizer.cpp index 1f36cad608..25b778ff22 100644 --- a/src/libs/linprog/LayoutOptimizer.cpp +++ b/src/libs/linprog/LayoutOptimizer.cpp @@ -914,7 +914,6 @@ LayoutOptimizer::_SolveSubProblem(const double* d, int am, double* p) negate_vector(pz, zn); // fTemp2 = Ztrans * G * Z - //multiply_optimization_matrix_matrix(Z, an, zn, fTemp1); multiply_matrices(fG, Z, fTemp1, zm, fVariableCount, zn); multiply_matrices(fZtrans, fTemp1, fTemp2, zn, zm, zn); diff --git a/src/libs/linprog/LinearSpec.cpp b/src/libs/linprog/LinearSpec.cpp index 74a819eed6..23de653112 100644 --- a/src/libs/linprog/LinearSpec.cpp +++ b/src/libs/linprog/LinearSpec.cpp @@ -149,7 +149,7 @@ LinearSpec::RemoveVariable(Variable* variable, bool deleteVariable) int32 LinearSpec::IndexOf(const Variable* variable) const { - return fVariables.IndexOf(variable); + return fUsedVariables.IndexOf(variable); } @@ -168,10 +168,20 @@ LinearSpec::AddConstraint(Constraint* constraint) if (!fConstraints.AddItem(constraint)) return false; + // ref count the used variables + SummandList* leftSide = constraint->LeftSide(); + for (int i = 0; i < leftSide->CountItems(); i++) { + Variable* var = leftSide->ItemAt(i)->Var(); + if (var->AddReference() == 1) + fUsedVariables.AddItem(var); + } + if (!fSolver->ConstraintAdded(constraint)) { - fConstraints.RemoveItem(constraint); + RemoveConstraint(constraint, false); return false; } + + constraint->fIsValid = true; return true; } @@ -183,6 +193,13 @@ LinearSpec::RemoveConstraint(Constraint* constraint, bool deleteConstraint) fConstraints.RemoveItem(constraint); constraint->fIsValid = false; + SummandList* leftSide = constraint->LeftSide(); + for (int i = 0; i < leftSide->CountItems(); i++) { + Variable* var = leftSide->ItemAt(i)->Var(); + if (var->RemoveReference() == 0) + fUsedVariables.RemoveItem(var); + } + if (deleteConstraint) delete constraint; return true; @@ -559,7 +576,7 @@ LinearSpec::Constraints() const const VariableList& LinearSpec::Variables() const { - return fVariables; + return fUsedVariables; } diff --git a/src/libs/linprog/Variable.cpp b/src/libs/linprog/Variable.cpp index 3419b273f1..f288112d45 100644 --- a/src/libs/linprog/Variable.cpp +++ b/src/libs/linprog/Variable.cpp @@ -295,12 +295,29 @@ Variable::Variable(LinearSpec* ls) fMin(-20000), fMax(20000), fLabel(NULL), - fIsValid(false) + fIsValid(false), + fReferenceCount(0) { } +int32 +Variable::AddReference() +{ + fReferenceCount++; + return fReferenceCount; +} + + +int32 +Variable::RemoveReference() +{ + fReferenceCount--; + return fReferenceCount; +} + + /** * Destructor. * Removes the variable from its specification.