Example #1
0
static int dfs(Agnode_t * n, Agedge_t * link, int warn)
{
    Agedge_t *e;
    Agedge_t *f;
    Agraph_t *g = agrootof(n);

    MARK(n) = 1;

    for (e = agfstin(g, n); e; e = f) {
	f = agnxtin(g, e);
	if (e == link)
	    continue;
	if (MARK(agtail(e)))
	    agdelete(g, e);
    }

    for (e = agfstout(g, n); e; e = agnxtout(g, e)) {
	if (MARK(aghead(e))) {
	    if (!warn) {
		warn++;
		fprintf(stderr,
			"warning: %s has cycle(s), transitive reduction not unique\n",
			agnameof(g));
		fprintf(stderr, "cycle involves edge %s -> %s\n",
			agnameof(agtail(e)), agnameof(aghead(e)));
	    }
	} else
	    warn = dfs(aghead(e), AGOUT2IN(e), warn);
    }

    MARK(n) = 0;
    return warn;
}
Example #2
0
/*-------------------------------------------------------------------------*\
 * Method: n.degree(self, what)
 * Determines degree of a node. 
 * Returns number of in-edges (what='*i'), out-edges (what='*o') or the sum 
 * of all edges (what='*a') to/from/of a node.
 * Example:
 * rv, err = n:degree("*i")
\*-------------------------------------------------------------------------*/
int gr_degree(lua_State *L)
{
  int count = 0;
  Agedge_t *e;
  Agraph_t *g;
  Agnode_t *n;
  gr_node_t *ud = tonode(L, 1, STRICT);
  char *flag = (char *) luaL_optstring(L, 2, "*a");
  int indeg = TRUE;
  int outdeg = TRUE;
  n = ud->n;
  g = agroot(ud->n);
  if (*flag != '*'){
    luaL_error(L, "invalid format specifier");
    return 0;
  }
  switch(*(flag+1)){
  case 'i': outdeg = FALSE; break;
  case 'o': indeg = FALSE; break;
  }
  if (indeg){
    for (e = agfstin(g, n); e; e = agnxtin(g, e)){
      count++;
    }
  }
  if (outdeg){
    for (e = agfstout(g, n); e; e = agnxtout(g, e)){
      count++;
    }
  }
  lua_pushnumber(L, count);
  return 1;
}
Example #3
0
static int in_cross(node_t *v,node_t *w)
{
  register edge_t *e1,*e2;
  register int inv, cross = 0, t;
                                                                                
  for (e2 = agfstin(w->graph,w); e2; e2 = agnxtin(w->graph,e2)) {
		register int cnt = ED_xpenalty(e2);
		inv = ND_order(e2->tail);
		for (e1 = agfstin(v->graph,v); e1; e1 = agnxtin(v->graph,e1)) {
			t = ND_order(e1->tail) - inv;
			if ((t > 0) || ((t == 0) && (ED_tailport(e1).p.x > ED_tailport(e2).p.x)))
				cross += ED_xpenalty(e1) * cnt;
    }
	}
	return cross;
}
Example #4
0
void remove_child(Agraph_t * graph, Agnode_t * node)
{
    Agedge_t *edge;
    Agedge_t *nexte;

    /* Avoid cycles */
    if MARKED
	(node) return;
    MARK(node);

    /* Skip nodes with more than one parent */
    edge = agfstin(node);
    if (edge && (agnxtin(edge) != NULL)) {
	UNMARK(node);
	return;
    }

    /* recursively remove children */
    for (edge = agfstout(node); edge; edge = nexte) {
	nexte = agnxtout(edge);
	if (aghead(edge) != node) {
	    if (verbose)
		fprintf(stderr, "Processing descendant: %s\n",
			agnameof(aghead(edge)));
	    remove_child(graph, aghead(edge));
	    agdeledge(edge);
	}
    }

    agdelnode(node);
    return;
}
Example #5
0
/* 
 populates rank lists of g.  there are some key details:
 1) the input graph ordering must be respected (in left to right initialization)
 2) connected components are separated and marked with indices
 3) series-parallel graphs (includes trees, obviously) must not have crossings
*/
static void build_ranks(Agraph_t *g, boolean down)
{
	queue			*q;
	component_t c;
	int				r;
	Agnode_t	*n;
	Agedge_t	*e;

	c = build_components(g, down);

	/* process each each component */
	q = new_queue(agnnodes(g)+1);
	for (r = 0; r < c.r; r++) {
		enqueue(q,c.root[r]);
		if ((r + 1 >= c.r)||(ND_component(c.root[r])!=ND_component(c.root[r+1]))) {
			while ((n = dequeue(q))) {
				install(g,n);
					if (down) {
						for (e = agfstout(g,n); e; e = agnxtout(g,e))
							if (--ND_priority(e->head) == 0) enqueue(q,e->head);
					}
					else {
						for (e = agfstin(g,n); e; e = agnxtin(g,e))
							if (--ND_priority(e->tail) == 0) enqueue(q,e->head);
					}
			}
		}
	}
	free_queue(q);
}
Example #6
0
/*
 * defines ND_sortweight of each node in r0 w.r.t. r1
 * returns...
 */
