/** 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); } }
/** 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; } }
/** 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; }
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); }
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(); }
/// <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(); }
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(); }