bool are_uwv_ok(const VertexListGraph& graph, Vertex uwv[]) { // Checking whether the FIRST and THIRD are not heighbors. typedef typename graph_traits<VertexListGraph>::adjacency_iterator AdjIterator; AdjIterator n_v, n_vend; for(tie(n_v, n_vend) = adjacent_vertices(uwv[FIRST], graph); n_v != n_vend; ++n_v) { if(uwv[THIRD] == *n_v) return false; } // Removing FIRST and THIRD, then checking whether graph remains connected. VertexListGraph temp_graph; copy_graph(graph, temp_graph); clear_vertex(uwv[FIRST], temp_graph); clear_vertex(uwv[THIRD], temp_graph); remove_vertex(uwv[FIRST], temp_graph); remove_vertex(uwv[THIRD], temp_graph); return is_graph_connected(temp_graph); }
struct Node* connected_double_edge_swap(struct Node* G, int node_count, int nswap, int windows_threhold){ // this version implement the windows size. srand((unsigned int)time(NULL)); int i; struct Node* node1; struct Node* node2; struct Node* n1_rel; struct Node* n2_rel; int max_id = 0; // copy G // directly copy may be dingerous for (int i = 0; i < node_count; i++) { struct Node * n = malloc(sizeof(struct Node)); n->node_id = G[i].node_id; if (n->node_id > max_id) { max_id = n->node_id; } n->neighbour_count = G[i].neighbour_count; n->neighbours = (int *)malloc(sizeof(int) * n->neighbour_count); for (int j = 0; j < n->neighbour_count; j ++) { n->neighbours[j] = G[i].neighbours[j]; } G[i] = *n; } struct Node ** id2Node = malloc(sizeof(struct Node) * (max_id + 1)); for (int i = 0; i < max_id + 1; i ++) { id2Node[i] = NULL; } for (int i = 0; i < node_count; i ++) { id2Node[G[i].node_id] = G + i; } i = 0; struct CDF * cdf = generate_cdf(G, node_count); windows_threhold = 3; int windows = 1; // printf("\nStArT\n"); while (i < nswap) { int wcount = 0; init_heap(); if (windows < windows_threhold) { // do check every time // printf("low windows count\n"); int fail = 0; while (wcount < windows && i < nswap) { // if (i % 100000 == 0) { // printf("done: %i\n", i); // } // printf("Low: i: %i, wcount: %i, windows: %i\n", i, wcount, windows); int * picked = choose_node_from_cdf(cdf, (float)(rand()) / (float)(RAND_MAX), (float)(rand()) / (float)(RAND_MAX)); int n1 = picked[0]; int n2 = picked[1]; if (n1 == n2) { continue; } // the node may be empty? node1 = get_node_from_graph(G, node_count, n1); node2 = get_node_from_graph(G, node_count, n2); if (node1 == NULL || node2 == NULL) { printf("Oops node empty %i, %i\n", n1, n2); continue; } int ri, rj; int n_id_1 = pick_neighbour(node1, &ri); int n_id_2 = pick_neighbour(node2, &rj); n1_rel = get_node_from_graph(G, node_count, n_id_1); n2_rel = get_node_from_graph(G, node_count, n_id_2); // any NULL error and continue if (node1 == NULL || node2 == NULL || n1_rel == NULL || n2_rel == NULL) { // printf("node1 %llx, node2 %llx, n1_rel %llx n2_rel %llx\n", node1, node2, n1_rel, n2_rel); continue; } if (node1->node_id == n2_rel->node_id || node2->node_id == n1_rel->node_id || n1_rel->node_id == n2_rel->node_id) { continue; } if (is_two_node_connected(node1, node2) || is_two_node_connected(n1_rel, n2_rel)) { continue; } // now let us do the exchage // before: node1 -- n1_rel after: node1 n1_rel // | | // node2 -- n2_rel node2 n2_rel // delete edge delete_edge(node1, n1_rel); delete_edge(node2, n2_rel); // add edge add_edge(node1, node2); add_edge(n1_rel, n2_rel); i += 1; add_swap(node1->node_id, node2->node_id, n1_rel->node_id, n2_rel->node_id); // if (! is_graph_connected(G, node_count, id2Node, max_id)) { if (! is_2_node_connected(id2Node, max_id, node1->node_id, n1_rel->node_id)) { // oops let us redo // printf("Oops not connected, retry~\n"); add_edge(node1, n1_rel); add_edge(node2, n2_rel); // add edge delete_edge(node1, node2); delete_edge(n1_rel, n2_rel); fail = 1; } else{ wcount += 1; } } if (fail == 1){ windows = ceilf((float)windows / 2); }else{ windows += 1; } }else{ // printf("high windows count\n"); // do check at end while (wcount < windows && i < nswap) { // if (i % 100000 == 0) { // printf("done: %i\n", i); // } // printf("High: i: %i, wcount: %i, window: %i\n", i, wcount, windows); int * picked = choose_node_from_cdf(cdf, (float)(rand()) / (float)(RAND_MAX), (float)(rand()) / (float)(RAND_MAX)); int n1 = picked[0]; int n2 = picked[1]; if (n1 == n2) { continue; } // the node may be empty? node1 = get_node_from_graph(G, node_count, n1); node2 = get_node_from_graph(G, node_count, n2); if (node1 == NULL || node2 == NULL) { // printf("Oops node empty %i, %i\n", n1, n2); continue; } int ri, rj; int n_id_1 = pick_neighbour(node1, &ri); int n_id_2 = pick_neighbour(node2, &rj); n1_rel = get_node_from_graph(G, node_count, n_id_1); n2_rel = get_node_from_graph(G, node_count, n_id_2); // any NULL error and continue if (node1 == NULL || node2 == NULL || n1_rel == NULL || n2_rel == NULL) { // printf("node1 %llx, node2 %llx, n1_rel %llx n2_rel %llx\n", node1, node2, n1_rel, n2_rel); continue; } if (node1->node_id == n2_rel->node_id || node2->node_id == n1_rel->node_id || n1_rel->node_id == n2_rel->node_id) { continue; } if (is_two_node_connected(node1, node2) || is_two_node_connected(n1_rel, n2_rel)) { continue; } // now let us do the exchage // before: node1 -- n1_rel after: node1 n1_rel // | | // node2 -- n2_rel node2 n2_rel // delete edge delete_edge(node1, n1_rel); delete_edge(node2, n2_rel); // add edge add_edge(node1, node2); add_edge(n1_rel, n2_rel); i += 1; add_swap(node1->node_id, node2->node_id, n1_rel->node_id, n2_rel->node_id); wcount += 1; } if (is_graph_connected(G, node_count, id2Node, max_id)) { windows += 1; }else{ // then redo all // printf("Oops not connected, retry~\n"); while (1) { // printf("redo\n"); struct Swap* s = get_swap(); if (s == NULL) { break; } struct Node * reN1 = get_node_from_graph(G, node_count, s->node1); struct Node * reN2 = get_node_from_graph(G, node_count, s->node2); struct Node * reN1_rel = get_node_from_graph(G, node_count, s->node3); struct Node * reN2_rel = get_node_from_graph(G, node_count, s->node4); add_edge(reN1, reN1_rel); add_edge(reN2, reN2_rel); // add edge delete_edge(reN1, reN2); delete_edge(reN1_rel, reN2_rel); } windows = ceilf((float)windows / 2.0); } } } return G; }