static boolean medians(Agraph_t *g, int r0, int r1)
{
	static int *list;
	static int list_extent;
	int     i,j,lm,rm,lspan,rspan;
	node_t  *n,**v;
	edge_t  *e;
	boolean hasfixed = FALSE;

	if (list_extent < GD_maxinoutdeg(g->root)) {
		list_extent = GD_maxinoutdeg(g->root);
		if (!list) list = realloc(list,sizeof(list[0])*list_extent);
		else list = realloc(list,sizeof(list[0])*list_extent);
	}
	v = GD_rank(g)[r0].v;
	for (i = leftmost(g,r0); i <= rightmost(g,r0); i++) {
		n = v[i]; j = 0;
		if (r1 > r0) for (e = agfstout(g,n); e; e = agnxtout(g,e))
			{if (ED_xpenalty(e) > 0) list[j++] = VAL(e->head,ED_headport(e));}
		else for (e = agfstin(g,n); e; e = agnxtin(g,e))
			{if (ED_xpenalty(e) > 0) list[j++] = VAL(e->tail,ED_tailport(e));}
		switch(j) {
			case 0:
				ND_sortweight(n) = -1;		/* no neighbor - median undefined */
				break;
			case 1:
				ND_sortweight(n) = list[0];
				break;
			case 2:
				ND_sortweight(n) = (list[0] + list[1])/2;
				break;
			default:
				qsort(list,j,sizeof(int),int_cmpf);
				if (j % 2) ND_sortweight(n) = list[j/2];
				else {
					/* weighted median */
					rm = j/2;
					lm = rm - 1;
					rspan = list[j-1] - list[rm];
					lspan = list[lm] - list[0];
					if (lspan == rspan)
						ND_sortweight(n) = (list[lm] + list[rm])/2;
					else {
						int w = list[lm]*rspan + list[rm]*lspan;
						ND_sortweight(n) = w / (lspan + rspan);
					}
				}
		}
	}
#ifdef NOTDEF
	/* this code was in the old mincross */
	for (i = 0; i < GD_rank(g)[r0].n; i++) {
		n = v[i];
		if ((ND_out(n).size == 0) && (ND_in(n).size == 0))
			hasfixed |= flat_sortweight(n);
	}
#endif
	return hasfixed;
}
Example #7
0
static int
indegree (graph_t * g, node_t *n)
{
  edge_t *e;
  int cnt = 0;
  for (e = agfstin(g,n); e; e = agnxtin(g,e)) cnt++;
  return cnt; 
}
Example #8
0
Agedge_t *agfstedge(Agraph_t * g, Agnode_t * n)
{
    Agedge_t *rv;
    rv = agfstout(g, n);
    if (rv == NILedge)
	rv = agfstin(g, n);
    return rv;
}
Example #9
0
Agedge_t *firstin(Agraph_t *g)
{
    Agnode_t *n;

    if (!g)
	return NULL;
    n = agfstnode(g);
    if (!n)
	return NULL;
    return agfstin(g, n);
}
Example #10
0
static void search_component(Agraph_t *g, Agnode_t *n, int c)
{
	Agedge_t	*e;
	ND_component(n) = c;
	for (e = agfstout(g,n); e; e = agnxtout(g,e))
		if (ND_component(e->head) < 0)
			search_component(g,e->head,c);
	for (e = agfstin(g,n); e; e = agnxtin(g,e))
		if (ND_component(e->tail) < 0)
			search_component(g,e->tail,c);
}
Agnode_t *firsttail(Agnode_t *n)
{
    Agedge_t *e;

    if (!n)
        return NULL;
    e = agfstin(agraphof(n), n);
    if (!e)
        return NULL;
    return agtail(e);
}
Example #12
0
static void transform(Agraph_t * g)
{
    Agnode_t *n;
    Agedge_t *e;
    char *str;
    Agsym_t *m_ix, *s_ix;
    int cnt, d;

    m_ix = bindedgeattr(g, "minlen");
    s_ix = bindedgeattr(g, "style");

    for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
	d = myindegree(n) + myoutdegree(n);
	if (d == 0) {
	    if (ChainLimit < 1)
		continue;
	    if (ChainNode) {
		e = agedge(g, ChainNode, n, "", TRUE);
		agxset(e, s_ix, "invis");
		ChainSize++;
		if (ChainSize < ChainLimit)
		    ChainNode = n;
		else {
		    ChainNode = NULL;
		    ChainSize = 0;
		}
	    } else
		ChainNode = n;
	} else if (d > 1) {
	    if (MaxMinlen < 1)
		continue;
	    cnt = 0;
	    for (e = agfstin(g, n); e; e = agnxtin(g, e)) {
		if (isleaf(agtail(e))) {
		    str = agxget(e, m_ix);
		    if (str[0] == 0) {
			adjustlen(e, m_ix, (cnt % MaxMinlen) + 1);
			cnt++;
		    }
		}
	    }

	    cnt = 0;
	    for (e = agfstout(g, n); e; e = agnxtout(g, e)) {
		if (isleaf(e->node) || (Do_fans && ischainnode(e->node))) {
		    str = agxget(e, m_ix);
		    if (str[0] == 0)
			adjustlen(e, m_ix, (cnt % MaxMinlen) + 1);
		    cnt++;
		}
	    }
	}
    }
}
Example #13
0
Agnode_t *firsttail(Agnode_t *n)
{
    Agedge_t *e;

    if (!n)
	return NULL;
    e = agfstin(n->graph, n);
    if (!e)
	return NULL;
    return e->tail;
}
Example #14
0
Agedge_t *agnxtedge(Agraph_t * g, Agedge_t * e, Agnode_t * n)
{
    Agedge_t *rv;

    if (n == AGTAIL(e)) {
	rv = agnxtout(g, e);
	if (rv == NILedge)
	    rv = agfstin(g, n);
    } else
	rv = agnxtin(g, e);
    return rv;
}
Example #15
0
int agdegree(Agnode_t * n, int want_in, int want_out)
{
    Agedge_t *e;
    int rv = 0;

    if (want_in)
	for (e = agfstin(n); e; e = agnxtin(e))
	    rv++;
    if (want_out)
	for (e = agfstout(n); e; e = agnxtout(e))
	    rv++;
    return rv;
}
Example #16
0
/* place_node:
 * Add n to list. By construction, n is not in list at start.
 */
