예제 #1
0
/** Find a maximum size matching in a bipartite graph
 *  by reducing the matching problem to a max flow problem.
 *  @param g1 is an undirected graph
 *  @param match is a list in which the result is returned
 */
void flowMatch(Graph& g, Glist<edge>& match) {
	// divide vertices into two independent sets
	ListPair split(g.n());
	if (!findSplit(g,split))
		Util::fatal("flowMatch: graph is not bipartite");

	// create flow graph, taking care to maintain edge numbers
	Flograph fg(g.n()+2, g.M()+g.n(), g.n()+1, g.n()+2);
	for (edge e = g.first(); e != 0; e = g.next(e)) {
		vertex u = (split.isIn(g.left(e)) ? g.left(e) : g.right(e));
		fg.joinWith(u,g.mate(u,e),e); fg.setCapacity(e,1);
	}
	for (vertex u = split.firstIn(); u != 0; u = split.nextIn(u)) {
		edge e = fg.join(fg.src(),u); fg.setCapacity(e,1);
	}
	for (vertex u = split.firstOut(); u != 0; u = split.nextOut(u)) {
		edge e = fg.join(u,fg.snk()); fg.setCapacity(e,1);
	}

	// solve flow problem
	(dinic(fg)); // parens added to eliminate ambiguity

	// now construct matching from flow
	match.clear();
	for (edge e = g.first(); e != 0; e = g.next(e)) {
		vertex u = (split.isIn(g.left(e)) ? g.left(e) : g.right(e));
		if (fg.f(u,e) != 0) match.addLast(e);
	}
}
예제 #2
0
/** Find a maximum size matching in a bipartite graph
 *  by reducing the matching problem to a max flow problem.
 *  @param[in] g is a graph
 *  @param[in,out] matchingEdge[u] is (on return) the matching edge incident
 *  to u or 0 if u is unmatched; if matchingEdge is not all 0 initially,
 *  it is assumed to represent a valid initial matching
 */
void matchb_f(const Graph& g, edge *matchingEdge) {
	// divide vertices into two independent sets
	ListPair split(g.n());
	if (!findSplit(g,split))
		Util::fatal("matchb_f: graph is not bipartite");

	// create flow graph, taking care to maintain edge numbers
	Graph_f fg(g.n()+2, g.M()+g.n(), g.n()+1, g.n()+2);
	for (edge e = g.first(); e != 0; e = g.next(e)) {
		vertex u = (split.isIn(g.left(e)) ? g.left(e) : g.right(e));
		fg.joinWith(u,g.mate(u,e),e); fg.setCapacity(e,1);
		if (e == matchingEdge[u]) fg.setFlow(e,1);
	}
	for (vertex u = split.firstIn(); u != 0; u = split.nextIn(u)) {
		edge e = fg.join(fg.src(),u); fg.setCapacity(e,1);
		if (e == matchingEdge[u]) fg.setFlow(e,1);
	}
	for (vertex u = split.firstOut(); u != 0; u = split.nextOut(u)) {
		edge e = fg.join(u,fg.snk()); 
		fg.setCapacity(e,1);
		if (e == matchingEdge[u]) fg.setFlow(e,1);
	}

	// solve flow problem
	(mflo_d(fg)); // parens added to eliminate ambiguity

	// now construct matching from flow
	for (vertex u = 1; u <= g.n(); u++) matchingEdge[u] = 0;
	for (edge e = g.first(); e != 0; e = g.next(e)) {
		vertex u = (split.isIn(g.left(e)) ? g.left(e) : g.right(e));
		if (fg.f(u,e) != 0)
			matchingEdge[u] = matchingEdge[g.mate(u,e)] = e;
	}
}
예제 #3
0
/** Find a maximum weight matching in a bipartite graph using the
 *  hungarian algorithm algorithm.
 *  @param g1 is an undirected graph
 *  @param match is a list in which the result is returned
 */
