static int count_all_crossings(nodelist_t * list, Agraph_t * subg) { nodelistitem_t *item; edgelist *openEdgeList = init_edgelist(); Agnode_t *n; Agedge_t *e; int crossings = 0; int order = 1; for (n = agfstnode(subg); n; n = agnxtnode(subg, n)) { for (e = agfstout(subg, n); e; e = agnxtout(subg, e)) { EDGEORDER(e) = 0; } } for (item = list->first; item; item = item->next) { n = item->curr; for (e = agfstedge(subg, n); e; e = agnxtedge(subg, e, n)) { if (EDGEORDER(e) > 0) { edgelistitem *eitem; Agedge_t *ep; for (eitem = (edgelistitem *) dtfirst(openEdgeList); eitem; eitem = (edgelistitem *) dtnext(openEdgeList, eitem)) { ep = eitem->edge; if (EDGEORDER(ep) > EDGEORDER(e)) { if ((ep->head != n) && (ep->tail != n)) crossings++; } } remove_edge(openEdgeList, e); } } for (e = agfstedge(subg, n); e; e = agnxtedge(subg, e, n)) { if (EDGEORDER(e) == 0) { EDGEORDER(e) = order; add_edge(openEdgeList, e); } } order++; } free_edgelist(openEdgeList); return crossings; }
static void dfs(Agraph_t * g, Agnode_t * u, bcstate * stp, Agnode_t * parent) { Agnode_t *v; Agedge_t *e; Agedge_t *ep; Agraph_t *sg; stp->count++; Low(u) = N(u) = stp->count; for (e = agfstedge(g, u); e; e = agnxtedge(g, e, u)) { if ((v = aghead(e)) == u) v = agtail(e); if (v == u) continue; if (N(v) == 0) { push(&stp->stk, e); dfs(g, v, stp, u); Low(u) = min(Low(u), Low(v)); if (Low(v) >= N(u)) { /* u is an articulation point */ Cut(u) = 1; sg = mkBlock(g, stp); do { ep = pop(&stp->stk); agsubnode(sg, aghead(ep), 1); agsubnode(sg, agtail(ep), 1); } while (ep != e); } } else if (parent != v) { Low(u) = min(Low(u), N(v)); if (N(v) < N(u)) push(&stp->stk, e); } } }
grafo le_grafo(FILE *input) { int i; Agnode_t *v; Agedge_t *a; Agraph_t *g_cgraph; g_cgraph = agread(input, NULL); if ( !g_cgraph ) return NULL; // Cria grafo grafo g = (grafo) malloc(sizeof(struct grafo)); g->tipo = agisdirected(g_cgraph); g->vertice = (vertice_t) malloc(agnnodes(g_cgraph) * sizeof(struct vertice_t)); //Copia nome do grafo g->nome = (char *) malloc(strlen(agnameof(g_cgraph))+1); strcpy(g->nome, agnameof(g_cgraph)); if (!g->vertice) return NULL; i = 0; // Copia vertices for (v=agfstnode(g_cgraph ); v; v=agnxtnode(g_cgraph ,v), i++) { // copia nome g->vertice[i].nome = (char *) malloc(strlen(agnameof(v))+1); strcpy(g->vertice[i].nome, agnameof(v)); // inicializa lista de arestas g->vertice[i].aresta = NULL; // seta next vertice if (i != agnnodes(g_cgraph) - 1) g->vertice[i].next = &g->vertice[i+1]; //set atribute Agnodeinfo_t *p; p = (Agnodeinfo_t*) agbindrec(v,"Agnodeinfo_t",sizeof(Agnodeinfo_t),TRUE); p->ref_v = &g->vertice[i]; } g->vertice[i-1].next = NULL; //Copia arestas i = 0; for (v=agfstnode(g_cgraph); v; v=agnxtnode(g_cgraph,v), i++) { if (g->tipo == NAODIRECIONADO){ for (a=agfstedge(g_cgraph,v); a; a=agnxtedge(g_cgraph,a,v)) add_aresta(g, &g->vertice[i], v, a); } else { for (a=agfstout(g_cgraph,v); a; a=agnxtout(g_cgraph,a)) add_aresta(g, &g->vertice[i], v, a); } } free(g_cgraph); return g; }
void dot_sameports (graph_t* g) /* merge edge ports in G */ { node_t *n; edge_t *e; char *id; same_t same[MAXSAME]; int i; E_samehead = agfindattr(g->proto->e,"samehead"); E_sametail = agfindattr(g->proto->e,"sametail"); if (!(E_samehead || E_sametail)) return; for (n = agfstnode(g); n; n = agnxtnode(g,n)) { n_same = 0; for (e = agfstedge(g,n); e; e = agnxtedge(g,e,n)) { if (e->head==n && E_samehead && (id = agxget (e, E_samehead->index))[0]) sameedge (same, n, e, id); else if (e->tail==n && E_sametail && (id = agxget (e, E_sametail->index))[0]) sameedge (same, n, e, id); } for (i=0; i<n_same; i++) { if (same[i].l.size>1) sameport (n, &same[i].l, same[i].arr_len); free_list(same[i].l); /* I sure hope I don't need to free the char* id */ } } }
/* degreeKind; * Returns degree of n ignoring loops and multiedges. * Returns 0, 1 or many (2) * For case of 1, returns other endpoint of edge. */ static int degreeKind(graph_t * g, node_t * n, node_t ** op) { edge_t *ep; int deg = 0; node_t *other = NULL; for (ep = agfstedge(g, n); ep; ep = agnxtedge(g, ep, n)) { if (ep->head == ep->tail) continue; /* ignore loops */ if (deg == 1) { if (((ep->tail == n) && (ep->head == other)) || /* ignore multiedge */ ((ep->tail == other) && (ep->head == n))) continue; return 2; } else { /* deg == 0 */ if (ep->tail == n) other = ep->head; else other = ep->tail; *op = other; deg++; } } return deg; }
static void adjust_anchors(Agraph_t* g, int* anchors, int k, mat z) { int i, j; double* centroid = (double*) malloc(sizeof(double)*z->c); for(i = 0; i < k; i++) { Agnode_t* n = get_node(anchors[i]); Agedge_t* e; int degree = 0; for(j = 0; j < z->c; j++) { centroid[j] = 0; } for(e = agfstedge(g,n); e; e = agnxtedge(g,e,n)) { int v = (n == aghead(e)) ? getid(agtail(e)) : getid(aghead(e)); for(j = 0; j < z->c; j++) { centroid[j] += z->m[mindex(v,j,z)]; } degree++; } for(j = 0; j < z->c; j++) { if(degree != 0) centroid[j] /= degree; z->m[mindex(anchors[i],j,z)] = centroid[j]; } } free(centroid); }
//------------------------------------------------------------------------------ static void guarda_arestas(Agraph_t *g, Agnode_t *v) { for (Agedge_t *a=agfstedge(g,v); a; a=agnxtedge(g,a,v)) if ( ! busca_aresta(a) ) insere_lista(a, lista_arestas); }
/* remove_pair_edges: * Create layout skeleton of ing. * Why is returned graph connected? */ static Agraph_t *remove_pair_edges(Agraph_t * ing) { int counter = 0; int nodeCount; Agraph_t *outg; Agraph_t *g; deglist_t *dl; Agnode_t *currnode, *adjNode; Agedge_t *e; outg = clone_graph(ing, &g); nodeCount = agnnodes(g); dl = getList(g); while (counter < (nodeCount - 3)) { currnode = firstDeglist(dl); /* Remove all adjacent nodes since they have to be reinserted */ for (e = agfstedge(g, currnode); e; e = agnxtedge(g, e, currnode)) { adjNode = e->head; if (currnode == adjNode) adjNode = e->tail; removeDeglist(dl, adjNode); } find_pair_edges(g, currnode, outg); for (e = agfstedge(g, currnode); e; e = agnxtedge(g, e, currnode)) { adjNode = e->head; if (currnode == adjNode) adjNode = e->tail; DEGREE(adjNode)--; insertDeglist(dl, adjNode); } agdelete(g, currnode); counter++; } agclose(g); freeDeglist(dl); return outg; }
/* find_longest_path: * Find and return longest path in tree. */ static nodelist_t* find_longest_path(Agraph_t* tree) { Agnode_t* n; Agedge_t* e; Agnode_t* common = 0; nodelist_t* path; nodelist_t* endPath; int maxlength = 0; int length; if (agnnodes(tree) == 1) { path = mkNodelist(); n = agfstnode(tree); appendNodelist(path, NULL, n); SET_ONPATH(n); return path; } for(n = agfstnode(tree); n; n = agnxtnode(tree, n)) { int count = 0; for(e = agfstedge(tree, n); e; e = agnxtedge(tree, e, n)) { count++; } if(count == 1) measure_distance(n, n, 0, NULL); } /* find the branch node rooted at the longest path */ for(n = agfstnode(tree); n; n = agnxtnode(tree, n)) { length = DISTONE(n) + DISTTWO(n); if(length > maxlength) { common = n; maxlength = length; } } path = mkNodelist(); for (n = LEAFONE(common); n != common; n = TPARENT(n)) { appendNodelist(path, NULL, n); SET_ONPATH(n); } appendNodelist(path, NULL, common); SET_ONPATH(common); if (DISTTWO(common)) { /* 2nd path might be empty */ endPath = mkNodelist(); for (n = LEAFTWO(common); n != common; n = TPARENT(n)) { appendNodelist(endPath, NULL, n); SET_ONPATH(n); } reverseAppend(path, endPath); } return path; }
static void flat_edges(Agraph_t *clust) { #ifdef NOTDEF for (n = agfstnode(clust); n; n = agnxtnode(clust)) { for (e = agfstedge(root,n); e; e = agnxtedge(root,e,n)) { } } ordered_edges(); #endif }
/* * attach and install edges between clusters. * essentially, class2() for interclust edges. */ void interclexp(graph_t* subg) { graph_t *g; node_t *n; edge_t *e,*prev; g = subg->root; for (n = agfstnode(subg); n; n = agnxtnode(subg,n)) { /* N.B. n may be in a sub-cluster of subg */ prev = NULL; for (e = agfstedge(subg->root,n); e; e = agnxtedge(subg->root,e,n)) { if (agcontains(subg,e)) continue; /* short/flat multi edges */ if (mergeable(prev,e)) { if (e->tail->u.rank == e->head->u.rank) e->u.to_virt = prev; else e->u.to_virt = NULL; if (prev->u.to_virt == NULL) continue; /* internal edge */ merge_chain(subg,e,prev->u.to_virt,FALSE); safe_other_edge(e); continue; } /* flat edges */ if (e->tail->u.rank == e->head->u.rank) { if (find_flat_edge(e->tail,e->head) == NULL) { flat_edge(g,e); prev = e; } else prev = NULL; continue; } assert (e->u.to_virt != NULL); /* forward edges */ if (e->head->u.rank > e->tail->u.rank) { make_interclust_chain(g,e->tail,e->head,e); prev = e; continue; } /* backward edges */ else { /* I think that make_interclust_chain should create call other_edge(e) anyway if (agcontains(subg,e->tail) && agfindedge(subg->root,e->head,e->tail)) other_edge(e); */ make_interclust_chain(g,e->head,e->tail,e); prev = e; } } } }
static void deleteNodeEdges(gctx_t *gctx, Agraph_t *g, Agnode_t *n) { Agedge_t *e, *e1; e = agfstedge(g, n); while (e) { e1 = agnxtedge(g, e, n); deleteEdge(gctx, g, e); e = e1; } }
//------------------------------------------------------------------------------ long int *obter_matriz_adjacencia(Agraph_t *g, vertice lista_vertices, int grafo_ponderado, int grafo_direcionado, unsigned int n_vertices) { Agedge_t *a; Agnode_t *v; long int *matriz = NULL; char *peso; char peso_string[] = "peso"; unsigned i; int cauda_indice, cabeca_indice; if(n_vertices > 0) { /* Aloca a quantidade de memória necessária para armazenar todas as arestas */ matriz = (long int *) malloc(sizeof(long int) * n_vertices * n_vertices); if(matriz != NULL) { /* Inicializa a matriz */ for(i = 0; i < n_vertices * n_vertices; ++i) { matriz[i] = 0; } /* Percorre todas as arestas do grafo */ for(v = agfstnode(g); v != NULL; v = agnxtnode(g, v)) { for(a = agfstedge(g, v); a != NULL; a = agnxtedge(g, a, v)) { /* Obtêm os vértices de origem e destino da aresta */ cauda_indice = encontra_vertice(lista_vertices, n_vertices, agnameof(agtail(a))); cabeca_indice = encontra_vertice(lista_vertices, n_vertices, agnameof(aghead(a))); /* Caso não sejam encontrados, retorna com um erro */ if(cauda_indice == -1 || cabeca_indice == -1) { free(matriz); return NULL; } /* Se o grafo é ponderado, armazena o valor do peso (se existir) na matriz, caso contrário armazena o valor 1 */ if(grafo_ponderado == 1) { peso = agget(a, peso_string); matriz[cauda_indice * (int) n_vertices + cabeca_indice] = (peso != NULL && *peso != '\0') ? atol(peso) : 0; } else { matriz[cauda_indice * (int) n_vertices + cabeca_indice] = 1; } /* Se o grafo não é direcionado, então M[i,j] = M[j,i] */ if(grafo_direcionado != 1) { matriz[cabeca_indice * (int) n_vertices + cauda_indice] = matriz[cauda_indice * (int) n_vertices + cabeca_indice]; } } } } } return matriz; }
static void cc_dfs(Agraph_t* g, Agnode_t* n) { Agedge_t* e; Agnode_t* nxt; ND_dfs_mark(n) = 1; for (e = agfstedge(g, n); e ; e = agnxtedge(g, e, n)) { if (n == e->tail) nxt = e->head; else nxt = e->tail; if (ND_dfs_mark(nxt) == 0) cc_dfs(g,nxt); } }
static v_data *makeGraph(Agraph_t* gg, int *nedges) { int i; int ne = agnedges(gg); int nv = agnnodes(gg); v_data *graph = N_NEW(nv, v_data); int *edges = N_NEW(2 * ne + nv, int); /* reserve space for self loops */ float *ewgts = N_NEW(2 * ne + nv, float); Agnode_t *np; Agedge_t *ep; Agraph_t *g = NULL; int i_nedges; ne = 0; i=0; // for (i = 0; i < nv; i++) { for (np = agfstnode(gg); np; np = agnxtnode(gg, np)) { graph[i].edges = edges++; /* reserve space for the self loop */ graph[i].ewgts = ewgts++; #ifdef STYLES graph[i].styles = NULL; #endif i_nedges = 1; /* one for the self */ if (!g) g = agraphof(np); for (ep = agfstedge(g, np); ep; ep = agnxtedge(g, ep, np)) { Agnode_t *vp; Agnode_t *tp = agtail(ep); Agnode_t *hp = aghead(ep); assert(hp != tp); /* FIX: handle multiedges */ vp = (tp == np ? hp : tp); ne++; i_nedges++; // *edges++ = ((temp_node_record *) AGDATA(vp))->TVref; *edges++ = ND_TVref(vp); *ewgts++ = 1; } graph[i].nedges = i_nedges; graph[i].edges[0] = i; graph[i].ewgts[0] = 1 - i_nedges; i++; } ne /= 2; /* each edge counted twice */ *nedges = ne; return graph; }
/* constrainY: * See constrainX. */ static void constrainY(graph_t* g, nitem* nlist, int nnodes, intersectfn ifn, int ortho) { Dt_t *list = dtopen(&constr, Dtobag); nitem *p = nlist; graph_t *cg; int i; for (i = 0; i < nnodes; i++) { p->val = p->pos.y; dtinsert(list, p); p++; } if (ortho) cg = mkConstraintG(g, list, ifn, distY); else cg = mkNConstraintG(g, list, ifn, distY); rank(cg, 2, INT_MAX); #ifdef DEBUG { Agsym_t *mlsym = agedgeattr(cg, "minlen", ""); Agsym_t *rksym = agnodeattr(cg, "rank", ""); char buf[100]; node_t *n; edge_t *e; for (n = agfstnode(cg); n; n = agnxtnode(cg, n)) { sprintf(buf, "%d", ND_rank(n)); agxset(n, rksym->index, buf); for (e = agfstedge(cg, n); e; e = agnxtedge(cg, e, n)) { sprintf(buf, "%d", ED_minlen(e)); agxset(e, mlsym->index, buf); } } } #endif p = nlist; for (i = 0; i < nnodes; i++) { int newpos, oldpos, delta; oldpos = p->pos.y; newpos = ND_rank(p->cnode); delta = newpos - oldpos; p->pos.y = newpos; p->bb.LL.y += delta; p->bb.UR.y += delta; p++; } closeGraph(cg); dtclose(list); }
void fdp_cleanup(graph_t * g) { node_t *n; edge_t *e; n = agfstnode(g); free(ND_alg(n)); for (; n; n = agnxtnode(g, n)) { for (e = agfstedge(g, n); e; e = agnxtedge(g, e, n)) { gv_cleanup_edge(e); } gv_cleanup_node(n); } fdp_cleanup_graph(g); }
static int label(Agnode_t *n, int nodecnt, int* edgecnt) { Agedge_t *e; setval(n,1); nodecnt++; for (e = agfstedge(n); e; e = agnxtedge(e,n)) { (*edgecnt) += 1; if (e->node == n) e = agopp(e); if (!getval(e->node)) nodecnt = label(e->node,nodecnt,edgecnt); } return nodecnt; }
void dijkstra(Dict_t * Q, Agraph_t * G, Agnode_t * n) { Agnode_t *u; Agedge_t *e; pre(G); setdist(n, 1); dtinsert(Q, n); while ((u = extract_min(Q))) { for (e = agfstedge(u); e; e = agnxtedge(e, u)) { update(Q, e->node, u, getlength(e)); } } post(G); }
static void cc_dfs(Agraph_t* g, Agraph_t * comp, Agnode_t * n) { Agedge_t *e; Agnode_t *other; CCMARK(n); agidnode(comp, AGID(n), 1); for (e = agfstedge(g, n); e; e = agnxtedge(g, e, n)) { if (agtail(e) == n) other = aghead(e); else other = agtail(e); if (!CCMARKED(other)) cc_dfs(g, comp, other); } }
static v_data *makeGraph(topview * tv, int *nedges) { int i; int ne = tv->Edgecount; /* upper bound */ int nv = tv->Nodecount; v_data *graph = N_NEW(nv, v_data); int *edges = N_NEW(2 * ne + nv, int); /* reserve space for self loops */ float *ewgts = N_NEW(2 * ne + nv, float); Agnode_t *np; Agedge_t *ep; Agraph_t *g = NULL; int i_nedges; ne = 0; for (i = 0; i < nv; i++) { graph[i].edges = edges++; /* reserve space for the self loop */ graph[i].ewgts = ewgts++; #ifdef STYLES graph[i].styles = NULL; #endif i_nedges = 1; /* one for the self */ np = tv->Nodes[i].Node; if (!g) g = agraphof(np); for (ep = agfstedge(g, np); ep; ep = agnxtedge(g, ep, np)) { Agnode_t *vp; Agnode_t *tp = agtail(ep); Agnode_t *hp = aghead(ep); assert(hp != tp); /* FIX: handle multiedges */ vp = (tp == np ? hp : tp); ne++; i_nedges++; *edges++ = OD_TVRef(vp); *ewgts++ = 1; } graph[i].nedges = i_nedges; graph[i].edges[0] = i; graph[i].ewgts[0] = 1 - i_nedges; } ne /= 2; /* each edge counted twice */ *nedges = ne; return graph; }
static void dfs(Agraph_t * g, Agnode_t * n, Agraph_t * out, char *marks) { Agedge_t *e; Agnode_t *other; MARK(n) = 1; #ifndef WITH_CGRAPH aginsert(out, n); #else /* WITH_CGRAPH */ agsubnode(out,n,1); #endif /* WITH_CGRAPH */ for (e = agfstedge(g, n); e; e = agnxtedge(g, e, n)) { if ((other = agtail(e)) == n) other = aghead(e); if (!MARK(other)) dfs(g, other, out, marks); } }
/* dfs: * Simple depth first search, adding traversed edges to tree. */ static void dfs(Agraph_t * g, Agnode_t * n, Agraph_t * tree) { Agedge_t *e; Agnode_t *neighbor; SET_VISITED(n); for (e = agfstedge(g, n); e; e = agnxtedge(g, e, n)) { neighbor = e->head; if (neighbor == n) neighbor = e->tail; if (!VISITED(neighbor)) { /* add the edge to the dfs tree */ aginsert(tree, e); TPARENT(neighbor) = n; dfs(g, neighbor, tree); } } }
/*-------------------------------------------------------------------------*\ * Write info about a node to stdout. * Example: * n:info() \*-------------------------------------------------------------------------*/ static int gr_info(lua_State *L) { Agraph_t *g; gr_node_t *ud = tonode(L, 1, STRICT); Agedge_t *se; Agsym_t *sym; g = agraphof(ud->n); printf("INFO NODE '%s' '%s' id=%lu seq=%d\n", agnameof(ud->n), ud->name, (unsigned long) AGID(ud->n), AGSEQ(ud->n)); printf(" ptr: %p\n", ud->n); printf(" Symbols:\n"); se = agfstout(g, ud->n); sym=0; while ((sym = agnxtattr(g,AGNODE,sym))!=NULL) printf(" %s = '%s'\n",sym->name,sym->defval); #if 0 printf(" Out edges: d-out=%d u-out=%d\n", agdegree(g, ud->n, 0, 1), agcountuniqedges(g, ud->n, 0, 1)); #endif while (se) { printf(" name: '%s', head: '%s', tail: '%s' id=%lud, seq=%d %p\n", agnameof(se), agnameof(aghead(se)), agnameof(agtail(se)), (unsigned long) AGID(se), AGSEQ(se), (void*)se); se = agnxtout(g, se); } #if 0 printf(" In edges: d-in=%d u-in=%d\n", agdegree(g, ud->n, 1, 0), agcountuniqedges(g, ud->n, 1, 0)); #endif se = agfstin(g, ud->n); while (se) { printf(" name: '%s', head: '%s', tail: '%s' îd=%lu seq=%d %p\n", agnameof(se), agnameof(aghead(se)), agnameof(agtail(se)), (unsigned long) AGID(se), AGSEQ(se), (void*)se); se = agnxtin(g, se); } #if 0 printf(" Edges: d-io=%d u-io=%d\n", agdegree(g, ud->n, 1, 1), agcountuniqedges(g, ud->n, 1, 1)); #endif se = agfstedge(g, ud->n); while (se) { printf(" name: '%s', head: '%s', tail: '%s' id=%lud seq=%d %p\n", agnameof(se), agnameof(aghead(se)), agnameof(agtail(se)), (unsigned long) AGID(se), AGSEQ(se), (void*)se); se = agnxtedge(g, se, ud->n); } return 0; }
/*-------------------------------------------------------------------------*\ * Method: n.delete(self) * Delete a node. All associated edges are deleted as well. * Returns non-nil on success. * Example: * rv, err = n:delete(h) \*-------------------------------------------------------------------------*/ static int gr_delete(lua_State *L) { Agraph_t *g; gr_node_t *ud = tonode(L, 1, NONSTRICT); if (ud->n != NULL){ /* Delete all associated edges with tail on this node */ Agedge_t *se, *ne; int ix; g = ud->n->graph; se = agfstedge(g, ud->n); while (se){ ne = agnxtedge(g, se, ud->n); ix = get_object(L, se); /* ud, se */ if (!(lua_isnil(L, -ix))){ TRACE("n:delete(): closing subedge: ud=%p 'edge@%d' id=0x%0x e=%p\n", (void *) lua_touserdata(L, -ix), AGID(se), AGID(se), (void *)se); lua_pushcfunction(L, gr_delete_edge); /* ud, se, func */ lua_pushvalue(L, -2); /* ud, se, func, se */ lua_call(L, 1, LUA_MULTRET); /* ud, se */ lua_pop(L, 1); /* ud */ } else { lua_pop(L, 2); /* ud */ } se = ne; } TRACE("n:delete(): ud=%p '%s' id=0x%0x \n", (void *) ud, agnameof(ud->n), AGID(ud->n)); del_object(L, ud->n); agdelete(g, ud->n); ud->n = NULL; if (ud->name){ free(ud->name); ud->name = NULL; } } else { TRACE("n:delete(): ud=%p already closed\n", (void *)ud); } lua_pushnumber(L, 0); return 1; }
/*-------------------------------------------------------------------------*\ * Method: e = nextedge(self, prev) * Retrieves next edge of a node. * Returns the next edge of the given node. With nil as prev the first * edge is returned. * Example: * first = n:nextedge(nil) * second = n:nextedge(first) * third = n:nextedge(second) \*-------------------------------------------------------------------------*/ static int gr_nextedge(lua_State *L) { int rv; char sbuf[32]; Agraph_t *g; Agedge_t *e; gr_edge_t *ud_e; gr_node_t *ud_n = tonode(L, 1, STRICT); g = agroot(ud_n->n); if (lua_isnil(L, 2)){ e = agfstedge(g, ud_n->n); } else { ud_e = toedge(L, 2, STRICT); e = agnxtedge(g, ud_e->e, ud_n->n); } if (!e){ /* no more edges */ lua_pushnil(L); return 1; } else { /* Check whether userdata exists .. */ rv = get_object(L, e); if (rv == 1){ /* .. yes: return it */ return rv; } else { /* .. no: create it */ lua_pop(L, rv); ud_e = lua_newuserdata(L, sizeof(gr_edge_t)); ud_e->e = e; sprintf(sbuf, "edge@%lu", (unsigned long) AGID(e)); ud_e->name = strdup(sbuf); ud_e->type = AGEDGE; ud_e->status = ALIVE; set_object(L, e); return new_edge(L); } } }
/* reduce: * Attempt to reduce edge crossings by moving nodes. * Original crossing count is in cnt; final count is returned there. * list is the original list; return the best list found. */ static nodelist_t *reduce(nodelist_t * list, Agraph_t * subg, int *cnt) { Agnode_t *curnode; Agedge_t *e; Agnode_t *neighbor; nodelist_t *listCopy; int crossings, j, newCrossings; crossings = *cnt; for (curnode = agfstnode(subg); curnode; curnode = agnxtnode(subg, curnode)) { /* move curnode next to its neighbors */ for (e = agfstedge(subg, curnode); e; e = agnxtedge(subg, e, curnode)) { neighbor = e->tail; if (neighbor == curnode) neighbor = e->head; for (j = 0; j < 2; j++) { listCopy = cloneNodelist(list); insertNodelist(list, curnode, neighbor, j); newCrossings = count_all_crossings(list, subg); if (newCrossings < crossings) { crossings = newCrossings; freeNodelist(listCopy); if (crossings == 0) { *cnt = 0; return list; } } else { freeNodelist(list); list = listCopy; } } } } *cnt = crossings; return list; }
void printBlocklist(blocklist_t * snl) { block_t *bp; for (bp = snl->first; bp; bp = bp->next) { Agnode_t *n; char *p; Agraph_t *g = bp->sub_graph; fprintf(stderr, "block=%s\n", g->name); for (n = agfstnode(g); n; n = agnxtnode(g, n)) { Agedge_t *e; if (PARENT(n)) p = PARENT(n)->name; else p = "<nil>"; fprintf(stderr, " %s (%d %s)\n", n->name, VAL(n), p); for (e = agfstedge(g, n); e; e = agnxtedge(g, e, n)) { fprintf(stderr, " %s--%s\n", e->tail->name, e->head->name); } } } }
int circuit_model(graph_t * g, int nG) { double **Gm; double **Gm_inv; int rv; long i, j; node_t *v; edge_t *e; Gm = new_array(nG, nG, 0.0); Gm_inv = new_array(nG, nG, 0.0); /* set non-diagonal entries */ for (v = agfstnode(g); v; v = agnxtnode(g, v)) { for (e = agfstedge(g, v); e; e = agnxtedge(g, e, v)) { i = AGID(agtail(e)); j = AGID(aghead(e)); if (i == j) continue; /* conductance is 1/resistance */ Gm[i][j] = Gm[j][i] = -1.0 / ED_dist(e); /* negate */ } } rv = solveCircuit(nG, Gm, Gm_inv); if (rv) for (i = 0; i < nG; i++) { for (j = 0; j < nG; j++) { GD_dist(g)[i][j] = Gm_inv[i][i] + Gm_inv[j][j] - 2.0 * Gm_inv[i][j]; } } free_array(Gm); free_array(Gm_inv); return rv; }
/* findUnvisited: * Look for unvisited node n in visited block (i.e., some nodes in * the block have been visited) with neighbor not in block. Note * that therefore neighbor is unvisited. Set neighbor's parent to n * and return neighbor. * Guaranteed blp is non-empty. * */ static Agnode_t *findUnvisited(blocklist_t * blp) { Agnode_t *retn = NULL; FIX:finish Agnode_t * n; Agnode_t *newn; graph_t *clust_subg; edge_t *e; block_t *bp; block_t *prev = NULL; for (bp = blp->first; prev != blp->last; bp = bp->next) { prev = bp; clust = bp->sub_graph; if (DONE(bp)) continue; if (PARTIAL(bp)) { for (n = agfstnode(clust); n; n = agnxtnode(clust, n)) { if (!VISITED(n)) { for (e = agfstedge(g, n); e; e = agnxtedge(g, e, n)) { newn = e->head; if (newn == n) newn = e->tail; if ((BLOCK(newn) != bp)) { retn = newn; return; } } /* mark n visited */ } } /* mark bp done */ } else { } } return retn; }