예제 #1
0
    /** pop will advance the \c next pointer among the siblings on the top and
	then moves the top to its correct position. #realpop is the method
	that actually removes the element from the heap */
    inline void pop() {
	CoinTreeSiblings* s = candidateList_.front();
	if (!s->advanceNode()) {
	    realpop();
	    delete s;
	} else {
	    fixTop();
	}
	--size_;
    }
예제 #2
0
파일: CbcTree.cpp 프로젝트: Flymir/coin-all
void
CbcTree::realpop()
{
    if (nodes_.size() > 0) {
        nodes_[0] = nodes_.back();
        nodes_.pop_back();
        fixTop();
    }
    assert (nodes_.size() >= 0);
}
예제 #3
0
void ExpressionTreeUtils::shrink(Expression*& top, Operator* op, bool leftside)
{
	// Can't shrink if only an atomic value left
	if ( ( leftside ? op->first()->type() : op->last()->type() ) != Operator::type() )
		return;

	// Can't shrink from a side where there is no delimiter
	if ( (leftside && op->descriptor()->prefix().isEmpty() ) || (!leftside && op->descriptor()->postfix().isEmpty()))
		return;

	Expression* new_border_expr = (leftside ? op->first() : op->last())->findCutExpression(leftside, leftside ? op->descriptor()->postfix() : op->descriptor()->prefix());
	if (new_border_expr == nullptr) return;

	Operator* cut_op = new_border_expr->parent();
	Operator* cut_op_parent = cut_op->parent();

	// Rewire the tree
	Expression* op_placeholder = new Empty;
	replace(top, op, op_placeholder);

	if (leftside)
	{
		cut_op->last(true);
		cut_op_parent->first(true);
		cut_op_parent->prepend(new_border_expr);
		cut_op->append(op);
	}
	else
	{
		cut_op->first(true);
		cut_op_parent->last(true);
		cut_op_parent->append(new_border_expr);
		cut_op->prepend(op);
	}

	delete replace(top, op_placeholder, cut_op);

	fixTop(top);
}
예제 #4
0
    virtual void realpop() {
	candidateList_[0] = candidateList_.back();
	candidateList_.pop_back();
	fixTop();
    }
예제 #5
0
void ExpressionTreeUtils::grow(Expression*& top, Operator* op, bool leftside)
{
	bool rightside = !leftside;

	// Can't grow if there is no parent
	if ( !op->parent() )
		return;


	// Can't grow from a side where there is no delimiter
	if ( (leftside && op->descriptor()->prefix().isEmpty() ) || (rightside && op->descriptor()->postfix().isEmpty()) )
		return;

	Operator* parent = op->parent();

	// Get context
	int delim_begin;
	int delim_end;
	op->globalDelimiterBoundaries(leftside ? 0 : op->descriptor()->numOperands(), delim_begin, delim_end);
	ExpressionContext c = top->findContext(leftside ? delim_begin: delim_end);

	// If this is an expression in the middle of two delimiters that belong to the same operator
	// this typically means that it can not be grown any more from only a single side...
	bool wrap_parent = false;
	if (   ( leftside && (c.leftType() == ExpressionContext::None || c.leftType() == ExpressionContext::OpBoundary) )
		 || ( rightside && (c.rightType() == ExpressionContext::None || c.rightType() == ExpressionContext::OpBoundary) )
			 )
	{
		// .. EXCEPT: when both delimiters are the same as the delimiter we're trying to grow and the
		// direction opposite of the growth direction is an end delimiter. In that case we simply
		// engulf the entire parent.
		op->globalDelimiterBoundaries(leftside ? op->descriptor()->numOperands() : 0, delim_begin, delim_end);
		ExpressionContext c_other = top->findContext(leftside ? delim_end : delim_begin );
		if (   ( leftside && c_other.rightType() == ExpressionContext::OpBoundary && c_other.rightText() == op->descriptor()->postfix() && c_other.rightDelim() == c_other.rightOp()->size())
			 || ( rightside && c_other.leftType() == ExpressionContext::OpBoundary && c_other.leftText() == op->descriptor()->prefix() && c_other.leftDelim() == 0) )
			wrap_parent = true;
		else
		return;
	}

	// Special case when the parent ends with a pre/postfix in the direction we're growing.
	// In that case we must wrap the whole operator as we can not break the delimiters.
	wrap_parent = wrap_parent || ( !(leftside && parent->descriptor()->prefix().isEmpty()) && !(rightside && parent->descriptor()->postfix().isEmpty()));
	if (wrap_parent)
	{
		Expression* placeholder = new Empty();
		replace(top, parent, placeholder);
		replace(top, op, leftside ? op->first(true) : op->last(true));
		if (leftside) op->prepend(parent);
		else op->append(parent);
		delete replace(top, placeholder, op);

		return;
	}

	// Find the expression that must be wrapped
	Operator* top_op = parent;
	Operator* child = op;
	while ( (leftside ? top_op->last() : top_op->first()) != child)
	{
		child = top_op;
		top_op = top_op->parent();
		if (!top_op) return;
	}
	Expression* to_wrap = leftside ? top_op->first()->smallestRightmostSubExpr() : top_op->last()->smallestLeftmostSubExpr();

	// Do the exchange --------------------------------------

	// Disconnect top_op from the the entire tree and from it's first and last
	// Note that if we've reached this point then first and last must be two different nodes
	Expression* top_op_placeholder = new Empty();
	replace(top, top_op, top_op_placeholder);
	Expression* top_op_last = top_op->last(true);   // Special case when rightside: top_op_last could be identical to to_wrap
	Expression* top_op_first = top_op->first(true); // Special case when leftside: top_op_first could be identical to to_wrap

	// Disconnect the to_wrap expression if not yet disconnected
	Expression* to_wrap_placeholder = nullptr;
	if ( (leftside && to_wrap != top_op_first) || (rightside && to_wrap != top_op_last) )
	{
		to_wrap_placeholder = new Empty();
		replace(top, to_wrap, to_wrap_placeholder);
	}

	// Disconnect the old_wrapped expression
	Expression* old_wrap = leftside ? op->first(true) : op->last(true); // This is the content that was previously wrapped
	// Disconnect the left and right children of top_op.

	// Make the necessary connections
	if (leftside)
	{
		op->prepend(top_op);
		top_op->prepend(to_wrap);
		top_op->append(old_wrap);
		//Consider the special case
		if (top_op_first == to_wrap)
		{
			delete replace(top, top_op_placeholder, top_op_last );
		}
		else
		{
			delete replace(top, top_op_placeholder, top_op_first );
			delete replace(top, to_wrap_placeholder, top_op_last);
		}
	}
	else
	{
		op->append(top_op);
		top_op->prepend(old_wrap);
		top_op->append(to_wrap);
		//Consider the special case
		if (top_op_last == to_wrap)
		{
			delete replace(top, top_op_placeholder, top_op_first );
		}
		else
		{
			delete replace(top, top_op_placeholder, top_op_last );
			delete replace(top, to_wrap_placeholder, top_op_first);
		}
	}

	fixTop(top);
}