// 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 ¤t_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; } } } }
// 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 }