コード例 #1
0
ファイル: lpsub.cpp プロジェクト: mneumann/tulip
void LpSub::addCons(ArrayBuffer<Constraint*> &newCons)
{
	// LpSub::addCons(): local variables
	ArrayBuffer<Row*> newRows(newCons.size(),false);  //!< the new constraints in row format
	ArrayBuffer<int> delVar(sub_->nVar(),false); //!< buffer of deletable components of row format
	double            rhsDelta;  //!< correction of right hand side
	InfeasCon::INFEAS infeas;    //!< infeasibility mode (TooLarge, TooSmall)

	Row *nr;

	constraint2row(newCons, newRows);

	// eliminate variables in added constraints
	/* Also the elimination of variables in an added constraint might
	*   cause a void left hand side (interpreted as 0) violated the right hand
	*   side of the constraint. These infeasible constraints are recognized,
	*   but the resolution is currently not implemented.
	*/
	const int nNewRows = newRows.size();

	for (int c = 0; c < nNewRows; c++) {
		//! eliminate variables in constraint \a c
		delVar.clear();
		rhsDelta = 0.0;
		nr       = newRows[c];
		const int nrNnz = nr->nnz();
		for(int i = 0; i < nrNnz; i++)
			if(eliminated(nr->support(i))) {
				delVar.push(i);
				rhsDelta += nr->coeff(i)*elimVal(nr->support(i));
			}
			nr->delInd(delVar,rhsDelta);
			nr->rename(orig2lp_);

			// check if constraint \a c has become infeasible
			if(nr->nnz() == 0) {
				infeas = newCons[c]->voidLhsViolated(nr->rhs());
				if (infeas != InfeasCon::Feasible) {
					infeasCons_.push(new InfeasCon(master_, newCons[c], infeas));
					Logger::ifout() << "LpSub::addCons(): infeasible constraint added.\nAll variables with nonzero coefficients are eliminated and constraint is violated.\nSorry, resolution not implemented yet.\n";
					OGDF_THROW_PARAM(AlgorithmFailureException, ogdf::afcLpSub);
				}
			}
	}

	LP::addRows(newRows);

	for (int i = 0; i < newRows.size(); i++)
		delete newRows[i];
}
コード例 #2
0
ファイル: Litterale.cpp プロジェクト: sylvainma/UTComputer
/*!
 *  \brief Ajoute une littérale atome en tant que variable d'une littérale passée en argument
 */
