Example #1
0
static void
cloneSubg (Agraph_t* parent, Agraph_t* sg, Dt_t* emap)
{
    Agraph_t* subg;
    Agnode_t* t;
    Agedge_t* e;
    Agnode_t* newt;
    Agedge_t* newe;
    Agraph_t* newg;

    if (is_a_cluster(sg)) {
	newg = agsubg (parent, agnameof(sg), 1);
	parent = newg; 

	for (t = agfstnode(sg); t; t = agnxtnode(sg, t)) {
	    newt = agnode(newg, agnameof(t), 0);
            agsubnode(newg, newt, 1);
	    /* if e is in sg, both end points are, so we can use out edges */
	    for (e = agfstout(sg, t); e; e = agnxtout(sg, e)) {
		newe = mapEdge (emap, e);
		agsubedge(newg, newe, 1);
	    }
	}
    }

    for (subg = agfstsubg(sg); subg; subg = agnxtsubg(subg)) {
	cloneSubg(parent, subg, emap);
    }
}
Example #2
0
/* spanning_tree:
 * Construct spanning forest of g as subgraph
 */
static Agraph_t *spanning_tree(Agraph_t * g)
{
    Agnode_t *n;
    Agraph_t *tree;
    char gname[SMALLBUF];
    static int id = 0;

    sprintf(gname, "_span_%d", id++);
    tree = agsubg(g, gname);
    for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
	aginsert(tree, n);
	DISTONE(n) = 0;
	DISTTWO(n) = 0;
	UNSET_VISITED(n);
    }

    for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
	if (!VISITED(n)) {
	    TPARENT(n) = NULL;
	    dfs(g, n, tree);
	}
    }

    return tree;
}
Example #3
0
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;
}
Example #4
0
/* 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;
    edge_t *e;
    graph_t *clg;
    agxbuf xb;
    Dt_t *map;
    unsigned char buf[SMALLBUF];

    map = dtopen(&mapDisc, Dtoset);
    clg = agsubg(g, "__clusternodes");
    agxbinit(&xb, SMALLBUF, buf);
    for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
	for (e = agfstout(g, n); e; e = agnxtout(g, e)) {
	    checkCompound(e, clg, &xb, map);
	}
    }
    agxbfree(&xb);
    dtclose(map);
    rv = agnnodes(clg);
    for (n = agfstnode(clg); n; n = agnxtnode(clg, n)) {
	agdelete(g, n);
    }
    agclose(clg);
    if (rv)
	SET_CLUST_EDGE(g);
    return rv;
}
Example #5
0
/* 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;
}
Example #6
0
QGVSubGraph *QGVSubGraph::addSubGraph(const QString &name, bool cluster)
{
        Agraph_t *sgraph;
        if (cluster)
                sgraph = agsubg(_sgraph->graph(), ("cluster_" + name).toLocal8Bit().data(), TRUE);
        else
                sgraph = agsubg(_sgraph->graph(), name.toLocal8Bit().data(), TRUE);

        if (sgraph == NULL) {
                qWarning() << "Invalid subGraph :" << name;
                return 0;
        }

        QGVSubGraph *item = new QGVSubGraph(new QGVGraphPrivate(sgraph), _scene);
        _scene->_subGraphs.append(item);
        _scene->addItem(item);
        return item;
}
Example #7
0
static Agraph_t *makeBlockGraph(Agraph_t * g, circ_state * state)
{
    char name[SMALLBUF];
    Agraph_t *subg;

    sprintf(name, "_block_%d", state->blockCount++);
    subg = agsubg(g, name);
    return subg;
}
Example #8
0
static void anonsubg(void)
{
	char			buf[SMALLBUF];
	Agraph_t			*subg;

	In_decl = FALSE;
	anonname(buf);
	subg = agsubg(G,buf);
	push_subg(subg);
}
Example #9
0
/* clone_graph:
 * Create two copies of the argument graph
 * One is a subgraph, the other is an actual copy since we will be
 * adding edges to it.
 */
