/*
 * Increments which cycles are cut. If all combinations have been tried, fixes
 * the graph and returns 0. Otherwise returns 1.
 */
int inc_cycles(cycle_counter counter, graph* g, graph* f) {

   ll_node* cc = counter->counter;
   int carry = 0;
   do {

      ll_node* cycle = (ll_node*)cc->data;
      cc_node n = *(cc_node*)cycle->data;

      fix_edge(counter->g_info,g->verts + n.src,n.g_cc_i);
      fix_edge(counter->f_info,f->verts + n.dest,n.f_cc_i);

      if(cycle->next->data == NULL) {
         carry = 1;
         cc->data = cycle->next->next;
         n = *(cc_node*)cycle->next->next->data;
      } else {
         cc->data = cycle->next;
         n = *(cc_node*)cycle->next->data;
      }

      DBGP(1);
      DBGP(2);
      DBGP(3);
      delete_edge(counter->g_info,g->verts + n.src,n.g_cc_i);
      delete_edge(counter->f_info,f->verts + n.dest,n.f_cc_i);

      cc = cc->next;

   } while(carry == 1 && cc != NULL);

   return carry != 1;

}
Exemplo n.º 2
0
/*---------------------------------------------------------------------*/
void* delete_vertex(GRAPH *g, VINDEX vertex)
{
    void *user;
    EINDEX from, nfrom, to, nto;

    GR_ASSERT(is_vertex(g, vertex), "delete vertex is_vertex\n");

    user = VERTEX_user(&GRAPH_v_i(g,vertex));

    /* delete the from edges */
    from = VERTEX_from(&GRAPH_v_i(g,vertex));
    while (from != INVALID_EINDEX)
    {
        nfrom = EDGE_nfrom(&GRAPH_e_i(g,from));
        delete_edge(g, from);
        from = nfrom;
    }

    /* delete the to edges */
    to =  VERTEX_to(&GRAPH_v_i(g,vertex));
    while (to != INVALID_EINDEX)
    {
        nto = EDGE_nto(&GRAPH_e_i(g,to));
        delete_edge(g, to);
        to = nto;
    }

    VERTEX_fcnt(&GRAPH_v_i(g,vertex)) = -1;
    VERTEX_from(&GRAPH_v_i(g,vertex)) = GRAPH_vfree(g);
    GRAPH_vfree(g) = vertex;
    GRAPH_vcnt(g)--;

    return user;

}
/*
 * Cuts the initial edges from the cycle counter. Assumes that the NULL node in
 * each of the cycle's loops is not the initial node
 */