static void place_node(Agraph_t * g, Agnode_t * n, nodelist_t * list)
{
    Agedge_t *e;
    int placed = 0;
    nodelist_t *neighbors = mkNodelist();
    nodelistitem_t *one, *two;

    for (e = agfstout(g, n); e; e = agnxtout(g, e)) {
	appendNodelist(neighbors, NULL, e->head);
	SET_NEIGHBOR(e->head);
    }
    for (e = agfstin(g, n); e; e = agnxtin(g, e)) {
	appendNodelist(neighbors, NULL, e->tail);
	SET_NEIGHBOR(e->tail);
    }

    /* Look for 2 neighbors consecutive on list */
    if (sizeNodelist(neighbors) >= 2) {
	for (one = list->first; one; one = one->next) {
	    if (one == list->last)
		two = list->first;
	    else
		two = one->next;

	    if (NEIGHBOR(one->curr) && NEIGHBOR(two->curr)) {
		appendNodelist(list, one, n);
		placed = 1;
		break;
	    }
	}
    }

    /* Find any neighbor on list */
    if (!placed && sizeNodelist(neighbors) > 0) {
	for (one = list->first; one; one = one->next) {
	    if (NEIGHBOR(one->curr)) {
		appendNodelist(list, one, n);
		placed = 1;
		break;
	    }
	}
    }

    if (!placed)
	appendNodelist(list, NULL, n);

    for (one = neighbors->first; one; one = one->next)
	UNSET_NEIGHBOR(one->curr);
    freeNodelist(neighbors);
}
Example #17
0
Agedge_t *nextin(Agraph_t *g, Agedge_t *e)
{
    Agnode_t *n;
    Agedge_t *ne;

    if (!g || !e)
	return NULL;
    ne = agnxtin(g, e);
    if (ne)
	return (ne);
    n = agnxtnode(g, n);
    if (!n)
	return NULL;
    return agfstin(g, n);
}
Example #18
0
int agcountuniqedges(Agraph_t * g, Agnode_t * n, int want_in, int want_out)
{
    Agedge_t *e;
    Agsubnode_t *sn;
    int rv = 0;

    sn = agsubrep(g, n);
    if (want_out) rv = cnt(g->e_seq,&(sn->out_seq));
    if (want_in) {
		if (!want_out) rv += cnt(g->e_seq,&(sn->in_seq));	/* cheap */
		else {	/* less cheap */
			for (e = agfstin(g, n); e; e = agnxtin(g, e))
				if (e->node != n) rv++;  /* don't double count loops */
		}
    }
    return rv;
}
Example #19
0
/* dumpE:
 */
