예제 #1
0
// the depth first search
// parameters:
//   GraphWin gw: the window as reference
//   graph g: the graph as a reference
//   node v: current node
//   int round: a flag to find out if v is a element of set 1 or set 2
//   node_array<int> level: the level-node-relation
//   node_array<int> free: stores whether node is free
//   edge<int> matching: stores whether edge is matched
//   node parent: the parent of v
//   int current_matching: the current matching
int dfs(GraphWin &gw, graph &g, node &v, int round, node_array<int> &level, node_array<int> &free, edge_array<int> &matching, node &parent, int &current_matching) {

    int next_round = round + 1;

    int invert;  // stores whether we should invert the path or not (boolean)

    // current node is blue
    gw.set_color(v, blue);
    control_wait(WAIT);

    // check all edges of v
    edge e;
    forall_inout_edges(e, v) {
        node opposite_node = g.opposite(v, e);
        // dont check parent node
        if (opposite_node == parent) {
            p("dont check parent");
            continue;
        }
        gw.set_color(e, green);
        control_wait(WAIT);

        if ((round % 2) == 0) { // node v is from vertex set 1
            if (matching[e] == 0) { // unmatched
                if (level[opposite_node] == level[v] + 1) { // level must be greater 1

                    gw.set_color(e, blue);
                    gw.set_color(opposite_node, blue);
                    control_wait(WAIT);

                    // check for augmented path
                    if (free[opposite_node] == 1) {
                        level[opposite_node] = -1;
                        gw.set_color(opposite_node, blue);
                        gw.set_user_label(opposite_node, string("%d", level[opposite_node]));

                        level[v] = -1;
                        gw.set_user_label(v, string("%d", level[v]));
                        
                        // invert path
                        if (matching[e] == 0) {
                            gw.set_color(e, blue);
                            free[opposite_node] = 0;
                            gw.set_border_width(opposite_node, 1);
                            free[v] = 0;
                            gw.set_width(e, 10);
                            gw.set_border_width(v, 1);
                            matching[e] = 1;
                            current_matching++;
                        } else {
                            matching[e] = 0; 
                            gw.set_width(e, 2);
                            current_matching--;
                        }
                        control_wait(WAIT);
                        return 1;
                    } else { // no augmented path yet
                        // call dfs for next node
                        invert = dfs(gw, g, opposite_node, next_round, level, free, matching, v, current_matching);
                        if (invert == 1) { // invert path
                            if (matching[e] == 0) {
                                free[opposite_node] = 0;

                                gw.set_border_width(opposite_node, 1);
                                gw.set_width(e, 10);
                                free[v] = 0;
                                gw.set_border_width(v, 1);
                                matching[e] = 1;
                                current_matching++;
                            } else {
                                gw.set_width(e, 1);
                                matching[e] = 0; 
                                current_matching--;
                            }
                            
                            level[v] = -1;
                            gw.set_user_label(v, string("%d", level[v]));
                            control_wait(WAIT);
                            return 1;
   
                        }
                    }
                }

            }
        } else { // v is a element of vertex set 2
            if (matching[e] == 1) { // matched
                if (level[opposite_node] == level[v] + 1) { // level must be greater 1

                    gw.set_color(e, blue);
                    gw.set_color(opposite_node, blue);
                    control_wait(WAIT);

                    // call dfs for opposite_node
                    invert = dfs(gw, g, opposite_node, next_round, level, free, matching, v, current_matching); }

                    if (invert == 1) {
                        // invert path
                        if (matching[e] == 0) {
                            free[opposite_node] = 0;

                            gw.set_border_width(opposite_node, 5);
                            free[v] = 0;
                            gw.set_border_width(v, 10);
                            gw.set_width(e, 5);
                            matching[e] = 1;
                            current_matching++;
                        } else {
                            matching[e] = 0; 
                            gw.set_width(e, 1);
                            current_matching--;
                        }
                        level[v] = -1;
                        gw.set_user_label(v, string("%d", level[v]));
                        control_wait(WAIT);
                        return 1;
   
                 } 
            }

        }
    }
예제 #2
0
// iterative function to conduct breadth-first-search (bfs);
// parameters:
//    v: current node
//    g: graph to be searched in (as reference)
//    gw: Diplaying window of graph (as reference)
//    height: Node array with all heights
//    distance: distance from starting node
//    flow: Edge array with all preflows
//    capacity: Edge array with all capacities
void bfs(node v, graph &g, GraphWin &gw, node_array<int> &height, int &distance, edge_array<double> &flow, edge_array<double> &capacity) {

    gw.message("start with a bfs to determine the height");

    queue<node> fifo_queue;    // queue for next bfs node

    fifo_queue.push(v); // add the starting node
    
    //gw.set_user_label(v, string("%d (%d)", distance, height[v]));  // Display bfs number
    //gw.set_color(v, red);                           // Color node in red
    //gw.redraw();                                  // Update displayed graph
    //control_wait(WAIT);                              // Wait for 0.5 sec 
    distance++;


    // loop through all queue elements and add all childs to queue
    // also add some graphical hints
    do {

        v = fifo_queue.pop(); // pop first element of search queue
        //gw.set_color(v, green); // current node of queue, mark it green
        //control_wait(WAIT); // Wait for 0.5sec

        edge e;
        forall_in_edges(e, v) {  // all neighbour nodes of v
            if (flow[e] != capacity[e]) {
                node w = g.opposite(v, e); // neighbour node on the other side of edge e
                if (height[w] < 0) { // if node w has not been visited yet
                    height[w] = height[v]+1; // assign to current node last assigned bfs number incremented by one
                    //gw.set_color(e, red);     // color edge in red     
                    //gw.set_color(w, red);	// color node in red
                    //gw.set_width(e, 2);           
                    //gw.set_user_label(w, string("%d (%d)", distance++, height[w])); // display order first, in brackets distance to starting node
                    fifo_queue.append(w); // add the child node to the queue
                    //control_wait(WAIT);             // Wait for 0.5 sec 
                } else {    // if node w has already been visited
                    if (height[w] < height[v]) { // Backward edge
                        //if (gw.get_color(e) == red){ // check, if edge is the connection between parent and child node
			            //    gw.set_color(e, blue); // color edge in blue
			                //gw.set_width(e, 2);
			                //control_wait(WAIT); // wait for 0.5 sec
		                //} else {
                        //     gw.set_color(e, green);
                        //} 
                    } else { // edge to a node in queue
                        //gw.set_color(e, green); // color edge 
                        //gw.set_width(e, 2);
                        //control_wait(WAIT); // wait for 0.5 sec
                    }
                }
            } else {
                //gw.set_color(e, violet);
                //control_wait(WAIT);
            }
        }
        //gw.set_color(v, blue); // Color node in blue
        //control_wait(WAIT); // wait for 0.5 sec
        //gw.redraw();
	    // Update displayed graph (to ensure correct updation)
    } while (!fifo_queue.empty());  // loop until queue is empty
}