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; }
BString Constraint::ToString() const { BString string; string << "Constraint "; string << fLabel; string << "(" << (int32)this << "): "; if (fIsValid) { for (int i = 0; i < fLeftSide->CountItems(); i++) { Summand* s = static_cast<Summand*>(fLeftSide->ItemAt(i)); if (i != 0 && s->Coeff() >= 0) string << " + "; string << (float)s->Coeff() << "*"; string << "x"; string << s->Var()->Index(); string << " "; } string << ((fOp == kEQ) ? "== " : (fOp == kGE) ? ">= " : (fOp == kLE) ? "<= " : "?? "); string << (float)fRightSide; string << " PenaltyPos=" << (float)PenaltyPos(); string << " PenaltyNeg=" << (float)PenaltyNeg(); } else string << "invalid"; return string; }
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; }
/** * Updates the internal representation of the objective function. * Must be called whenever the summands of the objective function are changed. */ void LPSolveInterface::_UpdateObjectiveFunction() { int32 size = fObjFunction->CountItems(); double coeffs[size]; int varIndexes[size]; Summand* current; for (int32 i = 0; i < size; i++) { current = (Summand*)fObjFunction->ItemAt(i); coeffs[i] = current->Coeff(); varIndexes[i] = current->Var()->GlobalIndex() + 1; } if (!SetObjectiveFunction(size, &coeffs[0], &varIndexes[0])) printf("Error in set_obj_fnex.\n"); }
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; }
/** * Sets the summands on the left side of the constraint. * The old summands are NOT deleted. * * @param summands a BList containing the Summand objects that make up the new left side */ void Constraint::SetLeftSide(SummandList* summands) { if (!fIsValid) return; // check left side for (int32 i = 0; i < summands->CountItems(); i++) { Summand* summand = summands->ItemAt(i); for (int32 a = i + 1; a < summands->CountItems(); a++) { Summand* nextSummand = summands->ItemAt(a); if (summand->Var() == nextSummand->Var()) { summand->SetCoeff(summand->Coeff() + nextSummand->Coeff()); summands->RemoveItem(nextSummand); delete nextSummand; a--; } } } fLeftSide = summands; fLS->UpdateLeftSide(this); }