Beispiel #1
0
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;
    }
}
Beispiel #2
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);
    }
}
Beispiel #3
0
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;
}