hungarian::hungarian(Wgraph& g1, Glist<edge>& match) : g(&g1) {
	// divide vertices into two independent sets
	split = new ListPair(g->n());
	if (!findSplit(*g,*split))
		Util::fatal("hungarian: graph is not bipartite");

	mEdge = new edge[g->n()+1];
	roots = new Dlist(g->n());
	for (vertex u = 1; u <= g->n(); u++) {
		mEdge[u] = 0;
		if (split->isIn(u)) roots->addLast(u);
	}

	// initialize vertex labels
	lab = new int[g->n()+1];
	initLabels();

	// augment the matching until no augmenting path remains
	vertex u; pEdge = new edge[g->n()+1];
	while ((u = findPath()) != 0) { augment(u); }

	// add matched edges to output set
	match.clear();
	for (vertex u = 1; u <= g->n(); u++) {
		edge e = mEdge[u];
		if (e != 0 && u < g->mate(u,e)) match.addLast(e);
	}
	delete split; delete roots;
	delete [] mEdge; delete [] pEdge; delete [] lab;
}
예제 #4
0
파일: bezier.cpp 프로젝트: honsey/fztaxedit
void Bezier::initControlIndex(QPointF p, double width)
{
	double t = findSplit(p, width);
	double totalLen = computeCubicCurveLength(1, 24);
	double len = computeCubicCurveLength(t, 24);
	//double d0 = GraphicsUtils::distanceSqd(p, m_cp0);
	//double d1 = GraphicsUtils::distanceSqd(p, m_cp1);
	m_drag_cp0 = (len <= totalLen / 2);
}
예제 #5
0
void BVH::generateHierarchyRecursive(std::vector<AABBox>& boxes, Node* node, int first, int last, int i, ProgressBar& progressBar)
{
	// Determine where to split the range.
	int split = findSplit(boxes, first, last);

	Node* rightChild;
	if (split == first)
	{
		rightChild = &m_leafNodes[split];
	}
	else
	{
		rightChild = &m_branchNodes[split];

		//push next node
		generateHierarchyRecursive(boxes, rightChild, first, split, i, progressBar);
	}

	Node* leftChild;
	if (split + 1 == last)
	{
		leftChild = &m_leafNodes[split + 1];
	}
	else
	{
		leftChild = &m_branchNodes[split + 1];

		//push next node
		generateHierarchyRecursive(boxes, leftChild, split + 1, last, i, progressBar);
	}

	//	m_branchNodes[i].m = max;
//	node->re = last;
//	node->rs = first;
//	node->s = split;

	node->rightChild = rightChild;
	node->leftChild = leftChild;
//	leftChild->parent = node;
//	rightChild->parent = node;

	i++;
	progressBar.updateProgress(static_cast<int>((static_cast<float>(i) / boxes.size()) * 100));
}
	void SerialRandomTree::build(){
		// create the attribute indices window
		m_attIndicesWindow = std::vector<int>(data->numAttributes,0);
		int j = 0;
		for(int i = 0; i < m_attIndicesWindow.size(); i++){
			m_attIndicesWindow[i] = j++;
		}

		data->whatGoesWhere = std::vector<int>(data->inBag.size(),0);
		data->createInBagSortedIndices();

		int unprocessedNodes = 1;
		int newNodes = 0;
		
		SerialTreeNodePtr currentNode = SerialTreeNodePtr(new SerialTreeNode);
		currentNode->sortedIndices = (*data->sortedIndices);

		// compute initial class counts
		currentNode->classProbs = std::vector<double>(data->numClasses,0);
		for(int i = 0; i < data->numInstances; i++) {
			currentNode->classProbs[(*data->instClassValues)[i]] += (*data->instWeights)[i];
		}

		m_depth = 0;
		m_treeNodes.push_back(currentNode);
		while(unprocessedNodes != 0){
			// Iterate through unprocessed nodes
			while(unprocessedNodes != 0){
				currentNode = m_treeNodes[m_treeNodes.size()-(unprocessedNodes+newNodes)];

				// Check if node is a leaf
				if((currentNode->sortedIndices.size() > 0  &&  currentNode->sortedIndices[0].size() < max(2, getMinNum()))  // small
					|| (abs(currentNode->classProbs[maxIndex(currentNode->classProbs)] - sum(currentNode->classProbs)) < 1e-6)      // pure
					|| ((getMaxDepth() > 0)  &&  (m_depth >= getMaxDepth()))                           // deep
					){
					createLeafNode(currentNode);
					currentNode->clean();
				}
				else{
					if(findSplit(currentNode)){
						createSplitNodes(currentNode,newNodes);
						currentNode->clean();
					}
					else{
						createLeafNode(currentNode);
						currentNode->clean();
					}
				}
				unprocessedNodes--;
			}
			m_depth++;
			unprocessedNodes = newNodes;
			newNodes = 0;
		}

		m_nodesInTree = m_treeNodes.size();

		data.reset();
		m_dists.clear();
		m_splits.clear();
		m_props.clear();
		m_vals.clear();

		m_dists.shrink_to_fit();
		m_splits.shrink_to_fit();
		m_props.shrink_to_fit();
		m_vals.shrink_to_fit();
	}
