bool LPSolveInterface::LeftSideChanged(Constraint* constraint) { if (!constraint->IsValid()) return false; int32 index = constraint->Index() + 1; if (index <= 0) return false; SummandList* leftSide = constraint->LeftSide(); OperatorType op = constraint->Op(); double coeffs[leftSide->CountItems() + 2]; int variableIndices[leftSide->CountItems() + 2]; int32 i; for (i = 0; i < leftSide->CountItems(); i++) { Summand* s = leftSide->ItemAt(i); coeffs[i] = s->Coeff(); variableIndices[i] = s->Var()->GlobalIndex() + 1; } double penaltyNeg = constraint->PenaltyNeg(); if (penaltyNeg > 0. && op != kLE) { if (!constraint->fDNegObjSummand) { constraint->fDNegObjSummand = new(std::nothrow) Summand( constraint->PenaltyNeg(), fLinearSpec->AddVariable()); fObjFunction->AddItem(constraint->fDNegObjSummand); } variableIndices[i] = constraint->fDNegObjSummand->Var()->GlobalIndex() + 1; coeffs[i] = 1.0; i++; } else { fObjFunction->RemoveItem(constraint->fDNegObjSummand); delete constraint->fDNegObjSummand; constraint->fDNegObjSummand = NULL; } double penaltyPos = constraint->PenaltyPos(); if (penaltyPos > 0. && op != kGE) { if (constraint->fDPosObjSummand == NULL) { constraint->fDPosObjSummand = new(std::nothrow) Summand(penaltyPos, fLinearSpec->AddVariable()); fObjFunction->AddItem(constraint->fDPosObjSummand); } variableIndices[i] = constraint->fDPosObjSummand->Var()->GlobalIndex() + 1; coeffs[i] = -1.0; i++; } else { fObjFunction->RemoveItem(constraint->fDPosObjSummand); delete constraint->fDPosObjSummand; constraint->fDPosObjSummand = NULL; } if (!set_rowex(fLP, index, i, coeffs, variableIndices)) return false; _UpdateObjectiveFunction(); _RemovePresolved(); return true; }
bool LayoutOptimizer::SetConstraints(const ConstraintList& list, int32 variableCount) { fConstraints = (ConstraintList*)&list; int32 constraintCount = fConstraints->CountItems(); if (fVariableCount != variableCount) { _MakeEmpty(); _Init(variableCount, constraintCount); } zero_matrix(fSoftConstraints, constraintCount, fVariableCount); double rightSide[constraintCount]; // set up soft constraint matrix for (int32 c = 0; c < fConstraints->CountItems(); c++) { Constraint* constraint = fConstraints->ItemAt(c); if (!constraint->IsSoft()) { rightSide[c] = 0; continue; } double weight = 0; double negPenalty = constraint->PenaltyNeg(); if (negPenalty > 0) weight += negPenalty; double posPenalty = constraint->PenaltyPos(); if (posPenalty > 0) weight += posPenalty; if (negPenalty > 0 && posPenalty > 0) weight /= 2; rightSide[c] = _RightSide(constraint) * weight; SummandList* summands = constraint->LeftSide(); for (int32 s = 0; s < summands->CountItems(); s++) { Summand* summand = summands->ItemAt(s); int32 variable = summand->Var()->Index(); if (constraint->Op() == LinearProgramming::kLE) fSoftConstraints[c][variable] = -summand->Coeff(); else fSoftConstraints[c][variable] = summand->Coeff(); fSoftConstraints[c][variable] *= weight; } } // create G transpose_matrix(fSoftConstraints, fTemp1, constraintCount, fVariableCount); multiply_matrices(fTemp1, fSoftConstraints, fG, fVariableCount, constraintCount, fVariableCount); // create d multiply_matrix_vector(fTemp1, rightSide, fVariableCount, constraintCount, fDesired); negate_vector(fDesired, fVariableCount); return true; }
double LayoutOptimizer::_ActualValue(Constraint* constraint, double* values) const { SummandList* summands = constraint->LeftSide(); double value = 0; for (int32 s = 0; s < summands->CountItems(); s++) { Summand* summand = summands->ItemAt(s); int32 variable = summand->Var()->Index(); value += values[variable] * summand->Coeff(); } if (constraint->Op() == LinearProgramming::kLE) return -value; return value; }
bool LPSolveInterface::ConstraintAdded(Constraint* constraint) { OperatorType op = constraint->Op(); SummandList* summands = constraint->LeftSide(); double coeffs[summands->CountItems() + 2]; int variableIndices[summands->CountItems() + 2]; int32 nCoefficient = 0; for (; nCoefficient < summands->CountItems(); nCoefficient++) { Summand* s = summands->ItemAt(nCoefficient); coeffs[nCoefficient] = s->Coeff(); variableIndices[nCoefficient] = s->Var()->GlobalIndex() + 1; } double penaltyNeg = constraint->PenaltyNeg(); if (penaltyNeg > 0. && op != kLE) { constraint->fDNegObjSummand = new(std::nothrow) Summand( constraint->PenaltyNeg(), fLinearSpec->AddVariable()); fObjFunction->AddItem(constraint->fDNegObjSummand); variableIndices[nCoefficient] = constraint->fDNegObjSummand->Var()->GlobalIndex() + 1; coeffs[nCoefficient] = 1.0; nCoefficient++; } double penaltyPos = constraint->PenaltyPos(); if (penaltyPos > 0. && op != kGE) { constraint->fDPosObjSummand = new(std::nothrow) Summand( constraint->PenaltyPos(), fLinearSpec->AddVariable()); fObjFunction->AddItem(constraint->fDPosObjSummand); variableIndices[nCoefficient] = constraint->fDPosObjSummand->Var()->GlobalIndex() + 1; coeffs[nCoefficient] = -1.0; nCoefficient++; } double rightSide = constraint->RightSide(); if (!add_constraintex(fLP, nCoefficient, coeffs, variableIndices, (op == kEQ ? EQ : (op == kGE) ? GE : LE), rightSide)) { return false; } _UpdateObjectiveFunction(); _RemovePresolved(); return true; }
BSize LPSolveInterface::MinSize(Variable* width, Variable* height) { SummandList* newObjFunction = new(std::nothrow) SummandList(2); newObjFunction->AddItem(new(std::nothrow) Summand(1.0, width)); newObjFunction->AddItem(new(std::nothrow) Summand(1.0, height)); SummandList* oldObjFunction = SwapObjectiveFunction(newObjFunction); ResultType result = Solve(); SetObjectiveFunction(oldObjFunction); if (result == kUnbounded) return kMinSize; if (result != kOptimal) printf("Could not solve the layout specification (%d). ", result); return BSize(width->Value(), height->Value()); }