static Agraph_t*
clone_graph(Agraph_t* ing, Agraph_t** xg)
{
	Agraph_t*  clone;
	Agraph_t*  xclone;
	Agnode_t*  n;
	Agnode_t*  xn;
	Agnode_t*  xh;
	Agedge_t*  e;
	Agedge_t*  xe;
	char       gname[SMALLBUF];
	static int id = 0;

	sprintf (gname, "_clone_%d", id++);
	clone = agsubg(ing, gname);
	sprintf (gname, "_clone_%d", id++);
	xclone = agopen(gname, ing->kind);

	for(n = agfstnode(ing); n; n = agnxtnode(ing, n)) {
		aginsert (clone, n);
		xn = agnode (xclone, n->name);
		CLONE(n) = xn;
	}

	for(n = agfstnode(ing); n; n = agnxtnode(ing, n)) {
		xn = CLONE(n);
		for(e = agfstout(ing, n); e; e = agnxtout(ing, e)) {
			aginsert (clone, e);
			xh = CLONE(e->head); 
			xe = agedge (xclone, xn, xh);
			ORIGE(xe) = e;
			DEGREE(xn) += 1;
			DEGREE(xh) += 1;
		}
	}
	*xg = xclone;
#ifdef OLD
	clone = agopen("clone", root->kind);

	for(n = agfstnode(root); n; n = agnxtnode(root, n)) {
		cn = agnode(clone, n->name);		
		ND_alg(cn) = DATA(n);
		BCDONE(cn) = 0;
	}

	for(n = agfstnode(root); n; n = agnxtnode(root, n)) {
		Agnode_t *t = agnode(clone, n);
		for(e = agfstout(root, n); e; e = agnxtout(root, e)) {
			Agnode_t *h = agnode(clone, e->head->name);
			agedge(clone, t, h);
		}
	}
#endif
	return clone;
}
Example #10
0
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;
}
Example #11
0
static void anonsubg(void)
{
	static int		anon_id = 0;
	char			buf[SMALLBUF];
	Agraph_t			*subg;

	In_decl = FALSE;
	sprintf(buf,"_anonymous_%d",anon_id++);
	subg = agsubg(G,buf);
	push_subg(subg);
}
Example #12
0
/* 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");
    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);
}
Example #13
0
/* removeFill:
 * This removes all of the fill nodes added in mincross.
 * It appears to be sufficient to remove them only from the
 * rank array and fast node list of the root graph.
 */
static void
removeFill (Agraph_t * g)
{
    Agnode_t* n;
    Agnode_t* nxt;
    Agraph_t* sg = agsubg (g, "_new_rank", 0);

    if (!sg) return;
    for (n = agfstnode(sg); n; n = nxt) {
	nxt = agnxtnode(sg, n);
	delete_fast_node (g, n);
	remove_from_rank (g, n);
	dot_cleanup_node (n);
	agdelnode(g, n);
    }
    agdelsubg (g, sg);

}
Example #14
0
/* 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);
}
Example #15
0
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;
}
Example #16
0
static block_t*
createOneBlock(Agraph_t * g, circ_state * state)
{
    Agraph_t *subg;
    char name[SMALLBUF];
    block_t *bp;
    Agnode_t* n;

    sprintf(name, "_block_%d", state->blockCount++);
    subg = agsubg(g, name, 1);
    bp = mkBlock(subg);

    for (n = agfstnode(g); n; n = agnxtnode(g,n)) {
	agsubnode(bp->sub_graph, n, 1);
	BLOCK(n) = bp;
    }

    return bp;
}
Example #17
0
//-------------------------------------------------
Agraph_t *graph(Agraph_t *g, char *name)
{
    if (!gvc)
	return NULL;
    return agsubg(g, name);
}
//-------------------------------------------------
Agraph_t *findsubg(Agraph_t *g, char *name)
{
    if (!g || !name)
        return NULL;
    return agsubg(g, name, 0);
}
Example #19
0
// add subgraph
static inline Agraph_t* _agsubg(Agraph_t* object, QString name) {
	return agsubg(object, const_cast<char *>(qPrintable(name)));
}
Example #20
0
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);
}
//-------------------------------------------------
Agraph_t *graph(Agraph_t *g, char *name)
{
    if (!gvc)
        gv_init();
    return agsubg(g, name, 1);
}