コード例 #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
ファイル: opt_costModel.c プロジェクト: Mytherin/MonetDBLite
/*
 * The cost will be used in many places to make decisions.
 * Access should be fast.
 * The SQL front-end also makes the BAT index available as the
 * property bid. This can be used to access the BAT and involve
 * more properties into the decision procedure.
 * [to be done]
 * Also make sure you don't re-use variables, because then the
 * row count becomes non-deterministic.
 */
int
OPTcostModelImplementation(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
{
	int i;
	BUN c1, c2;
	InstrPtr p;

	(void) cntxt;
	(void) stk;
	(void) pci;

	if ( mb->inlineProp )
		return 0;

	for (i = 0; i < mb->stop; i++) {
		p = getInstrPtr(mb, i);
		if (getModuleId(p)==algebraRef) {
			 if (getFunctionId(p) == subselectRef ||
				getFunctionId(p) == thetasubselectRef) {
				newRows(1,2, (c1 > 2 ? c2 / 2 +1: c1/2+1),0);
			} else if (
				getFunctionId(p) == selectNotNilRef  ||
				getFunctionId(p) == sortRef  ||
				getFunctionId(p) == subsortRef  ||
				getFunctionId(p) == projectRef  ){
				newRows(1,1,c1,0);
			} else if (getFunctionId(p) == subjoinRef ||
				getFunctionId(p) == projectionRef ||
				getFunctionId(p) == subbandjoinRef ||
				getFunctionId(p) == projectionpathRef ) {
				/* assume 1-1 joins */
				newRows(1,2,(c1 < c2 ? c1 : c2),0);
			} else
			if (getFunctionId(p) == crossRef) {
				newRows(1,2,((log((double) c1) + log((double) c2) > log(INT_MAX) ? INT_MAX : c1 * c2 +1)),0);
				/* log sets errno if it cannot compute the log. This will then screw with code that checks errno */
				if (errno == ERANGE || errno == EDOM) {
					errno = 0;
				}
			}
		} else if (getModuleId(p) == batcalcRef) {
			if( getFunctionId(p) == ifthenelseRef) {
				if( isaBatType(getArgType(mb,p,2) ) ) {
					newRows(2,2, c1,0);
				} else {
					newRows(3,3, c1,0);
				}
			} else if( isaBatType(getArgType(mb,p,1)) ){
					newRows(1,1, c1,0);
				} else {
					newRows(2, 2, c2,0);
				}
		} else if (getModuleId(p) == batstrRef) {
				newRows(1,1, c1,0);
		} else if (getModuleId(p) == batRef) {
			if (getFunctionId(p) == appendRef ||
				   getFunctionId(p) == insertRef ){
				/*
				 * Updates are a little more complicated, because you have to
				 * propagate changes in the expected size up the expression tree.
				 * For example, the SQL snippet:
				 *     _49:bat[:oid,:oid]{rows=0,bid=622}  := sql.bind_dbat("sys","example",3);
				 *     _54 := bat.setWriteMode(_49);
				 *     bat.append(_54,_47,true);
				 * shows what is produced when it encounters a deletion. If a non-empty
				 * append is not properly passed back to _49, the emptySet
				 * optimizer might remove the complete deletion code.
				 * The same holds for replacement operations, which add information to
				 * an initially empty insertion BAT.
				 */
				if( isaBatType(getArgType(mb,p,2)) ){
					/* insert BAT */
					newRows(1,2, (c1 + c2+1),1);
				} else {
					/* insert scalars */
					newRows(1,1, (c1 +1),1);
				}
			} else if (getFunctionId(p) == deleteRef){
				if( isaBatType(getArgType(mb,p,2)) ){
					/* delete BAT */
					newRows(1, 2, (c2 >= c1 ? 1 : c1 - c2), 1);
				} else {
					/* insert scalars */
					newRows(1, 1, (c1 <= 1 ? 1 : c1 - 1), 1);
				}
			} else if (getFunctionId(p) == insertRef){
				newRows(1,1,( c1 + 1),0); /* faked */
			}
		} else if (getModuleId(p)==groupRef) {
			if (getFunctionId(p) ==subgroupRef ) {
				newRows(1,1,( c1 / 10+1),0);
			} else {
				newRows(1,1, c1,0);
			}
		} else if (getModuleId(p)== aggrRef) {
			if (getFunctionId(p) == sumRef ||
				getFunctionId(p) == minRef ||
				getFunctionId(p) == maxRef ||
				getFunctionId(p) == avgRef) {
				newRows(1, 1, (c1 != 0 ? c1 : 1), 0);
			} else	if (getFunctionId(p) == countRef){
				newRows(1,1, 1,0);
			}
		} else if( p->token == ASSIGNsymbol && p->argc== 2){
			/* copy the rows property */
			c1 = getRowCnt(mb, getArg(p,1));
			/* just to ensure that rowcnt was/is never set to -1 */
			assert(c1 != (BUN) -1);
			if (c1 != BUN_NONE)
				setRowCnt(mb, getArg(p,0), c1);
		}
	}
	return 1;
}