예제 #7
0
/// <summary>
/// Generates the hierarchy.  http://devblogs.nvidia.com/parallelforall/wp-content/uploads/sites/3/2012/11/karras2012hpg_paper.pdf
/// </summary>
/// <param name="boxes">The boxes.</param>
void BVH::generateHierarchyFullParallel(std::vector<AABBox>& boxes)
{
	ProgressBar progressBar;

#if !_DEBUG
#pragma omp parallel for schedule(dynamic,1)
#endif
	for (int i = 0; i < (boxes.size() - 1); i++)
	{
		//first, find the range this node corresponds to
		//d == -1 means range ends at i, d == +1 means range starts at i
		int d = sign(commonPrefix(boxes, i, i + 1) - commonPrefix(boxes, i, i - 1));

		//find a maximum and minimum value for the range this node covers.  Must be a power of two for easy binary searching
		int min = commonPrefix(boxes, i, i - d);
		int max = 128;

		while (commonPrefix(boxes, i, i + (max * d)) > min)
		{
			max *= 4;
		}

		//use binary serach to find the farthest common prefis that is greater than min
		int l = 0;
		for (int t = max >> 1; t >= 1; t = t >> 1)
		{
			if (commonPrefix(boxes, i, i + (l + t) * d) > min)
			{
				//serach to the right of this value
				l += t;
			}
		}

		//end of range
		int j = i + l * d;
		int first = i;

		if (d < 0)
		{
			first = j;
			j = i;
		}


		// Determine where to split the range.
		int split = findSplit(boxes, first, j);

		Node* rightChild;
		if (split == first)
		{
			rightChild = &m_leafNodes[split];
		}
		else
		{
			rightChild = &m_branchNodes[split];
		}

		Node* leftChild;
		if (split + 1 == j)
		{
			leftChild = &m_leafNodes[split + 1];
		}
		else
		{
			leftChild = &m_branchNodes[split + 1];
		}

//		m_branchNodes[i].m = max;
//		m_branchNodes[i].re = first;
//		m_branchNodes[i].rs = j;
//		m_branchNodes[i].s = split;
		m_branchNodes[i].rightChild = rightChild;
		m_branchNodes[i].leftChild = leftChild;
//		leftChild->parent = &m_branchNodes[i];
//		rightChild->parent = &m_branchNodes[i];

#pragma omp critical
		{
			progressBar.updateProgress(static_cast<int>((static_cast<float>(i) / boxes.size()) * 100));
		}
	}

	progressBar.end();
}
예제 #8
0
void BVH::generateHierarchyStackLinear(std::vector<AABBox>& boxes)
{
	std::stack<constructData *> dataStack;
	dataStack.push(new constructData(&m_branchNodes[0], 0, static_cast<int>(boxes.size() - 1)));

	//	constructData *dataStackArray = new constructData[1024];
	//	dataStackArray[0] = constructData(&m_branchNodes[0], 0, static_cast<int>(boxes.size() - 1));
	//	uint32_t stackSize = 1;

	int i = 0;
	ProgressBar progressBar;

	do
	{
		constructData* data = dataStack.top();
		dataStack.pop();

		//		--stackSize;
		//		constructData data = dataStackArray[stackSize];

		// Determine where to split the range.
		int split = findSplit(boxes, data->first, data->last);

		Node* rightChild;
		if (split == data->first)
		{
			rightChild = &m_leafNodes[split];
		}
		else
		{
			rightChild = &m_branchNodes[split];

			//push next node
			dataStack.push(new constructData(rightChild, data->first, split));
			//			dataStackArray[stackSize] = constructData(rightChild, data.first, split);
			//			++stackSize;
		}

		Node* leftChild;
		if (split + 1 == data->last)
		{
			leftChild = &m_leafNodes[split + 1];
		}
		else
		{
			leftChild = &m_branchNodes[split + 1];

			//push next node
			dataStack.push(new constructData(leftChild, split + 1, data->last));
			//			dataStackArray[stackSize] = constructData(leftChild, split + 1, data.last);
			//			++stackSize;
		}

		//		m_branchNodes[i].m = max;
		//		data.node->re = data.last;
		//		data.node->rs = data.first;
		//		data.node->s = split;
		data->node->rightChild = rightChild;
		data->node->leftChild = leftChild;
		//		leftChild->parent = data.node;
		//		rightChild->parent = data.node;

		delete data;

		i++;
		progressBar.updateProgress(static_cast<int>((static_cast<float>(i) / boxes.size()) * 100));
	}
	while (!dataStack.empty());

	progressBar.end();
}