Exemple #1
0
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;
}
Exemple #5
0
/**
 * 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");
}
Exemple #6
0
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);
}