void init_cut_cycles(cycle_counter counter, graph* g, graph* f) {
   ll_node* cc = counter->counter;
   while(cc != NULL) {
      cc_node n = *(cc_node*)((ll_node*)cc->data)->data;

      delete_edge(counter->g_info,g->verts + n.src,n.g_cc_i);
      delete_edge(counter->f_info,f->verts + n.dest,n.f_cc_i);

      cc = cc->next;
   }
}
Exemplo n.º 4
0
//funkcja usuwajaca węzły
void delete_node(nodes *ptr, edges *ptr2, char i[])
{
 nodes prev;
 nodes temp;
 nodes next;
 prev=NULL;
 if(*ptr==NULL)
 {
  printf("Nie można usunać nieistniejącego wierzchołka!\n");
  return;
 }
 temp=*ptr;
 while((temp->next != NULL)&&(!compare(temp->id,i,0,0)))
 {
  prev=temp;
  temp=temp->next;
 }
 if((temp->next == NULL)&&(!compare(temp->id,i,0,0)))
 {
  printf("Nie można usunać nieistniejącego wierzchołka!\n");
  return;
 }
  while(temp->inEdges != NULL)
  {
   delete_edge(ptr2, temp->inEdges->edg->id);
  }
  while(temp->outEdges != NULL)
  {
   delete_edge(ptr2, temp->outEdges->edg->id);
  }
 char tempstr[50];
 strcpy(tempstr,i);
 if(temp != NULL)
 {
  next=temp->next;
  if(prev==NULL)
  {
   free(temp);
   *ptr=next;
  }
  else
  {
   free(temp);
   prev->next=next;
  }
 }
 printf("Węzeł %s usunięty!\n", tempstr);
}
Exemplo n.º 5
0
delete_edge(graph *g, int x, int y, bool directed)
{
	int i;				/* counter */
	edgenode *p;			/* temporary pointers */

	p = g->edges[x];
	p_back = NULL;

	while (p != NULL) 
		if (p->y == y) {
			g->degree[x] --;
			if (p_back != NULL) 
				p_back->next = p->next;
			else
				g->edges[x] = p->next;

			free(p);

			if (directed == FALSE)
				delete_edge(g,y,x,TRUE);
			else
				g->nedges --;

			return;
		}
		else
			p = p->next;

	printf("Warning: deletion(%d,%d) not found in g.\n",x,y);
}
Exemplo n.º 6
0
void recv_delete_edge(void)
{
    int i = recv_index();
    int j = recv_index();
    int k = recv_index();

    delete_edge(i, j, k);
}
Exemplo n.º 7
0
void send_delete_edge(int i, int j, int k)
{
    send_event(EVENT_DELETE_EDGE);
    send_index(i);
    send_index(j);
    send_index(k);

    delete_edge(i, j, k);
}
Exemplo n.º 8
0
static void delete_vert(int i, int j)
{
    struct object *o = get_object(i);

    int k;
    int l;

    /* Remove this vertex from the vertex vector. */

    memmove(vecget(o->vv, j),
            vecget(o->vv, j + 1), vecsiz(o->vv) * (vecnum(o->vv) - j - 1));

    vecpop(o->vv);

    /* Remove all references to this vertex from all meshes. */

    for (k = 0; k < get_mesh_count(i); ++k)
    {
        /* Delete all referencing faces.  Move later references down. */

        for (l = 0; l < get_face_count(i, k); ++l)
        {
            struct object_face *f = get_object_face(i, k, l);

            if (f->vi[0] == j || f->vi[1] == j || f->vi[2] == j)
                delete_face(i, k, l--);
            else
            {
                if (f->vi[0] > j) f->vi[0]--;
                if (f->vi[1] > j) f->vi[1]--;
                if (f->vi[2] > j) f->vi[2]--;
            }
        }

        /* Delete all referencing edges.  Move later references down. */

        for (l = 0; l < get_edge_count(i, k); ++l)
        {
            struct object_edge *e = get_object_edge(i, k, l);

            if (e->vi[0] == j || e->vi[1] == j)
                delete_edge(i, k, l--);
            else
            {
                if (e->vi[0] > j) e->vi[0]--;
                if (e->vi[1] > j) e->vi[1]--;
            }
        }
    }

    /* Invalidate the object's vertex buffer and bounding volume. */

    fini_object(i);
}
int main()
{
    int source,destination,ver;
    char option;
    v_node *head=NULL;
    while(1)
    {
        system("cls");
        printf("\t\t\t\tAdjacency List Implementation\n\n");
        printf("Choose Option :-\n\n1 - Insert Vertex\n2 - Insert Edge\n3 - Delete Edge\n4 - Delete Vertex\n5 - Display\n\tBackspace - Exit\n");
        option = getch();
        system("cls");
        switch(option)
        {
        case '1':
            printf("\t\t\t\tHere you can insert vertex\n\n");
            printf("Enter vertex to be inserted : ");
            scanf("%d",&ver);
            head=insert_vertex(head,ver);
            hold_screen();
            break;
        case '2':
            printf("\t\t\t\tHere you can insert an edge\n\n");
            printf("Enter source : ");
            scanf("%d",&source);
            printf("Enter destination : ");
            scanf("%d",&destination);
            insert_edge(head,source,destination);
            hold_screen();
            break;
        case '3':
            printf("\t\t\t\tHere you can delete an edge\n\n");
            printf("Enter source : ");
            scanf("%d",&source);
            printf("Enter destination : ");
            scanf("%d",&destination);
            delete_edge(head,source,destination);
            hold_screen();
            break;
        case '4':
            printf("Enter vertex to be deleted : ");
            scanf("%d",&ver);
            head=delete_vertex(head,ver);
            hold_screen();
            break;
        case '5':
            display(head);
            hold_screen();
            break;
        case 8:
            return 0;
        }
    }
}
Exemplo n.º 10
0
int main(){
int choice,i;
int v1,v2;
	do{
		printf("Choose the option:\n");
		printf("1.Create new empty graph\n");
		printf("2.Add edge\n");
		printf("3.Delete edge\n");
		printf("4.bfs\n");
		printf("5.dfs\n");
		printf("6.Increment graph-size\n");
		printf("7.Print list");	
		printf("Enter any other integer to exit\n");
		scanf("%d",&choice);
		printf("You entered:%d\n",choice);
		switch(choice){
			case 1:
			if(graph)
			 choice=delete_graph();
			if(choice){
				printf("Enter the initial number of nodes you want in the graph\n");
				scanf("%d",&node_count);
				graph=(node**)malloc(node_count*sizeof(node*));
				if(graph){
					printf("Empty graph of size:%d created\n",node_count);
					for(i=0;i<node_count;i++){
					graph[i]=(node*)malloc(sizeof(node));
					graph[i]->data=i;
					graph[i]->next=NULL;
					}
					break;
				}
				printf("Error allocating memory for empty graph of size:%d,try again...\n",node_count);
				break;	
			}
			case 2:
				if(!graph){
					printf("First Create a new empty graph\n");
					break;
				}
				printf("Enter the two vertices to add edge between them\n");
				scanf("%d%d",&v1,&v2);
				add_edge(v1,v2);
				break;
			case 3:
				if(!graph){
					printf("First Create a new empty graph\n");
					break;
				}
				printf("Enter the two vertices to delete edge between them\n");
				scanf("%d%d",&v1,&v2);
				delete_edge(v1,v2);
				break;
			case 4:
				if(!graph){
					printf("First Create a new empty graph\n");
					break;
				}
				printf("Enter the vertex to start bfs from\n");
				scanf("%d",&v1);
				bfs(v1);
				break;
			case 5:
				if(!graph){
					printf("First Create a new empty graph\n");
					break;
				}
				printf("Enter the vertex to start dfs from\n");
				scanf("%d",&v1);
				dfs(v1);
				break;
			case 6:
				if(!graph){
					printf("First Create a new empty graph\n");
					break;
				}
				printf("Enter the new size of the graph you want\n");
				scanf("%d",&choice);
				increment_graphsize(choice);
				break;
			case 7:
				if(!graph){
					printf("First Create a new empty graph\n");
					break;
				}
				print_list();
				break;
			default:
				printf("Exiting\n");
				return 0;
		}
	}while(true);
return 0;
}
Exemplo n.º 11
0
int main()
{
    int n,ans,a,b;
    node* start=NULL;
    do
    {
        printf("\n---------Directed Graph------------");
        printf("\n1.Insertnode");
        printf("\n2.Insertedge");
        printf("\n3.Deletenode");
        printf("\n4.Deleteedge");
        printf("\n5.Display-nodes");
        printf("\n6.Exit\n");
        printf("\nEnter your choice:");
        scanf("%d",&ans);
        fflush(stdin);
        switch(ans)
        {
        case 1:
            printf("\nEnter the value to be inserted:");
            fflush(stdin);
            scanf("%c",&n);
            fflush(stdin);
            insertnode(&start,n);
            break;
        case 2:
            printf("\nEnter the start point of edge:");
            fflush(stdin);
            scanf("%c",&a);
            fflush(stdin);
            printf("\nEnter the end point of edge:");
            scanf("%c",&b);
            fflush(stdin);
            insertedge(start,a,b);
            break;

        case 3:
            printf("Enter the value to be deleted-->");
            fflush(stdin);
            scanf("%c",&n);
            fflush(stdin);
            delete_node(&start,n);
            break;
        case 4:
            printf("\nEnter the start point of edge:");
            fflush(stdin);
            scanf("%c",&a);
            fflush(stdin);
            printf("\nEnter the end point of edge:");
            scanf("%c",&b);
            fflush(stdin);
            delete_edge(start,a,b);
            break;
        case 5:
            printf("\nDisplaying node of the graph using breadth first traversal: \n");
            bfs_disp(start);
            break;
        case 6:
            break;
        }

    }
    while(ans!=6);
    return 0;
}
Exemplo n.º 12
0
// outputs the edge_pair (le, re)
// le: counterclockwise convex hull edge out of the leftmost vertex
// re: clockwise convex hull edge out of the rightmost vertex
edge_pair delaunay_dc(vertex v[], size_t n, vertex_buffer p) {
    // assumes that v is sorted in lexicographic order
    edge_pair ldo_ldi, rdi_rdo;
    edge a, b, c, ldo, ldi, rdo, rdi, basel, lcand, rcand, temp;
    vertex *v_l, *v_r;
    size_t v_l_n, v_r_n;
    bool lcand_valid, rcand_valid;

    if (n == 2) { 
        // for two vertices, return the two directed edges between them
        a = make_edge(v[0], v[1]);
        return edge_pair(a, a.sym());

    } else if (n == 3) {
        // for three vertices
        a = make_edge();
        b = make_edge();
        splice(a.sym(), b);
        a.set_org(v[0]);
        a.set_dst(v[1]);
        b.set_org(v[1]);
        b.set_dst(v[2]);
        if (p.orient2d(v[0], v[1], v[2]) > 0) {
            c = connect(b, a);
            return edge_pair(a, b.sym());
        } else if (p.orient2d(v[0], v[2], v[1]) > 0) {
            c = connect(b, a);
            return edge_pair(c.sym(), c);
        } else { // the points are collinear
            return edge_pair(a, b.sym());
        }

    } else { // n >= 4
        // divide v into left half v_l, right half v_r
        v_l = v;
        v_l_n = n/2;
        v_r = (v + v_l_n);
        v_r_n = (n - v_l_n);

        ldo_ldi = delaunay_dc(v_l, v_l_n, p);
        ldo = ldo_ldi[0];
        ldi = ldo_ldi[1];
        rdi_rdo = delaunay_dc(v_r, v_r_n, p);
        rdi = rdi_rdo[0];
        rdo = rdi_rdo[1];

        // loop to compute lower common tangent of l and r
        while (true) {
            if (p.leftof(rdi.org(), ldi.org(), ldi.dst())) {
                ldi = ldi.lnext();
            } else if (p.rightof(ldi.org(), rdi.org(), rdi.dst())) {
                //rdi = rdi.rprev(); // Guibas and Stolfi wrong here?
                rdi = rdi.rnext();
            } else {
                break;
            }
        }

        // create the first cross edge basel from rdi.org to ldi.org
        basel = connect(rdi.sym(), ldi);
        if (ldi.org() == ldo.org()) {
            ldo = basel.sym();
        }
        if (rdi.org() == rdo.org()) {
            rdo = basel;
        }

        // merge loop
        while (true) {
            // is lcand valid?
            lcand = basel.sym().onext();
            lcand_valid = p.rightof(lcand.dst(), basel.org(), basel.dst());
            if (lcand_valid) {
                while (p.incircle(basel.dst(), basel.org(), lcand.dst(), lcand.onext().dst()) > 0) {
                    temp = lcand.onext();
                    delete_edge(lcand);
                    lcand = temp;
                }
            }
            // is rcand valid?
            rcand = basel.oprev();
            rcand_valid = p.rightof(rcand.dst(), basel.org(), basel.dst());
            if (rcand_valid) {
                while (p.incircle(basel.dst(), basel.org(), rcand.dst(), rcand.oprev().dst()) > 0) {
                    temp = rcand.oprev();
                    delete_edge(rcand);
                    rcand = temp;
                }
            }

            lcand_valid = p.rightof(lcand.dst(), basel.org(), basel.dst());
            rcand_valid = p.rightof(rcand.dst(), basel.org(), basel.dst());
            // if both lcand and rcand are invalid, 
            // then basel is the upper common tangent
            // ... break out of merge loop
            if ((not lcand_valid) and (not rcand_valid)) {
                break;
            }

            // the next cross edge is to be connected to either 
            // lcand.dst() or rcand.dst() 
            // if both valid, choose the appropriate one using incircle test
            if ((not lcand_valid) or ((rcand_valid and 
                (p.incircle(lcand.dst(), lcand.org(), rcand.org(), rcand.dst())) > 0))) {
                // add cross edge basel from rcand.dst() to basel.dst()
                basel = connect(rcand, basel.sym());
            } else {
                // add cross edge basel from basel.org() to lcand.dst()
                basel = connect(basel.sym(), lcand.sym());
            }
        }

        return edge_pair(ldo, rdo);
    }
}
Exemplo n.º 13
0
// Write another function delete_self_loops( g ) that uses del_edge to
// delete all self-loops from the graph
inline void delete_self_loops( graph& g )
{
    for ( vertex_id u = 0, n = count_vertices( g ); u != n; ++u )
        delete_edge(g, u, u);
}
Exemplo n.º 14
0
edge_pair delaunay_dc2(vertex v[], size_t n, bool div_by_x, vertex_buffer p) {
    edge_pair ldo_ldi, rdi_rdo;
    edge a, b, c, ldo, ldi, rdo, rdi, basel, lcand, rcand, temp;
    vertex *v_l, *v_r;
    size_t median, v_l_n, v_r_n;
    bool lcand_valid, rcand_valid;

    if (n == 2) { 
        // for two vertices, return the two directed edges between them
        if (point_lte(p.val(v[0]), p.val(v[1]), div_by_x)) {
            a = make_edge(v[0], v[1]);
        } else {
            a = make_edge(v[1], v[0]);
        }
        return edge_pair(a, a.sym());

    } else if (n == 3) {
        // for three vertices
        a = make_edge();
        b = make_edge();
        splice(a.sym(), b);

        // order the vertices on the right axis
        bool zero_lte_one = point_lte(p.val(v[0]), p.val(v[1]), div_by_x);
        bool one_lte_two = point_lte(p.val(v[1]), p.val(v[2]), div_by_x);
        bool two_lte_zero = point_lte(p.val(v[2]), p.val(v[0]), div_by_x);
        vertex first, second, third;
        if (zero_lte_one) {
            if (one_lte_two) {
                first = v[0]; 
                second = v[1]; 
                third = v[2];
            } else {
                if (two_lte_zero) {
                    first = v[2];
                    second = v[0];
                    third = v[1];
                } else {
                    first = v[0];
                    second = v[2];
                    third = v[1];
                }
            }
        } else {
            if (one_lte_two) {
                if (two_lte_zero) {
                    first = v[1];
                    second = v[2];
                    third = v[0];
                } else {
                    first = v[1];
                    second = v[0];
                    third = v[2];
                }
            } else {
                first = v[2];
                second = v[1];
                third = v[0];
            }
        }
        a.set_org(first);
        a.set_dst(second);
        b.set_org(second);
        b.set_dst(third);
        if (p.orient2d(first, second, third) > 0) {
            c = connect(b, a);
            return edge_pair(a, b.sym());
        } else if (p.orient2d(first, third, second) > 0) {
            c = connect(b, a);
            return edge_pair(c.sym(), c);
        } else { // the points are collinear
            return edge_pair(a, b.sym());
        }

    } else { // n >= 4
        // div_by_x tells whether this recursive case is splitting by x
        // divide v into left half v_l, right half v_r
        median = lexico_partition(v, n, div_by_x, p);
        v_l = v;
        v_l_n = median + 1; // +1 ensures that the lower partition has >=2
        v_r = (v + v_l_n);
        v_r_n = (n - v_l_n);


        // recursive calls split in opposite axis; *do and *di are flipped!
        // must merge on the current axis, however
        ldo_ldi = delaunay_dc2(v_l, v_l_n, !div_by_x, p);
        ldo = ldo_ldi[0]; // ccw, so right face is open
        ldi = ldo_ldi[1]; // cw, so left face is open
        rdi_rdo = delaunay_dc2(v_r, v_r_n, !div_by_x, p);
        rdi = rdi_rdo[0]; // ccw, so right face is open
        rdo = rdi_rdo[1]; // cw, so left face is open

        // move *di, *do into the correct "leftmost", "rightmost" for level
        if (div_by_x) {
            while (point_lte(p.val(ldo.rprev().org()), p.val(ldo.org()), 
                    div_by_x)) {
                ldo = ldo.rprev();
            }
            while (point_lte(p.val(ldi.org()), p.val(ldi.lnext().org()), 
                    div_by_x)) {
                ldi = ldi.lnext();
            }
            while (point_lte(p.val(rdi.rprev().org()), p.val(rdi.org()), 
                    div_by_x)) {
                rdi = rdi.rprev();
            }
            while (point_lte(p.val(rdo.org()), p.val(rdo.lnext().org()), 
                    div_by_x)) {
                rdo = rdo.lnext();
            }
        } else {
            while (point_lte(p.val(ldo.rnext().org()), p.val(ldo.org()), 
                    div_by_x)) {
                ldo = ldo.rnext();
            }
            while (point_lte(p.val(ldi.org()), p.val(ldi.lprev().org()), 
                    div_by_x)) {
                ldi = ldi.lprev();
            }
            while (point_lte(p.val(rdi.rnext().org()), p.val(rdi.org()), 
                    div_by_x)) {
                rdi = rdi.rnext();
            }
            while (point_lte(p.val(rdo.org()), p.val(rdo.lprev().org()), 
                    div_by_x)) {
                rdo = rdo.lprev();
            }
        }

        // loop to compute lower common tangent of l and r
        while (true) {
            if (p.leftof(rdi.org(), ldi.org(), ldi.dst())) {
                ldi = ldi.lnext();
            } else if (p.rightof(ldi.org(), rdi.org(), rdi.dst())) {
                //rdi = rdi.rprev(); // Guibas and Stolfi wrong here?
                rdi = rdi.rnext();
            } else {
                break;
            }
        }

        // create the first cross edge basel from rdi.org to ldi.org
        basel = connect(rdi.sym(), ldi);
        if (ldi.org() == ldo.org()) {
            ldo = basel.sym();
        }
        if (rdi.org() == rdo.org()) {
            rdo = basel;
        }

        // merge loop
        while (true) {
            // is lcand valid?
            lcand = basel.sym().onext();
            lcand_valid = p.rightof(lcand.dst(), basel.org(), basel.dst());
            if (lcand_valid) {
                while (p.incircle(basel.dst(), basel.org(), lcand.dst(), lcand.onext().dst()) > 0) {
                    temp = lcand.onext();
                    delete_edge(lcand);
                    lcand = temp;
                }
            }
            // is rcand valid?
            rcand = basel.oprev();
            rcand_valid = p.rightof(rcand.dst(), basel.org(), basel.dst());
            if (rcand_valid) {
                while (p.incircle(basel.dst(), basel.org(), rcand.dst(), rcand.oprev().dst()) > 0) {
                    temp = rcand.oprev();
                    delete_edge(rcand);
                    rcand = temp;
                }
            }
            lcand_valid = p.rightof(lcand.dst(), basel.org(), basel.dst());
            rcand_valid = p.rightof(rcand.dst(), basel.org(), basel.dst());
            // if both lcand and rcand are invalid, 
            // then basel is the upper common tangent
            // ... break out of merge loop
            if ((not lcand_valid) and (not rcand_valid)) {
                break;
            }

            // the next cross edge is to be connected to either 
            // lcand.dst() or rcand.dst() 
            // if both valid, choose the appropriate one using incircle test
            if ((not lcand_valid) or ((rcand_valid and 
                (p.incircle(lcand.dst(), lcand.org(), rcand.org(), rcand.dst())) > 0))) {
                // add cross edge basel from rcand.dst() to basel.dst()
                basel = connect(rcand, basel.sym());
            } else {
                // add cross edge basel from basel.org() to lcand.dst()
                basel = connect(basel.sym(), lcand.sym());
            }
        }

        return edge_pair(ldo, rdo);
    }
}
Exemplo n.º 15
0
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;
}
Exemplo n.º 16
0
// Write another function delete_self_loops( g ) that uses del_edge to
// delete all self-loops from the edge_list
inline void delete_self_loops( adjacency_list& g )
{
    for ( vertex_id u = 0, n = count_vertices( g ); u != n; ++u )
        delete_edge(g, u, u);
}
Exemplo n.º 17
0
/* 
 * The merge function is where most of the work actually gets done. It is
 * written as one (longish) function for speed.
 */
