예제 #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;
}
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;
}
예제 #4
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;
}
예제 #5
0
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());
}