void LitteraleAtome::addVar(LitteraleAtome* atome, Litterale* l) {
    // On vérifie que l'atome en question n'existe pas déjà dans la liste vars.
    // On vérifie également que le même nom n'existe pas déjà.
    // Si l'une des deux vérifications précédentes n'est pas vérifiée, alors on écrase (on supprime la variable préexistente et on ajoute la nouvelle).
    
    // Parcourt de la liste
    for(vector<LitteraleAtome*>::iterator it=vars.begin(); it!=vars.end(); ++it) {
        // Même pointeur atome OU même nom d'atome -> on delete de la liste
        if(*it==atome || (*it)->getId()==atome->getId()) delVar(*it);
    }
    
    // On ajoute l'atome dans vars en tant que variable pour la littérale
    vars.push_back(atome);
    
    // On lie l'atome à sa littérale
    atome->valeur=l;
}
コード例 #3
0
ファイル: lpsub.cpp プロジェクト: mneumann/tulip
void LpSub::initialize()
{
	// LpSub::initialize(): local variables
	Array<double> obj(sub_->nVar());
	Array<double> lBound(sub_->nVar());
	Array<double> uBound(sub_->nVar());
	Array<Row*>   rows(sub_->nCon());

	Array<LPVARSTAT::STATUS> lpVarStat(sub_->nVar());
	Array<SlackStat::STATUS> slackStat(sub_->nCon());

	Row   row(master_, sub_->nVar());                //!< buffer to store generated row
	int         conNnz;                          //!< number of nonzeros of constraint \a c
	int         c;                               //!< loop index

	// generate the row format of the active constraints
	/* After the generation of the row format we allocate a row of
	*   the correct length and make a copy in order to safe memory.
	*/
	int nRow = 0;

	const int nCon = sub_->nCon();

	for (c = 0; c < nCon; c++) {
		conNnz  = sub_->constraint(c)->genRow(sub_->actVar(), row);
		rows[nRow] = new Row(master_, conNnz);
		rows[nRow]->copy(row);
		slackStat[nRow] = sub_->slackStat(c)->status();
		++nRow;
		row.clear();
	}

	// eliminate set and fixed variables and initialize the columns
	Variable   *v;                           //!< pointer to variable of subproblem
	Array<bool> marked(0,sub_->nVar()-1, false);  //!< \a true if variable can be eliminated

	nOrigVar_ = sub_->nVar();
	valueAdd_ = 0.0;

	// LpSub: mark variables to eliminate, build objective function and bounds
	/* We mark all variables which can be eliminated, add them to the
	*   ArrayBuffer \a delVar, compute the mappings from the original variable
	*   set to the actual variable set in the \a LP, and vice versa, and
	*   determine the correction term for the LP-value.

	*   If all variables can be eliminated then we do not eliminate the last
	*   variable for simpification. Otherwise it would be necessary to load
	*   an problem with 0 variables to the LP-solver which is, e.g., for
	*   Cplex not possible. Although the emulation of the optimization would
	*   still be simple, but extra work would have to be performed if later
	*   constraints were added.
	*/
	const int nVar = sub_->nVar();
	int nCol = 0;
	for (int i = 0; i < nVar; i++) {
		v = sub_->variable(i);
		if(sub_->fsVarStat(i)->fixedOrSet()) {
			if (eliminable(i) && (nCol || (i != sub_->nVar() - 1))) {

				//! eliminate variable \a i from the LP
				marked[i]  = true;
				valueAdd_  += v->obj() * elimVal(i);
				orig2lp_[i] = -1;
			}
			else {

				// fix variable \a i in the LP
				/* As variable \a i could not be eliminated we set both its upper and lower
				*   bound to the value it is fixed or set to.
				*/
				orig2lp_[i]     = nCol;
				lp2orig_[nCol]  = i;
				obj[nCol]       = v->obj();
				lBound[nCol]    = elimVal(i);
				uBound[nCol]    = elimVal(i);
				lpVarStat[nCol] = sub_->lpVarStat(i)->status();
				++nCol;
			}
		}
		else {

			// add variable \a i to the LP
			orig2lp_[i]     = nCol;
			lp2orig_[nCol]  = i;
			obj[nCol]       = v->obj();
			lBound[nCol]    = sub_->lBound(i);
			uBound[nCol]    = sub_->uBound(i);
			lpVarStat[nCol] = sub_->lpVarStat(i)->status();
			++nCol;
		}
	}

	// LpSub: update the constraints
	/* If all active variables of a constraint are eliminated then
	*   its left hand side is void (implicitly 0), but its right hand side
	*   can be nonzero. Depending on the sense of the constraint it can be
	*   infeasible.
	*   If the elimination of variables from constraints causes an infeasible
	*   \a LP, the constraint is memorized in \a infeasCons_.
	*/
	ArrayBuffer<int> delVar(sub_->nVar(),false); //!< buffer of deletable components of row format
	double            rhsDelta;  //!< correction of right hand side due to eliminations
	InfeasCon::INFEAS infeas;    //!< infeasibility mode (TooLarge, TooSmall)

	for (c = 0; c < nCon; c++) {

		// eliminate the variables from the constraint
		delVar.clear();
		rhsDelta = 0.0;
		const int rNnz = rows[c]->nnz();
		for(int i = 0; i < rNnz; i++)
			if(marked[rows[c]->support(i)]) {
				delVar.push(i);
				rhsDelta += rows[c]->coeff(i)*elimVal(rows[c]->support(i));
			}

			rows[c]->delInd(delVar, rhsDelta);

			// check if the constraint is now infeasible
			if (rows[c]->nnz() == 0) {
				infeas = sub_->constraint(c)->voidLhsViolated(rows[c]->rhs());
				if (infeas != InfeasCon::Feasible)
					infeasCons_.push(new InfeasCon(master_, sub_->constraint(c), infeas));
			}
			rows[c]->rename(orig2lp_);
	}

	// initialize the LP-solver and clean up
	LP::initialize(*master_->optSense(), nRow, sub_->maxCon(), nCol,
		sub_->maxVar(), obj, lBound, uBound, rows,
		lpVarStat, slackStat);

	for (c = 0; c < nCon; c++)
		delete rows[c];
}
コード例 #4
0
ファイル: lpsub.cpp プロジェクト: mneumann/tulip
void LpSub::addVars(
	ArrayBuffer<Variable*> &vars,
	ArrayBuffer<FSVarStat*> &fsVarStat,
	ArrayBuffer<double> &lb,
	ArrayBuffer<double> &ub)
{
	// LpSub::addVars(): local variables
	ArrayBuffer<int> delVar(vars.size(),false);  //!< the eliminated variables
	Array<double> rhsDelta(0,sub_->nCon()-1, 0.0);  //!< the correction of the rhs
	double vValue;
	double coeff;
	bool modifyRhs = false;  //!< if \a true the modification of rhs required
	int oldNCol = trueNCol();
	int n = trueNCol();
	Variable *v;

	// divide the added variables in eliminable and non-eliminable ones
	int nVariables = vars.size();

	for (int i = 0; i < nVariables; i++) {
		v = vars[i];
		if(fsVarStat[i]->fixedOrSet()) {
			if (eliminable(i)) {
				//! the new variable is eliminated
				delVar.push(i);

				vValue = elimVal(fsVarStat[i], lb[i], ub[i]);

				valueAdd_ += v->obj() * vValue;
				orig2lp_[nOrigVar_++] = -1;

				const int nCon = sub_->nCon();

				for (int c = 0; c < nCon; c++) {
					coeff = sub_->constraint(c)->coeff(v);
					if (fabs(coeff) > master_->eps()) {
						rhsDelta[c] += vValue * coeff;
						modifyRhs    = true;
					}
				}
			}
			else {
				// the new variable is fixed in the LP
				orig2lp_[nOrigVar_++] = n;
				lp2orig_[n] = oldNCol + i;
				++n;
				lb[i] = ub[i] = elimVal(fsVarStat[i], lb[i], ub[i]);
			}
		}
		else {
			// the new variable will be added to the LP explicitly
			orig2lp_[nOrigVar_++] = n;
			lp2orig_[n] = oldNCol + i;
			++n;
		}
	}

	// remove the fixed and set added variables
	if (delVar.size()) {
		vars.leftShift(delVar);
		fsVarStat.leftShift(delVar);
		lb.leftShift(delVar);
		ub.leftShift(delVar);
	}

	// generate the column of the added variable and add them to the LP
	ArrayBuffer<Column*> newCols(vars.size(),false);
	//!< new columns added to the constraint matrix
	Column colBuf(master_, nRow());  //!< buffer for generated columns
	Column *col;

	nVariables = vars.size();
	for(int i = 0; i < nVariables; i++) {
		vars[i]->genColumn(sub_->actCon(), colBuf);
		col = new Column(master_, colBuf.nnz());
		col->copy(colBuf);
		col->obj(colBuf.obj());
		col->uBound(colBuf.uBound());
		col->lBound(colBuf.lBound());
		newCols.push(col);
		colBuf.clear();
	}

	LP::addCols(newCols);

	// modify the right hand side if fixed or set variables are added
	if (modifyRhs) {
		const int nCon = sub_->nCon();

		Array<double> newRhs(nCon);
		for(int c = 0; c < nCon; c++)
			newRhs[c] = rhs(c) - rhsDelta[c];

		changeRhs(newRhs);
	}

	// LpSub::addVars(): clean up
	for(int i = 0; i < nVariables; i++)
		delete newCols[i];
}