int augmentPath(t_graph* resNet, int v, int t, int flow) { int n,min; if(resNet!=NULL && !resNet->vertices[v].visited) { if(v==t) return flow; resNet->vertices[v].visited=TRUE; for(n=nextNeighbor(resNet,v,-1);n<resNet->v;n=nextNeighbor(resNet,v,n)) { if(!resNet->vertices[n].visited) { if(resNet->am[v][n]<flow) min=resNet->am[v][n]; else min=flow; } if((min=augmentPath(resNet,n,t,min))>0) { if(resNet->am[v][n]!=INF) resNet->am[v][n] -= min; if(resNet->am[n][v]!=INF) resNet->am[n][v] += min; return min; } } return 0; } }
void OneByOne::receiveRoom(RoomAdmin *const admin, const Room *const room) { if (factory->compare(room, deref(event), params.matchingTolerance) == ComparisonResult::EQUAL) { augmentPath(shortPaths->back(), admin, room); } else { // needed because the memory address is not unique and // calling admin->release might destroy a room still held by some path handler->hold(room, admin, this); handler->release(room); } }
void HungarianMatrix<T>::csaz() { // step 5; constact a series of alternating zeros; bool done = false; int r = -1, c = -1, path_count = 1; vector<vector<int>>path(height, vector<int>(width)); for (size_t i = 0; i < height; ++i) { // path[i].resize(width); memset(&path[i].begin(), 0, sizeof(path[i])); } path[path_count - 1][0] = path_row0; path[path_count - 1][1] = path_col0; while (!done) { findStarInCol(path[path_count - 1][1], r); if (r > -1) { path_count++; path[path_count - 1][0] = r; path[path_count - 1][1] = path[path_count - 2][1]; } else { done = true; } if (!done) { findPrimeInRow(path[path_count - 1][0], c); path_count++; path[path_count - 1][0] = path[path_count - 2][0]; path[path_count - 1][1] = c; } } augmentPath(path_count, path); clearCovers(); erasePrimes(); for (size_t i = 0; i < height; ++i) path[i].clear(); path.clear(); czc(); }
bool EdmondMatching::augmentMatching (int n){ //The main analyzing function, with the int node,nodeLabel; //goal of finding augmenting paths or initAlg(n); //concluding that the matching is maximum. for (int i=0; i<n; i++) if (!match[i]){ label[i].even=empty; enqueue(i,0); //Initialize the queue with the exposed vertices, } //making them the roots in the forest. while (queueFront<queueBack){ node=queue[queueFront].vertex; nodeLabel=queue[queueFront].type; if (nodeLabel==0){ for (int i=0; i<n; i++) if (g[node][i]==unmatched){ if (blossom[node]==blossom[i]); //Do nothing. Edges inside the same blossom have no meaning. else if (label[i].even!=undef){ /* The tree has reached a vertex with a label. The parity of this label indicates that an odd length alternating path has been found. If this path is between roots, we have an augmenting path, else there's an alternating cycle, a blossom. */ endPath[0]=endPath[1]=0; backtrace(node,0,empty,0,reverse); backtrace(i,1,empty,0,reverse); //Call the backtracing function to find out. if (path[0][0]==path[1][0]) newBlossom(node,i); /* If the same root node is reached, a blossom was found. Start the labelling procedure to create pseudo-contraction. */ else { augmentPath(); return true; /* If the roots are different, we have an augmenting path. Improve the matching by augmenting this path. Now some labels might make no sense, stop the function, returning that it was successful in improving. */ } } else if (label[i].even==undef && label[i].odd[0]==undef){ //If an unseen vertex is found, report the existing path //by labeling it accordingly. label[i].odd[0]=node; enqueue(i,1); } } } else if (nodeLabel==1){ //Similar to above. for (int i=0; i<n; i++) if (g[node][i]==matched){ if (blossom[node]==blossom[i]); else if (label[i].odd[0]!=undef){ endPath[0]=endPath[1]=0; backtrace(node,0,empty,1,reverse); backtrace(i,1,empty,1,reverse); if (path[0][0]==path[1][0]) newBlossom(node,i); else { augmentPath(); return true; } } else if (label[i].even==undef && label[i].odd[0]==undef){ label[i].even=node; enqueue(i,0); } } } /* The scanning of this label is complete, dequeue it and keep going to the next one. */ queueFront++; } /* If the function reaches this point, the queue is empty, all labels have been scanned. The algorithm couldn't find an augmenting path. Therefore, it concludes the matching is maximum. */ return false; }