void dumpE(graph_t * g, int derived)
{
    Agnode_t *n;
    Agedge_t *e;
    Agedge_t **ep;
    Agedge_t *el;
    int i;
    int deg;

    prIndent();
    fprintf(stderr, "Graph %s : %d nodes %d edges\n", g->name, agnnodes(g),
	    agnedges(g));
    for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
	deg = 0;
	for (e = agfstout(g, n); e; e = agnxtout(g, e)) {
	    deg++;
	    prIndent();
	    fprintf(stderr, " %s -- %s\n", e->tail->name, e->head->name);
	    if (derived) {
		for (i = 0, ep = (Agedge_t **) ED_to_virt(e);
		     i < ED_count(e); i++, ep++) {
		    el = *ep;
		    prIndent();
		    fprintf(stderr, "   %s -- %s\n", el->tail->name,
			    el->head->name);
		}
	    }
	}
	if (deg == 0) {		/* no out edges */
	    if (!agfstin(g, n))	/* no in edges */
		fprintf(stderr, " %s\n", n->name);
	}
    }
    if (!derived) {
	bport_t *pp;
	if ((pp = PORTS(g))) {
	    int sz = NPORTS(g);
	    fprintf(stderr, "   %d ports\n", sz);
	    while (pp->e) {
		fprintf(stderr, "   %s : %s -- %s\n", pp->n->name,
			pp->e->tail->name, pp->e->head->name);
		pp++;
	    }
	}
    }
}
Example #20
0
Agedge_t *agnxtedge(Agraph_t * g, Agedge_t * e, Agnode_t * n)
{
    Agedge_t *rv;

    if (AGTYPE(e) == AGOUTEDGE) {
	rv = agnxtout(g, e);
	if (rv == NILedge) {
	    do {
		rv = !rv ? agfstin(g, n) : agnxtin(g,rv);
	    } while (rv && (rv->node == n));
	}
    } else {
	do {
	    rv = agnxtin(g, e);		/* so that we only see each edge once, */
		e = rv;
	} while (rv && (rv->node == n));	/* ignore loops as in-edges */
    }
    return rv;
}
Example #21
0
Agraph_t *firstsupg(Agraph_t *g)
{
    Agraph_t *mg;
    Agnode_t *n;
    Agedge_t *e;

    if (!g)
	return NULL;
    n = g->meta_node;
    if (!n) 
	return NULL;
    mg = n->graph;
    if (!mg) 
	return NULL;
    e = agfstin(mg, n);
    if (!e) 
	return NULL;
    return agusergraph(e->tail);
}
Example #22
0
/*-------------------------------------------------------------------------*\
 * 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;
}
Example #23
0
void agwrnode(Agraph_t * g, FILE * fp, Agnode_t * n, int full, int indent)
{
    char *myval, *defval;
    int i, didwrite = FALSE;
    int nprint = 0;
    Agdict_t *d = n->graph->univ->nodeattr;
    Agsym_t *a;

    if (full) {
	for (i = 0; i < dtsize(d->dict); i++) {
	    a = d->list[i];
	    if (a->printed == FALSE)
		continue;
	    myval = agget(n, a->name);
	    if (g == n->graph)
		defval = a->value;
	    else
		defval = agget(g->proto->n, a->name);
	    if (strcmp(defval, myval)) {
		if (didwrite == FALSE) {
		    tabover(fp, indent);
		    agputs(agcanonical(n->name), fp);
		    didwrite = TRUE;
		}
		writeattr(fp, &nprint, a->name, myval);
	    }
	}
	if (didwrite) {
	    agputs(nprint > 0 ? "];\n" : ";\n", fp);
	    return;
	}
    }
    if ((agfstout(g, n) == NULL) && (agfstin(g, n) == NULL)) {
	tabover(fp, indent);
	agputs(agcanonical(n->name), fp);
	agputs(";\n", fp);
    }
}
Agedge_t *firstin(Agnode_t *n)
{
    if (!n)
        return NULL;
    return agfstin(agraphof(n), n);
}
Example #25
0
grafo le_grafo(FILE *input) {

    Agraph_t *ag = agread(input, 0);
    if(!(ag && agisstrict(ag)))
        return NULL;

//	struct grafo *g = malloc(sizeof(struct grafo));
	grafo g = malloc(sizeof(struct grafo));
    if( !g ) return NULL;

	g->vertices = constroi_lista();
    g->nome     = malloc(sizeof(char) * strlen(agnameof(ag)+1));
    strcpy(g->nome, agnameof(ag));
    g->direcionado = agisdirected(ag);
    g->n_vertices  = (unsigned int)agnnodes(ag);
    g->n_arestas   = (unsigned int)agnedges(ag);
    g->ponderado   = 0;

	for( Agnode_t *v = agfstnode(ag); v; v = agnxtnode(ag,v) ){

		vertice vt = malloc(sizeof(struct vertice));
		vt->nome   = malloc(sizeof(char) * strlen(agnameof(v))+1);
		strcpy( vt->nome, agnameof(v) );
		vt->visitado = 0;
		vt->coberto  = 0;
		vt->arestas_saida   = constroi_lista();
		vt->arestas_entrada = constroi_lista();

		insere_lista(vt, g->vertices);
	}

	for( Agnode_t *v = agfstnode(ag); v; v = agnxtnode(ag,v) ){

		vertice vt = busca_vertice(g->vertices, agnameof(v));

		if( g-> direcionado ){
			for( Agedge_t *e = agfstout(ag,v); e; e = agnxtout(ag,e) ){
				aresta at = cria_aresta(g->vertices, e);
				if( at->peso != 0 ) g->ponderado = 1;
				insere_lista(at, vt->arestas_saida);
			}
			for( Agedge_t *e = agfstin(ag,v); e; e = agnxtin(ag,e) ){
				aresta at = cria_aresta(g->vertices, e);
				if( at->peso != 0 ) g->ponderado = 1;
				insere_lista(at, vt->arestas_entrada);
			}
		}
		else {

			for( Agedge_t *e = agfstedge(ag,v); e; e = agnxtedge(ag,e,v) ){
				if( agtail(e) != v ) continue;
				aresta at = cria_aresta(g->vertices, e);
				if( at->peso != 0 ) g->ponderado = 1;
				insere_lista(at, at->origem->arestas_saida);
				insere_lista(at, at->destino->arestas_saida);
			}
		}
	}

	if( agclose(ag) )
		return NULL;
	return g;
}
Example #26
0
Agedge_t *firstin(Agnode_t *n)
{
    if (!n)
	return NULL;
    return agfstin(n->graph, n);
}
Example #27
0
						/* could happen with an undirected edge */
						char 	*temp;
						temp = tp; tp = hp; hp = temp;
					}
					if (tp && tp[0]) {
						agxset(e,TAILX,tp);
						agstrfree(tp); 
					}
					if (hp && hp[0]) {
						agxset(e,HEADX,hp);
						agstrfree(hp); 
					}
				}
			}
		}
	}
	tailptr = SP->list; 
	while (tailptr) {
		freeptr = tailptr;
		tailptr = tailptr->link;
		if (TAG_OF(freeptr->data.obj) == TAG_NODE)
		free(freeptr);
	}
	if (G != SP->subg) abort();
	agpopproto(G);
	In_edge_stmt = SP->in_edge_stmt;
	old_SP = SP;
	SP = SP->link;
	In_decl = FALSE;
	free(old_SP);
	Current_class = TAG_GRAPH;
}

#if 0 /* NOT USED */
static Agraph_t *parent_of(Agraph_t *g)
{
	Agraph_t		*rv;
	rv = agusergraph(agfstin(g->meta_node->graph,g->meta_node)->tail);
	return rv;
}