/* sizeArray: * Set column and row sizes. Optimize for minimum width and * height. Where there is slack, try to distribute evenly. * We do this by encoding cells as edges with min length is * a dag on a chain. We then run network simplex, using * LR_balance. */ void sizeArray(htmltbl_t * tbl) { graph_t *rowg; graph_t *colg; /* Do the 1D cases by hand */ if ((tbl->rc == 1) || (tbl->cc == 1)) { sizeLinearArray(tbl); return; } tbl->heights = N_NEW(tbl->rc + 1, int); tbl->widths = N_NEW(tbl->cc + 1, int); #ifdef WITH_CGRAPH rowg = agopen("rowg", Agdirected,NIL(Agdisc_t *)); colg = agopen("colg", Agdirected,NIL(Agdisc_t *)); /* Only need GD_nlist */ agbindrec(rowg, "Agraphinfo_t", sizeof(Agraphinfo_t), TRUE); // graph custom data agbindrec(colg, "Agraphinfo_t", sizeof(Agraphinfo_t), TRUE); // graph custom data #else rowg = agopen("rowg", AGDIGRAPH); colg = agopen("colg", AGDIGRAPH); #endif makeGraphs(tbl, rowg, colg); rank(rowg, 2, INT_MAX); rank(colg, 2, INT_MAX); setSizes(tbl, rowg, colg); closeGraphs(rowg, colg); }
static graph_t *create_test_graph(void) { #define NUMNODES 5 Agnode_t *node[NUMNODES]; Agedge_t *e; Agraph_t *g; Agraph_t *sg; int j, k; char name[10]; /* Create a new graph */ g = agopen("new_graph", Agdirected,NIL(Agdisc_t *)); /* Add nodes */ for (j = 0; j < NUMNODES; j++) { sprintf(name, "%d", j); node[j] = agnode(g, name, 1); agbindrec(node[j], "Agnodeinfo_t", sizeof(Agnodeinfo_t), TRUE); //node custom data } /* Connect nodes */ for (j = 0; j < NUMNODES; j++) { for (k = j + 1; k < NUMNODES; k++) { e = agedge(g, node[j], node[k], NULL, 1); agbindrec(e, "Agedgeinfo_t", sizeof(Agedgeinfo_t), TRUE); //edge custom data } } sg = agsubg (g, "cluster1", 1); agsubnode (sg, node[0], 1); return g; }
static void sfdp_init_edge(edge_t * e) { #ifdef WITH_CGRAPH agbindrec(e, "Agedgeinfo_t", sizeof(Agedgeinfo_t), TRUE); //node custom data #endif /* WITH_CGRAPH */ common_init_edge(e); }
/* mapGraphs: */ static void mapGraphs(graph_t * g, graph_t * cg, distfn dist) { node_t *n; edge_t *e; edge_t *ce; node_t *t; node_t *h; nitem *tp; nitem *hp; int delta; for (n = agfstnode(g); n; n = agnxtnode(g, n)) { tp = (nitem *) ND_alg(n); t = tp->cnode; for (e = agfstout(g, n); e; e = agnxtout(g, e)) { hp = (nitem *) ND_alg(aghead(e)); delta = dist(&tp->bb, &hp->bb); h = hp->cnode; #ifndef WITH_CGRAPH ce = agedge(cg, t, h); #else ce = agedge(cg, t, h, NULL, 1); agbindrec(ce, "Agedgeinfo_t", sizeof(Agedgeinfo_t), TRUE); #endif ED_weight(ce) = 1; if (ED_minlen(ce) < delta) { if (ED_minlen(ce) == 0.0) { elist_append(ce, ND_out(t)); elist_append(ce, ND_in(h)); } ED_minlen(ce) = delta; } } } }
/* clustNode: * Generate a special cluster node representing the end node * of an edge to the cluster cg. n is a node whose name is the same * as the cluster cg. clg is the subgraph of all of * the original nodes, which will be deleted later. */ static node_t *clustNode(node_t * n, graph_t * cg, agxbuf * xb, graph_t * clg) { node_t *cn; static int idx = 0; char num[100]; agxbput(xb, "__"); sprintf(num, "%d", idx++); agxbput(xb, num); agxbputc(xb, ':'); agxbput(xb, agnameof(cg)); cn = agnode(agroot(cg), agxbuse(xb), 1); agbindrec(cn, "Agnodeinfo_t", sizeof(Agnodeinfo_t), TRUE); SET_CLUST_NODE(cn); agsubnode(cg,cn,1); //aginsert(cg, cn); agsubnode(clg,n,1); //aginsert(clg, n); /* set attributes */ N_label = setAttr(agraphof(cn), cn, "label", "", N_label); N_style = setAttr(agraphof(cn), cn, "style", "invis", N_style); N_shape = setAttr(agraphof(cn), cn, "shape", "box", N_shape); /* N_width = setAttr (cn->graph, cn, "width", "0.0001", N_width); */ return cn; }
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; }
/* mapN: * Convert cluster nodes back to ordinary nodes * If n is already ordinary, return it. * Otherwise, we know node's name is "__i:xxx" * where i is some number and xxx is the nodes's original name. * Create new node of name xxx if it doesn't exist and add n to clg * for later deletion. */ static node_t *mapN(node_t * n, graph_t * clg) { node_t *nn; char *name; graph_t *g = agraphof(n); Agsym_t *sym; if (!(IS_CLUST_NODE(n))) return n; agsubnode(clg, n, 1); name = strchr(agnameof(n), ':'); assert(name); name++; if ((nn = agfindnode(g, name))) return nn; nn = agnode(g, name, 1); agbindrec(nn, "Agnodeinfo_t", sizeof(Agnodeinfo_t), TRUE); /* Set all attributes to default */ for (sym = agnxtattr(g, AGNODE, NULL); sym; (sym = agnxtattr(g, AGNODE, sym))) { if (agxget(nn, sym) != sym->defval) agxset(nn, sym, sym->defval); } return nn; }
/* processClusterEdges: * Look for cluster edges. Replace cluster edge endpoints * corresponding to a cluster with special cluster nodes. * Delete original nodes. * Return 0 if no cluster edges; 1 otherwise. */ int processClusterEdges(graph_t * g) { int rv; node_t *n; node_t *nxt; edge_t *e; graph_t *clg; agxbuf xb; Dt_t *map; Dt_t *cmap = mkClustMap (g); unsigned char buf[SMALLBUF]; map = dtopen(&mapDisc, Dtoset); clg = agsubg(g, "__clusternodes",1); agbindrec(clg, "Agraphinfo_t", sizeof(Agraphinfo_t), TRUE); agxbinit(&xb, SMALLBUF, buf); for (n = agfstnode(g); n; n = agnxtnode(g, n)) { if (IS_CLUST_NODE(n)) continue; for (e = agfstout(g, n); e; e = agnxtout(g, e)) { checkCompound(e, clg, &xb, map, cmap); } } agxbfree(&xb); dtclose(map); rv = agnnodes(clg); for (n = agfstnode(clg); n; n = nxt) { nxt = agnxtnode(clg, n); agdelete(g, n); } agclose(clg); if (rv) SET_CLUST_EDGE(g); dtclose(cmap); return rv; }
static void dot_init_edge(edge_t * e) { char *tailgroup, *headgroup; #ifdef WITH_CGRAPH agbindrec(e, "Agedgeinfo_t", sizeof(Agedgeinfo_t), TRUE); //graph custom data #endif /* WITH_CGRAPH */ common_init_edge(e); ED_weight(e) = late_double(e, E_weight, 1.0, 0.0); tailgroup = late_string(agtail(e), N_group, ""); headgroup = late_string(aghead(e), N_group, ""); ED_count(e) = ED_xpenalty(e) = 1; if (tailgroup[0] && (tailgroup == headgroup)) { ED_xpenalty(e) = CL_CROSS; ED_weight(e) *= 100; } if (nonconstraint_edge(e)) { ED_xpenalty(e) = 0; ED_weight(e) = 0; } ED_showboxes(e) = late_int(e, E_showboxes, 0, 0); ED_minlen(e) = late_int(e, E_minlen, 1, 0); }
static void circular_init_edge(edge_t * e) { agbindrec(e, "Agedgeinfo_t", sizeof(Agedgeinfo_t), TRUE); //node custom data common_init_edge(e); ED_factor(e) = late_double(e, E_weight, 1.0, 0.0); }
static void twopi_init_edge(edge_t * e) { #ifdef WITH_CGRAPH agbindrec(e, "Agedgeinfo_t", sizeof(Agedgeinfo_t), TRUE); //edge custom data #endif /* WITH_CGRAPH */ common_init_edge(e); ED_factor(e) = late_double(e, E_weight, 1.0, 0.0); }
Agedge_t* mkMCEdge (Agraph_t* g, Agnode_t* tail, Agnode_t* head, char* name, int type, Agedge_t* orige) { Agedge_t* tmpE = agedge(g, tail, head, name, 1); agbindrec(tmpE, "mcedgeinfo_t", sizeof(mcedgeinfo_t), TRUE); MED_type(tmpE) = type; MED_orig(tmpE) = orige; return tmpE; }
/* cloneEdge: * Make a copy of e in e's graph but using ct and ch as nodes */ static edge_t *cloneEdge(edge_t * e, node_t * ct, node_t * ch) { graph_t *g = agraphof(ct); edge_t *ce = agedge(g, ct, ch,NULL,1); agbindrec(ce, "Agedgeinfo_t", sizeof(Agedgeinfo_t), TRUE); agcopyattr(e, ce); return ce; }
/* emitNode: * set node id * label, width height, x, y, type fillcolor */ static void emitNode (Agraph_t* G, Agnode_t* n, FILE* outFile) { agbindrec (n, "nodeinfo", sizeof(Agnodeinfo_t), TRUE); fprintf (outFile, " node [\n id %lu\n name \"%s\"\n", id, agnameof(n)); ID(n) = id++; emitNodeAttrs (G, n, outFile, 2); fprintf (outFile, " ]\n"); }
/* mkDeriveNode: * Constructor for a node in a derived graph. * Allocates dndata. */ static node_t *mkDeriveNode(graph_t * dg, char *name) { node_t *dn; dn = agnode(dg, name,1); agbindrec(dn, "Agnodeinfo_t", sizeof(Agnodeinfo_t), TRUE); //node custom data ND_alg(dn) = (void *) NEW(dndata); /* free in freeDeriveNode */ ND_pos(dn) = N_GNEW(GD_ndim(dg), double); /* fprintf (stderr, "Creating %s\n", dn->name); */ return dn; }
static Agraph_t *mkBlock(Agraph_t * g, bcstate * stp) { Agraph_t *sg; stp->nComp++; sg = agsubg(g, blockName(agnameof(g), stp->nComp), 1); agbindrec(sg, "info", sizeof(Agraphinfo_t), TRUE); NEXTBLK(sg) = stp->blks; stp->blks = sg; return sg; }
/* makeDerivedNode: * Make a node in the derived graph, with the given name. * orig points to what it represents, either a real node or * a cluster. Copy size info from original node; needed for * adjustNodes and packSubgraphs. */ static node_t *makeDerivedNode(graph_t * dg, char *name, int isNode, void *orig) { node_t *n = agnode(dg, name,1); agbindrec(n, "Agnodeinfo_t", sizeof(Agnodeinfo_t), TRUE); //node custom data ND_alg(n) = (void *) NEW(cdata); if (isNode) { ND_pos(n) = N_NEW(Ndim, double); ND_lw(n) = ND_lw((node_t *) orig); ND_rw(n) = ND_rw((node_t *) orig); ND_ht(n) = ND_ht((node_t *) orig); ORIGN(n) = (node_t *) orig; } else
static void dot_init_node(node_t * n) { agbindrec(n, "Agnodeinfo_t", sizeof(Agnodeinfo_t), TRUE); //graph custom data common_init_node(n); gv_nodesize(n, GD_flip(agraphof(n))); alloc_elist(4, ND_in(n)); alloc_elist(4, ND_out(n)); alloc_elist(2, ND_flat_in(n)); alloc_elist(2, ND_flat_out(n)); alloc_elist(2, ND_other(n)); ND_UF_size(n) = 1; }
static void dot_init_subg(graph_t * g, graph_t* droot) { graph_t* subg; if ((g != agroot(g))) agbindrec(g, "Agraphinfo_t", sizeof(Agraphinfo_t), TRUE); if (g == droot) GD_dotroot(agroot(g)) = droot; for (subg = agfstsubg(g); subg; subg = agnxtsubg(subg)) { dot_init_subg(subg, droot); } }
static void initSubg (Agraph_t* sg, Agraph_t* g) { agbindrec(sg, "Agraphinfo_t", sizeof(Agraphinfo_t), TRUE); GD_drawing(sg) = NEW(layout_t); GD_drawing(sg)->quantum = GD_drawing(g)->quantum; GD_drawing(sg)->dpi = GD_drawing(g)->dpi; GD_gvc(sg) = GD_gvc (g); GD_charset(sg) = GD_charset (g); GD_rankdir2(sg) = GD_rankdir2 (g); GD_nodesep(sg) = GD_nodesep(g); GD_ranksep(sg) = GD_ranksep(g); GD_fontnames(sg) = GD_fontnames(g); }
void init_graph(Agraph_t* g) { int i = 0; Agnode_t* n; weight = agattr(g, AGEDGE, "weight", "1.0"); pos = agattr(g, AGNODE, "pos", ""); color = agattr(g, AGNODE, "color", "black"); comment = agattr(g, AGRAPH, "cmd", ""); nodes = (Agnode_t**) malloc(sizeof(Agnode_t*)*agnnodes(g)); for(n = agfstnode(g); n; n = agnxtnode(g,n)) { agbindrec(n, (char*)"nodedata", sizeof(nodedata_t),1); setid(n,i); nodes[i] = n; i++; } }
/* undoClusterEdges: * Replace cluster nodes with originals. Make sure original has * no attributes. Replace original edges. Delete cluster nodes, * which will also delete cluster edges. */ void undoClusterEdges(graph_t * g) { node_t *n; edge_t *e; graph_t *clg; clg = agsubg(g, "__clusternodes",1); agbindrec(clg, "Agraphinfo_t", sizeof(Agraphinfo_t), TRUE); for (n = agfstnode(g); n; n = agnxtnode(g, n)) { for (e = agfstout(g, n); e; e = agnxtout(g, e)) { undoCompound(e, clg); } } for (n = agfstnode(clg); n; n = agnxtnode(clg, n)) { agdelete(g, n); } agclose(clg); }
static int visit(Agnode_t *n, Agraph_t* map, Stack* sp, sccstate* st) { unsigned int m,min; Agnode_t* t; Agraph_t* subg; Agedge_t* e; min = ++(st->ID); setval(n,min); push (sp, n); for (e = agfstout(n); e; e = agnxtout(e)) { t = aghead(e); if (getval(t) == 0) m = visit(t,map,sp,st); else m = getval(t); if (m < min) min = m; } if (getval(n) == min) { if (!wantDegenerateComp && (top(sp) == n)) { setval(n,INF); pop(sp); } else { char name[32]; Agraph_t* G = agraphof(n);; sprintf(name,"cluster_%d",(st->Comp)++); subg = agsubg(G,name,TRUE); agbindrec(subg,"scc_graph",sizeof(Agraphinfo_t),TRUE); setrep(subg,agnode(map,name,TRUE)); do { t = pop(sp); agsubnode(subg,t,TRUE); setval(t,INF); setscc(t,subg); st->N_nodes_in_nontriv_SCC++; } while (t != n); nodeInduce(subg); if (!Silent) agwrite(subg,stdout); } } return min; }
/* mkMCNode: returns a new node unless a name is provided, depending on the node type either a temporary node or a temp label node is returned otherwise a regular node is returned. it is caller's responsibility to set necessary edges */ Agnode_t *mkMCNode (Agraph_t * g, int type, char *name) { static int k = 0; Agnode_t *rv; char buf[512]; switch (type) { case INTNODE: sprintf(buf, "____tempN%d", k++); /*unique node name for internal nodes */ rv = agnode(g, buf, 1); break; case LBLNODE: sprintf(buf, "____lblN%d", k++); /*unique node name for labels */ rv = agnode(g, buf, 1); break; default: rv = agnode(g, name, 1); } agbindrec(rv, "mcnodeinfo_t", sizeof(mcnodeinfo_t), TRUE); MND_type(rv) = type; return rv; }
static void checkChain(graph_t * g) { node_t *t; node_t *h; edge_t *e; t = GD_nlist(g); for (h = ND_next(t); h; h = ND_next(h)) { if (!agfindedge(g, t, h)) { #ifdef WITH_CGRAPH e = agedge(g, t, h, NULL, 1); agbindrec(e, "Agedgeinfo_t", sizeof(Agedgeinfo_t), TRUE); #else e = agedge(g, t, h); #endif ED_minlen(e) = 0; elist_append(e, ND_out(t)); elist_append(e, ND_in(h)); } t = h; } }
static int visit(Agnode_t * n, Agraph_t * map, Stack * sp, sccstate * st) { unsigned int m, min; Agnode_t *t; Agraph_t *subg; Agedge_t *e; min = ++(st->ID); setval(n, min); push(sp, n); #ifdef USE_CGRAPH for (e = agfstout(n->root, n); e; e = agnxtout(n->root, e)) { #else for (e = agfstout(n); e; e = agnxtout(e)) { #endif t = aghead(e); if (getval(t) == 0) m = visit(t, map, sp, st); else m = getval(t); if (m < min) min = m; } if (getval(n) == min) { if (!wantDegenerateComp && (top(sp) == n)) { setval(n, INF); pop(sp); } else { char name[32]; Agraph_t *G = agraphof(n);; sprintf(name, "cluster_%d", (st->Comp)++); subg = agsubg(G, name, TRUE); agbindrec(subg, "scc_graph", sizeof(Agraphinfo_t), TRUE); setrep(subg, agnode(map, name, TRUE)); do { t = pop(sp); agsubnode(subg, t, TRUE); setval(t, INF); setscc(t, subg); st->N_nodes_in_nontriv_SCC++; } while (t != n); #ifdef USE_CGRAPH nodeInduce(subg, map); #else nodeInduce(subg); #endif if (!Silent) agwrite(subg, stdout); } } return min; } static int label(Agnode_t * n, int nodecnt, int *edgecnt) { Agedge_t *e; setval(n, 1); nodecnt++; #ifdef USE_CGRAPH for (e = agfstedge(n->root, n); e; e = agnxtedge(n->root, e, n)) { #else for (e = agfstedge(n); e; e = agnxtedge(e, n)) { #endif (*edgecnt) += 1; if (e->node == n) e = agopp(e); if (!getval(e->node)) nodecnt = label(e->node, nodecnt, edgecnt); } return nodecnt; } static int countComponents(Agraph_t * g, int *max_degree, float *nontree_frac) { int nc = 0; int sum_edges = 0; int sum_nontree = 0; int deg; int n_edges; int n_nodes; Agnode_t *n; #ifdef USE_CGRAPH for (n = agfstnode(g); n; n = agnxtnode(g, n)) { #else for (n = agfstnode(g); n; n = agnxtnode(n)) { #endif if (!getval(n)) { nc++; n_edges = 0; n_nodes = label(n, 0, &n_edges); sum_edges += n_edges; sum_nontree += (n_edges - n_nodes + 1); } } if (max_degree) { int maxd = 0; #ifdef USE_CGRAPH for (n = agfstnode(g); n; n = agnxtnode(g, n)) { deg = agdegree(g, n, TRUE, TRUE); #else for (n = agfstnode(g); n; n = agnxtnode(n)) { deg = agdegree(n, TRUE, TRUE); #endif if (maxd < deg) maxd = deg; setval(n, 0); } *max_degree = maxd; } if (nontree_frac) { if (sum_edges > 0) *nontree_frac = (float) sum_nontree / (float) sum_edges; else *nontree_frac = 0.0; } return nc; } static void process(Agraph_t * G) { Agnode_t *n; Agraph_t *map; int nc = 0; float nontree_frac = 0; int Maxdegree = 0; Stack stack; sccstate state; aginit(G, AGRAPH, "scc_graph", sizeof(Agraphinfo_t), TRUE); aginit(G, AGNODE, "scc_node", sizeof(Agnodeinfo_t), TRUE); state.Comp = state.ID = 0; state.N_nodes_in_nontriv_SCC = 0; if (Verbose) nc = countComponents(G, &Maxdegree, &nontree_frac); initStack(&stack, agnnodes(G) + 1); map = agopen("scc_map", Agdirected, (Agdisc_t *) 0); #ifdef USE_CGRAPH for (n = agfstnode(G); n; n = agnxtnode(G, n)) #else for (n = agfstnode(G); n; n = agnxtnode(n)) #endif if (getval(n) == 0) visit(n, map, &stack, &state); freeStack(&stack); if (!Silent) agwrite(map, stdout); agclose(map); if (Verbose) fprintf(stderr, "%d %d %d %d %.4f %d %.4f\n", agnnodes(G), agnedges(G), nc, state.Comp, state.N_nodes_in_nontriv_SCC / (double) agnnodes(G), Maxdegree, nontree_frac); else fprintf(stderr, "%d nodes, %d edges, %d strong components\n", agnnodes(G), agnedges(G), state.Comp); } static char *useString = "Usage: %s [-sdv?] <files>\n\ -s - silent\n\ -d - allow degenerate components\n\ -v - verbose\n\ -? - print usage\n\ If no files are specified, stdin is used\n"; static void usage(int v) { printf(useString, CmdName); exit(v); }
static void my_init_graph(Agraph_t *g, Agobj_t *graph, void *arg) { int *sz = arg; agbindrec(graph,"level graph rec",sz[0],TRUE); }
/* mkConstraintG: */ static graph_t *mkConstraintG(graph_t * g, Dt_t * list, intersectfn intersect, distfn dist) { nitem *p; nitem *nxt = NULL; nitem *nxp; graph_t *vg; node_t *prev = NULL; node_t *root = NULL; node_t *n = NULL; edge_t *e; int lcnt, cnt; int oldval = -INT_MAX; #ifdef OLD double root_val; #endif node_t *lastn = NULL; #ifndef WITH_CGRAPH graph_t *cg = agopen("cg", AGDIGRAPHSTRICT); #else graph_t *cg = agopen("cg", Agstrictdirected, NIL(Agdisc_t *)); agbindrec(cg, "Agraphinfo_t", sizeof(Agraphinfo_t), TRUE); // graph custom data #endif /* count distinct nodes */ cnt = 0; for (p = (nitem *) dtflatten(list); p; p = (nitem *) dtlink(list, (Dtlink_t *) p)) { if (oldval != p->val) { oldval = p->val; cnt++; } } /* construct basic chain to enforce left to right order */ oldval = -INT_MAX; lcnt = 0; for (p = (nitem *) dtflatten(list); p; p = (nitem *) dtlink(list, (Dtlink_t *) p)) { if (oldval != p->val) { oldval = p->val; /* n = newNode (cg); */ #ifndef WITH_CGRAPH n = agnode(cg, agnameof(p->np)); /* FIX */ #else n = agnode(cg, agnameof(p->np), 1); /* FIX */ agbindrec(n, "Agnodeinfo_t", sizeof(Agnodeinfo_t), TRUE); //node custom data #endif ND_alg(n) = p; if (root) { ND_next(lastn) = n; lastn = n; } else { root = n; #ifdef OLD root_val = p->val; #endif lastn = GD_nlist(cg) = n; } alloc_elist(lcnt, ND_in(n)); if (prev) { if (prev == root) alloc_elist(2 * (cnt - 1), ND_out(prev)); else alloc_elist(cnt - lcnt - 1, ND_out(prev)); #ifndef WITH_CGRAPH e = agedge(cg, prev, n); #else e = agedge(cg, prev, n, NULL, 1); agbindrec(e, "Agedgeinfo_t", sizeof(Agedgeinfo_t), TRUE); // edge custom data #endif ED_minlen(e) = SCALE; ED_weight(e) = 1; elist_append(e, ND_out(prev)); elist_append(e, ND_in(n)); } lcnt++; prev = n; } p->cnode = n; } alloc_elist(0, ND_out(prev)); /* add immediate right neighbor constraints * Construct visibility graph, then perform transitive reduction. * Remaining outedges are immediate right neighbors. * FIX: Incremental algorithm to construct trans. reduction? */ #ifndef WITH_CGRAPH vg = agopen("vg", AGDIGRAPHSTRICT); #else vg = agopen("vg", Agstrictdirected, NIL(Agdisc_t *)); #endif for (p = (nitem *) dtflatten(list); p; p = (nitem *) dtlink(list, (Dtlink_t *) p)) { #ifndef WITH_CGRAPH n = agnode(vg, agnameof(p->np)); /* FIX */ #else n = agnode(vg, agnameof(p->np), 1); /* FIX */ agbindrec(n, "Agnodeinfo_t", sizeof(Agnodeinfo_t), TRUE); //node custom data #endif p->vnode = n; ND_alg(n) = p; } oldval = -INT_MAX; for (p = (nitem *) dtflatten(list); p; p = (nitem *) dtlink(list, (Dtlink_t *) p)) { if (oldval != p->val) { /* new pos: reset nxt */ oldval = p->val; for (nxt = (nitem *) dtlink(link, (Dtlink_t *) p); nxt; nxt = (nitem *) dtlink(list, (Dtlink_t *) nxt)) { if (nxt->val != oldval) break; } if (!nxt) break; } for (nxp = nxt; nxp; nxp = (nitem *) dtlink(list, (Dtlink_t *) nxp)) { if (intersect(p, nxp)) #ifndef WITH_CGRAPH agedge(vg, p->vnode, nxp->vnode); #else agedge(vg, p->vnode, nxp->vnode, NULL, 1); #endif } } /* Remove redundant constraints here. However, the cost of doing this * may be a good deal more than the time saved in network simplex. Also, * if the graph is changed, the ND_in and ND_out data has to be updated. */ mapGraphs(vg, cg, dist); agclose(vg); /* add dummy constraints for absolute values and initial positions */ #ifdef OLD for (n = agfstnode(cg); n; n = agnxtnode(cg, n)) { node_t *vn; /* slack node for absolute value */ node_t *an; /* node representing original position */ p = (nitem *) ND_alg(n); if ((n == root) || (!p)) continue; vn = newNode(cg); ND_next(lastn) = vn; lastn = vn; alloc_elist(0, ND_out(vn)); alloc_elist(2, ND_in(vn)); an = newNode(cg); ND_next(lastn) = an; lastn = an; alloc_elist(1, ND_in(an)); alloc_elist(1, ND_out(an)); #ifndef WITH_CGRAPH e = agedge(cg, root, an); #else e = agedge(cg, root, an, 1); #endif ED_minlen(e) = p->val - root_val; elist_append(e, ND_out(root)); elist_append(e, ND_in(an)); #ifndef WITH_CGRAPH e = agedge(cg, an, vn); #else e = agedge(cg, an, vn, 1); #endif elist_append(e, ND_out(an)); elist_append(e, ND_in(vn)); #ifndef WITH_CGRAPH e = agedge(cg, n, vn); #else e = agedge(cg, n, vn, 1); #endif elist_append(e, ND_out(n)); elist_append(e, ND_in(vn)); } #endif /* OLD */ return cg; }
/* mkNConstraintG: * Similar to mkConstraintG, except it doesn't enforce orthogonal * ordering. If there is overlap, as defined by intersect, the * nodes will kept/pushed apart in the current order. If not, no * constraint is enforced. If a constraint edge is added, and it * corresponds to a real edge, we increase the weight in an attempt * to keep the resulting shift short. */ static graph_t *mkNConstraintG(graph_t * g, Dt_t * list, intersectfn intersect, distfn dist) { nitem *p; nitem *nxp; node_t *n; edge_t *e; node_t *lastn = NULL; #ifndef WITH_CGRAPH graph_t *cg = agopen("cg", AGDIGRAPHSTRICT); #else graph_t *cg = agopen("cg", Agstrictdirected, NIL(Agdisc_t *)); agbindrec(cg, "Agraphinfo_t", sizeof(Agraphinfo_t), TRUE); // graph custom data #endif for (p = (nitem *) dtflatten(list); p; p = (nitem *) dtlink(list, (Dtlink_t *) p)) { #ifndef WITH_CGRAPH n = agnode(cg, agnameof(p->np)); /* FIX */ #else n = agnode(cg, agnameof(p->np), 1); /* FIX */ agbindrec(n, "Agnodeinfo_t", sizeof(Agnodeinfo_t), TRUE); //node custom data #endif ND_alg(n) = p; p->cnode = n; alloc_elist(0, ND_in(n)); alloc_elist(0, ND_out(n)); if (lastn) { ND_next(lastn) = n; lastn = n; } else { lastn = GD_nlist(cg) = n; } } for (p = (nitem *) dtflatten(list); p; p = (nitem *) dtlink(list, (Dtlink_t *) p)) { for (nxp = (nitem *) dtlink(link, (Dtlink_t *) p); nxp; nxp = (nitem *) dtlink(list, (Dtlink_t *) nxp)) { e = NULL; if (intersect(p, nxp)) { double delta = dist(&p->bb, &nxp->bb); #ifndef WITH_CGRAPH e = agedge(cg, p->cnode, nxp->cnode); #else e = agedge(cg, p->cnode, nxp->cnode, NULL, 1); agbindrec(e, "Agedgeinfo_t", sizeof(Agedgeinfo_t), TRUE); // edge custom data #endif assert (delta <= 0xFFFF); ED_minlen(e) = delta; ED_weight(e) = 1; } if (e && agfindedge(g,p->np, nxp->np)) { ED_weight(e) = 100; } #if 0 if (agfindedge(g,p->np, nxp->np)) { if (e == NULL) e = agedge(cg, p->cnode, nxp->cnode); ED_weight(e) = 100; /* If minlen < SCALE, the nodes can't conflict or there's * an overlap but it will be removed in the orthogonal pass. * So we just keep the node's basically where they are. */ if (SCALE > ED_minlen(e)) ED_minlen(e) = SCALE; } #endif } } for (p = (nitem *) dtflatten(list); p; p = (nitem *) dtlink(list, (Dtlink_t *) p)) { n = p->cnode; for (e = agfstout(cg,n); e; e = agnxtout(cg,e)) { elist_append(e, ND_out(n)); elist_append(e, ND_in(aghead(e))); } } /* We could remove redundant constraints here. However, the cost of doing * this may be a good deal more than the time saved in network simplex. * Also, if the graph is changed, the ND_in and ND_out data has to be * updated. */ return cg; }
//------------------------------------------------------------------------------ grafo le_grafo(FILE *input) { int i, j; Agnode_t *v; Agedge_t *a; Agraph_t *g_cgraph; // le grafo g_cgraph = agread(input, NULL); if ( !g_cgraph ) return NULL; // Cria grafo grafo g = (grafo) malloc(sizeof(struct grafo)); // pega tipo do grafo g->tipo = agisdirected(g_cgraph); g->peso = SEMPESO; // pega numero de vertices g->n_vertices = agnnodes(g_cgraph); // aloca espaco p/ vetor de vertices g->vertices = (vertice) malloc( (unsigned int)g->n_vertices * sizeof(struct vertice)); if (!g->vertices) return NULL; //Copia nome do grafo g->nome = (char *) malloc(strlen(agnameof(g_cgraph))+1); strcpy(g->nome, agnameof(g_cgraph)); g->matriz_dist = NULL; //aloca matriz g->matriz_adj = (elemento **) malloc((unsigned int)g->n_vertices * sizeof(elemento *) ); // zera matriz for (i=0; i < g->n_vertices; i++){ g->matriz_adj[i] = (elemento *) malloc((unsigned int)g->n_vertices * sizeof(elemento) ); for(j=0; j < g->n_vertices; j++){ g->matriz_adj[i][j].adjacente = 0; } } i = 0; // Copia vertices for (v = agfstnode(g_cgraph ); v; v = agnxtnode(g_cgraph ,v), i++) { // copia nome g->vertices[i].nome = (char *) malloc(strlen(agnameof(v))+1); //g->vertice[i].nome = agnameof(v); strcpy(g->vertices[i].nome, agnameof(v)); // seta next vertice if (i != agnnodes(g_cgraph) - 1) g->vertices[i].next = &g->vertices[i+1]; //set atribute Agnodeinfo_t *p; p = (Agnodeinfo_t*) agbindrec(v,"Agnodeinfo_t",sizeof(Agnodeinfo_t),TRUE); p->ref_v = i; } g->vertices[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(i, v, a, g); } else { for (a=agfstout(g_cgraph,v); a; a=agnxtout(g_cgraph,a)) add_aresta(i, v, a, g); } } free(g_cgraph); return g; }