static void merge(edge * r_cw_l, point * s, edge * l_ccw_r, point * u,
                  edge ** l_tangent)
{
    edge *base, *l_cand, *r_cand;
    point *org_base, *dest_base;
    double u_l_c_o_b, v_l_c_o_b, u_l_c_d_b, v_l_c_d_b;
    double u_r_c_o_b, v_r_c_o_b, u_r_c_d_b, v_r_c_d_b;
    double c_p_l_cand, c_p_r_cand;
    double d_p_l_cand, d_p_r_cand;
    boolean above_l_cand, above_r_cand, above_next, above_prev;
    point *dest_l_cand, *dest_r_cand;
    double cot_l_cand = 0, cot_r_cand = 0;
    edge *l_lower, *r_lower;
    point *org_r_lower, *org_l_lower;

    /* Create first cross edge by joining lower common tangent */
    lower_tangent(r_cw_l, s, l_ccw_r, u, &l_lower, &org_l_lower, &r_lower,
                  &org_r_lower);
    base = join(l_lower, org_l_lower, r_lower, org_r_lower, side::right);
    org_base = org_l_lower;
    dest_base = org_r_lower;

    /* Need to return lower tangent. */
    *l_tangent = base;

    /* Main merge loop */
    do {
        /* Initialise l_cand and r_cand */
        l_cand = Next(base, org_base);
        r_cand = Prev(base, dest_base);
        dest_l_cand = Other_point(l_cand, org_base);
        dest_r_cand = Other_point(r_cand, dest_base);

        /* Vectors for above and "in_circle" tests. */
        Vector(dest_l_cand, org_base, u_l_c_o_b, v_l_c_o_b);
        Vector(dest_l_cand, dest_base, u_l_c_d_b, v_l_c_d_b);
        Vector(dest_r_cand, org_base, u_r_c_o_b, v_r_c_o_b);
        Vector(dest_r_cand, dest_base, u_r_c_d_b, v_r_c_d_b);

        /* Above tests. */
        c_p_l_cand =
            Cross_product_2v(u_l_c_o_b, v_l_c_o_b, u_l_c_d_b, v_l_c_d_b);
        c_p_r_cand =
            Cross_product_2v(u_r_c_o_b, v_r_c_o_b, u_r_c_d_b, v_r_c_d_b);
        above_l_cand = c_p_l_cand > 0.0;
        above_r_cand = c_p_r_cand > 0.0;
        if (!above_l_cand && !above_r_cand)
            break;              /* Finished. */

        /* Advance l_cand ccw, deleting the old l_cand edge, until the 
           "in_circle" test fails. */
        if (above_l_cand) {
            double u_n_o_b, v_n_o_b, u_n_d_b, v_n_d_b;
            double c_p_next, d_p_next, cot_next;
            edge *next;
            point *dest_next;

            d_p_l_cand =
                Dot_product_2v(u_l_c_o_b, v_l_c_o_b, u_l_c_d_b, v_l_c_d_b);
            cot_l_cand = d_p_l_cand / c_p_l_cand;

            do {
                next = Next(l_cand, org_base);
                dest_next = Other_point(next, org_base);
                Vector(dest_next, org_base, u_n_o_b, v_n_o_b);
                Vector(dest_next, dest_base, u_n_d_b, v_n_d_b);
                c_p_next =
                    Cross_product_2v(u_n_o_b, v_n_o_b, u_n_d_b, v_n_d_b);
                above_next = c_p_next > 0.0;

                if (!above_next)
                    break;      /* Finished. */

                d_p_next =
                    Dot_product_2v(u_n_o_b, v_n_o_b, u_n_d_b, v_n_d_b);
                cot_next = d_p_next / c_p_next;

                if (cot_next > cot_l_cand)
                    break;      /* Finished. */

                delete_edge(l_cand);
                l_cand = next;
                cot_l_cand = cot_next;

            } while (TRUE);
        }

        /* Now do the symmetrical for r_cand */
        if (above_r_cand) {
            double u_p_o_b, v_p_o_b, u_p_d_b, v_p_d_b;
            double c_p_prev, d_p_prev, cot_prev;
            edge *prev;
            point *dest_prev;

            d_p_r_cand =
                Dot_product_2v(u_r_c_o_b, v_r_c_o_b, u_r_c_d_b, v_r_c_d_b);
            cot_r_cand = d_p_r_cand / c_p_r_cand;

            do {
                prev = Prev(r_cand, dest_base);
                dest_prev = Other_point(prev, dest_base);
                Vector(dest_prev, org_base, u_p_o_b, v_p_o_b);
                Vector(dest_prev, dest_base, u_p_d_b, v_p_d_b);
                c_p_prev =
                    Cross_product_2v(u_p_o_b, v_p_o_b, u_p_d_b, v_p_d_b);
                above_prev = c_p_prev > 0.0;

                if (!above_prev)
                    break;      /* Finished. */

                d_p_prev =
                    Dot_product_2v(u_p_o_b, v_p_o_b, u_p_d_b, v_p_d_b);
                cot_prev = d_p_prev / c_p_prev;

                if (cot_prev > cot_r_cand)
                    break;      /* Finished. */

                delete_edge(r_cand);
                r_cand = prev;
                cot_r_cand = cot_prev;

            } while (TRUE);
        }

        /*
         * Now add a cross edge from base to either l_cand or r_cand. 
         * If both are valid choose on the basis of the in_circle test. 
         * Advance base and whichever candidate was chosen.
         */
        dest_l_cand = Other_point(l_cand, org_base);
        dest_r_cand = Other_point(r_cand, dest_base);
        if (!above_l_cand
            || (above_l_cand && above_r_cand && cot_r_cand < cot_l_cand)) {
            /* Connect to the right */
            base = join(base, org_base, r_cand, dest_r_cand, side::right);
            dest_base = dest_r_cand;
        } else {
            /* Connect to the left */
            base = join(l_cand, dest_l_cand, base, dest_base, side::right);
            org_base = dest_l_cand;
        }

    } while (TRUE);
}