예제 #1
0
int main(int argc, char **argv)
{
    dglGraph_s graph;
    int fd;
    int nret;

    /* program options
     */
    char *pszFilein;

    GNO_BEGIN			/* short  long        default     variable        help */
	GNO_OPTION("g", "graph", NULL, &pszFilein, "Graph file to view")
	GNO_END if (GNO_PARSE(argc, argv) < 0) {
	return 1;
    }
    /*
     * options parsed
     */

    if (pszFilein == NULL) {
	GNO_HELP("Incomplete parameters");
	return 1;
    }

    fd = open(pszFilein, O_RDONLY);
    if (fd < 0) {
	perror("open");
	return 1;
    }

    nret = dglRead(&graph, fd);

    if (nret < 0) {
	fprintf(stderr, "dglRead error: %s\n", dglStrerror(&graph));
	return 1;
    }

    close(fd);

    /* print the header
     */
    fprintf(stdout, "Version: %d\n", graph.Version);
    fprintf(stdout, "Byte Order: %s\n",
	    (graph.Endian ==
	     DGL_ENDIAN_LITTLE) ? "Little Endian" : "Big Endian");
    fprintf(stdout, "Node Attribute Size:  %ld\n", graph.NodeAttrSize);
    fprintf(stdout, "Edge Attribute Size:  %ld\n", graph.EdgeAttrSize);
    fprintf(stdout,
	    "Counters:  %ld Edges - %ld Nodes: %ld HEAD / %ld TAIL / %ld ALONE\n",
	    graph.cEdge, graph.cNode, graph.cHead, graph.cTail, graph.cAlone);
    fprintf(stdout, "Opaque Settings:\n");
    fprintf(stdout, "%10ld %10ld %10ld %10ld\n",
	    graph.aOpaqueSet[0], graph.aOpaqueSet[1],
	    graph.aOpaqueSet[2], graph.aOpaqueSet[3]);
    fprintf(stdout, "%10ld %10ld %10ld %10ld\n",
	    graph.aOpaqueSet[4], graph.aOpaqueSet[5],
	    graph.aOpaqueSet[6], graph.aOpaqueSet[7]);
    fprintf(stdout, "%10ld %10ld %10ld %10ld\n",
	    graph.aOpaqueSet[8], graph.aOpaqueSet[9],
	    graph.aOpaqueSet[10], graph.aOpaqueSet[11]);
    fprintf(stdout, "%10ld %10ld %10ld %10ld\n",
	    graph.aOpaqueSet[12], graph.aOpaqueSet[13],
	    graph.aOpaqueSet[14], graph.aOpaqueSet[15]);
    fprintf(stdout, "Total Cost: %lld\n", graph.nnCost);
    fprintf(stdout, "--\n");


    {
	dglInt32_t *pnode;
	dglNodeTraverser_s traverser;

	dglNode_T_Initialize(&traverser, &graph);
	for (pnode = dglNode_T_First(&traverser); pnode;
	     pnode = dglNode_T_Next(&traverser)) {
	    _print_node(&graph, pnode, stdout);
	}
	dglNode_T_Release(&traverser);
    }

    printf("\n");
    dglRelease(&graph);
    return 0;

}
예제 #2
0
/*!
   \brief Get number of articulation points in the graph

   \param graph input graph
   \param[out] articulation_list list of articulation points

   \return number of points
   \return -1 on error
 */
int NetA_articulation_points(dglGraph_s * graph,
                             struct ilist *articulation_list)
{
    int nnodes;
    int points = 0;

    dglEdgesetTraverser_s *current;	/*edge to be processed when the node is visited */
    int *tin, *min_tin;		/*time in, and smallest tin over all successors. 0 if not yet visited */
    dglInt32_t **parent;	/*parents of the nodes */
    dglInt32_t **stack;		/*stack of nodes */
    dglInt32_t **current_edge;	/*current edge for each node */
    int *mark;			/*marked articulation points */
    dglNodeTraverser_s nt;
    dglInt32_t *current_node;
    int stack_size;
    int i, time;

    nnodes = dglGet_NodeCount(graph);
    current =
        (dglEdgesetTraverser_s *) G_calloc(nnodes + 1,
                                           sizeof(dglEdgesetTraverser_s));
    tin = (int *)G_calloc(nnodes + 1, sizeof(int));
    min_tin = (int *)G_calloc(nnodes + 1, sizeof(int));
    parent = (dglInt32_t **) G_calloc(nnodes + 1, sizeof(dglInt32_t *));
    stack = (dglInt32_t **) G_calloc(nnodes + 1, sizeof(dglInt32_t *));
    current_edge = (dglInt32_t **) G_calloc(nnodes + 1, sizeof(dglInt32_t *));
    mark = (int *)G_calloc(nnodes + 1, sizeof(int));
    if (!tin || !min_tin || !parent || !stack || !current || !mark) {
        G_fatal_error(_("Out of memory"));
        return -1;
    }

    for (i = 1; i <= nnodes; i++) {
        dglEdgeset_T_Initialize(&current[i], graph,
                                dglNodeGet_OutEdgeset(graph,
                                        dglGetNode(graph, i)));
        current_edge[i] = dglEdgeset_T_First(&current[i]);
        tin[i] = mark[i] = 0;
    }

    dglNode_T_Initialize(&nt, graph);

    time = 0;
    for (current_node = dglNode_T_First(&nt); current_node;
            current_node = dglNode_T_Next(&nt)) {
        dglInt32_t current_id = dglNodeGet_Id(graph, current_node);

        if (tin[current_id] == 0) {
            int children = 0;	/*number of subtrees rooted at the root/current_node */

            stack[0] = current_node;
            stack_size = 1;
            parent[current_id] = NULL;
            while (stack_size) {
                dglInt32_t *node = stack[stack_size - 1];
                dglInt32_t node_id = dglNodeGet_Id(graph, node);

                if (tin[node_id] == 0)	/*vertex visited for the first time */
                    min_tin[node_id] = tin[node_id] = ++time;
                else {		/*return from the recursion */
                    dglInt32_t to = dglNodeGet_Id(graph,
                                                  dglEdgeGet_Tail(graph,
                                                          current_edge
                                                          [node_id]));
                    if (min_tin[to] >= tin[node_id])	/*no path from the subtree above the current node */
                        mark[node_id] = 1;	/*so the current node must be an articulation point */

                    if (min_tin[to] < min_tin[node_id])
                        min_tin[node_id] = min_tin[to];
                    current_edge[node_id] = dglEdgeset_T_Next(&current[node_id]);	/*proceed to the next edge */
                }
                /*try next edges */
                for (; current_edge[node_id]; current_edge[node_id] = dglEdgeset_T_Next(&current[node_id])) {
                    dglInt32_t *to =
                        dglEdgeGet_Tail(graph, current_edge[node_id]);
                    if (to == parent[node_id])
                        continue;	/*skip parent */
                    int to_id = dglNodeGet_Id(graph, to);

                    if (tin[to_id]) {	/*back edge, cannot be a bridge/articualtion point */
                        if (tin[to_id] < min_tin[node_id])
                            min_tin[node_id] = tin[to_id];
                    }
                    else {	/*forward edge */
                        if (node_id == current_id)
                            children++;	/*if root, increase number of children */
                        parent[to_id] = node;
                        stack[stack_size++] = to;
                        break;
                    }
                }
                if (!current_edge[node_id])
                    stack_size--;	/*current node completely processed */
            }
            if (children > 1)
                mark[current_id] = 1;	/*if the root has more than 1 subtrees rooted at it, then it is an
					 * articulation point */
        }
    }

    for (i = 1; i <= nnodes; i++)
        if (mark[i]) {
            points++;
            Vect_list_append(articulation_list, i);
        }

    dglNode_T_Release(&nt);
    for (i = 1; i <= nnodes; i++)
        dglEdgeset_T_Release(&current[i]);

    G_free(current);
    G_free(tin);
    G_free(min_tin);
    G_free(parent);
    G_free(stack);
    G_free(current_edge);
    return points;
}
예제 #3
0
파일: components.c 프로젝트: rkrug/grass-ci
/*!
   \brief Computes weakly connected components

   \param graph input graph
   \param[out] component array of component ids

   \return number of components
   \return -1 on failure
 */
int NetA_weakly_connected_components(dglGraph_s * graph, int *component)
{
    int nnodes, i;
    dglInt32_t *stack;
    int stack_size, components;
    dglInt32_t *cur_node;
    dglNodeTraverser_s nt;
    int have_node_costs;
    dglInt32_t ncost;

    if (graph->Version < 2) {
	G_warning("Directed graph must be version 2 or 3 for NetA_weakly_connected_components()");
	return -1;
    }

    components = 0;
    nnodes = dglGet_NodeCount(graph);
    stack = (dglInt32_t *) G_calloc(nnodes + 1, sizeof(dglInt32_t));
    if (!stack) {
	G_fatal_error(_("Out of memory"));
	return -1;
    }

    for (i = 1; i <= nnodes; i++)
	component[i] = 0;

    ncost = 0;
    have_node_costs = dglGet_NodeAttrSize(graph);

    dglNode_T_Initialize(&nt, graph);

    for (cur_node = dglNode_T_First(&nt); cur_node;
	 cur_node = dglNode_T_Next(&nt)) {
	dglInt32_t cur_node_id = dglNodeGet_Id(graph, cur_node);

	if (!component[cur_node_id]) {
	    stack[0] = cur_node_id;
	    stack_size = 1;
	    component[cur_node_id] = ++components;
	    while (stack_size) {
		dglInt32_t *node, *edgeset, *edge;
		dglEdgesetTraverser_s et;

		node = dglGetNode(graph, stack[--stack_size]);
		edgeset = dglNodeGet_OutEdgeset(graph, node);
		dglEdgeset_T_Initialize(&et, graph, edgeset);
		for (edge = dglEdgeset_T_First(&et); edge;
		     edge = dglEdgeset_T_Next(&et)) {
		    dglInt32_t to;

		    to = dglNodeGet_Id(graph, dglEdgeGet_Tail(graph, edge));
		    if (!component[to]) {
			component[to] = components;
			/* do not go through closed nodes */
			if (have_node_costs) {
			    memcpy(&ncost, dglNodeGet_Attr(graph, dglEdgeGet_Tail(graph, edge)),
				   sizeof(ncost));
			}
			if (ncost >= 0)
			    stack[stack_size++] = to;
		    }
		}
		dglEdgeset_T_Release(&et);

		edgeset = dglNodeGet_InEdgeset(graph, node);
		dglEdgeset_T_Initialize(&et, graph, edgeset);
		for (edge = dglEdgeset_T_First(&et); edge;
		     edge = dglEdgeset_T_Next(&et)) {
		    dglInt32_t to;

		    to = dglNodeGet_Id(graph, dglEdgeGet_Head(graph, edge));
		    if (!component[to]) {
			component[to] = components;
			/* do not go through closed nodes */
			if (have_node_costs) {
			    memcpy(&ncost, dglNodeGet_Attr(graph, dglEdgeGet_Tail(graph, edge)),
				   sizeof(ncost));
			}
			if (ncost >= 0)
			    stack[stack_size++] = to;
		    }
		}
		dglEdgeset_T_Release(&et);
	    }
	}
    }
    dglNode_T_Release(&nt);

    G_free(stack);
    return components;
}
예제 #4
0
/*!
   \brief Get number of bridges in the graph.

   Bridge is an array containing the indices of the bridges.

   \param graph input graph
   \param[out] bridge_list list of bridges

   \return number of bridges, -1 on error
 */
int NetA_compute_bridges(dglGraph_s * graph, struct ilist *bridge_list)
{
    int nnodes;
    int bridges = 0;

    dglEdgesetTraverser_s *current;	/*edge to be processed when the node is visited */
    int *tin, *min_tin;		/*time in, and smallest tin over all successors. 0 if not yet visited */
    dglInt32_t *parent;		/*edge from parent to the node */
    dglInt32_t **stack;		/*stack of nodes */
    dglInt32_t **current_edge;	/*current edge for each node */
    dglNodeTraverser_s nt;
    dglInt32_t *current_node;
    int stack_size;
    int i, time;

    nnodes = dglGet_NodeCount(graph);
    current =
	(dglEdgesetTraverser_s *) G_calloc(nnodes + 1,
					   sizeof(dglEdgesetTraverser_s));
    tin = (int *)G_calloc(nnodes + 1, sizeof(int));
    min_tin = (int *)G_calloc(nnodes + 1, sizeof(int));
    parent = (dglInt32_t *) G_calloc(nnodes + 1, sizeof(dglInt32_t));
    stack = (dglInt32_t **) G_calloc(nnodes + 1, sizeof(dglInt32_t *));
    current_edge = (dglInt32_t **) G_calloc(nnodes + 1, sizeof(dglInt32_t *));
    if (!tin || !min_tin || !parent || !stack || !current) {
	G_fatal_error(_("Out of memory"));
	return -1;
    }

    for (i = 1; i <= nnodes; i++) {
	dglEdgeset_T_Initialize(&current[i], graph,
				dglNodeGet_OutEdgeset(graph,
						      dglGetNode(graph, i)));
	current_edge[i] = dglEdgeset_T_First(&current[i]);
	tin[i] = 0;
    }

    dglNode_T_Initialize(&nt, graph);

    time = 0;
    for (current_node = dglNode_T_First(&nt); current_node;
	 current_node = dglNode_T_Next(&nt)) {
	dglInt32_t current_id = dglNodeGet_Id(graph, current_node);

	if (tin[current_id] == 0) {
	    stack[0] = current_node;
	    stack_size = 1;
	    parent[current_id] = 0;
	    while (stack_size) {
		dglInt32_t *node = stack[stack_size - 1];
		dglInt32_t node_id = dglNodeGet_Id(graph, node);

		if (tin[node_id] == 0)	/*vertex visited for the first time */
		    min_tin[node_id] = tin[node_id] = ++time;
		else {		/*return from the recursion */
		    dglInt32_t to = dglNodeGet_Id(graph,
						  dglEdgeGet_Tail(graph,
								  current_edge
								  [node_id]));
		    if (min_tin[to] > tin[node_id]) {	/*no path from the subtree above the current node */
			Vect_list_append(bridge_list, dglEdgeGet_Id(graph, current_edge[node_id]));	/*so it must be a bridge */
			bridges++;
		    }
		    if (min_tin[to] < min_tin[node_id])
			min_tin[node_id] = min_tin[to];
		    current_edge[node_id] = dglEdgeset_T_Next(&current[node_id]);	/*proceed to the next edge */
		}
		for (; current_edge[node_id]; current_edge[node_id] = dglEdgeset_T_Next(&current[node_id])) {	/*try next edges */
		    dglInt32_t *to =
			dglEdgeGet_Tail(graph, current_edge[node_id]);
		    dglInt32_t edge_id =
			dglEdgeGet_Id(graph, current_edge[node_id]);
		    if (abs(edge_id) == parent[node_id])
			continue;	/*skip edge we used to travel to this node */
		    int to_id = dglNodeGet_Id(graph, to);

		    if (tin[to_id]) {	/*back edge, cannot be a bridge/articualtion point */
			if (tin[to_id] < min_tin[node_id])
			    min_tin[node_id] = tin[to_id];
		    }
		    else {	/*forward edge */
			parent[to_id] = abs(edge_id);
			stack[stack_size++] = to;
			break;
		    }
		}
		if (!current_edge[node_id])
		    stack_size--;	/*current node completely processed */
	    }
	}
    }

    dglNode_T_Release(&nt);
    for (i = 1; i <= nnodes; i++)
	dglEdgeset_T_Release(&current[i]);

    G_free(current);
    G_free(tin);
    G_free(min_tin);
    G_free(parent);
    G_free(stack);
    G_free(current_edge);
    return bridges;
}
예제 #5
0
파일: components.c 프로젝트: rkrug/grass-ci
/*!
   \brief Computes strongly connected components with Kosaraju's 
   two-pass algorithm

   \param graph input graph
   \param[out] component array of component ids

   \return number of components
   \return -1 on failure
 */
int NetA_strongly_connected_components(dglGraph_s * graph, int *component)
{
    int nnodes, i;
    dglInt32_t *stack, *order;
    int *processed;
    int stack_size, order_size, components;
    dglInt32_t *cur_node;
    dglNodeTraverser_s nt;
    int have_node_costs;
    dglInt32_t ncost;

    if (graph->Version < 2) {
	G_warning("Directed graph must be version 2 or 3 for NetA_strongly_connected_components()");
	return -1;
    }

    components = 0;
    nnodes = dglGet_NodeCount(graph);
    stack = (dglInt32_t *) G_calloc(nnodes + 1, sizeof(dglInt32_t));
    order = (dglInt32_t *) G_calloc(nnodes + 1, sizeof(dglInt32_t));
    processed = (int *)G_calloc(nnodes + 1, sizeof(int));
    if (!stack || !order || !processed) {
	G_fatal_error(_("Out of memory"));
	return -1;
    }

    for (i = 1; i <= nnodes; i++) {
	component[i] = 0;
    }

    ncost = 0;
    have_node_costs = dglGet_NodeAttrSize(graph);

    order_size = 0;
    dglNode_T_Initialize(&nt, graph);

    for (cur_node = dglNode_T_First(&nt); cur_node;
	 cur_node = dglNode_T_Next(&nt)) {
	dglInt32_t cur_node_id = dglNodeGet_Id(graph, cur_node);

	if (!component[cur_node_id]) {
	    component[cur_node_id] = --components;
	    stack[0] = cur_node_id;
	    stack_size = 1;
	    while (stack_size) {
		dglInt32_t *node, *edgeset, *edge;
		dglEdgesetTraverser_s et;
		dglInt32_t node_id = stack[stack_size - 1];

		if (processed[node_id]) {
		    stack_size--;
		    order[order_size++] = node_id;
		    continue;
		}
		processed[node_id] = 1;

		node = dglGetNode(graph, node_id);
		edgeset = dglNodeGet_OutEdgeset(graph, node);
		dglEdgeset_T_Initialize(&et, graph, edgeset);
		for (edge = dglEdgeset_T_First(&et); edge;
		     edge = dglEdgeset_T_Next(&et)) {
		    dglInt32_t to;

		    to = dglNodeGet_Id(graph, dglEdgeGet_Tail(graph, edge));
		    if (!component[to]) {
			component[to] = components;
			/* do not go through closed nodes */
			if (have_node_costs) {
			    memcpy(&ncost, dglNodeGet_Attr(graph, dglEdgeGet_Tail(graph, edge)),
				   sizeof(ncost));
			}
			if (ncost < 0)
			    processed[to] = 1;

			stack[stack_size++] = to;
		    }
		}
		dglEdgeset_T_Release(&et);
	    }
	}
    }

    dglNode_T_Release(&nt);

    components = 0;
    dglNode_T_Initialize(&nt, graph);

    while (order_size) {
	dglInt32_t cur_node_id = order[--order_size];
	int cur_comp = component[cur_node_id];

	if (cur_comp < 1) {
	    component[cur_node_id] = ++components;
	    stack[0] = cur_node_id;
	    stack_size = 1;
	    while (stack_size) {
		dglInt32_t *node, *edgeset, *edge;
		dglEdgesetTraverser_s et;
		dglInt32_t node_id = stack[--stack_size];

		node = dglGetNode(graph, node_id);
		edgeset = dglNodeGet_InEdgeset(graph, node);
		dglEdgeset_T_Initialize(&et, graph, edgeset);
		for (edge = dglEdgeset_T_First(&et); edge;
		     edge = dglEdgeset_T_Next(&et)) {
		    dglInt32_t to;

		    to = dglNodeGet_Id(graph, dglEdgeGet_Head(graph, edge));
		    if (component[to] == cur_comp) {
			component[to] = components;
			/* do not go through closed nodes */
			if (have_node_costs) {
			    memcpy(&ncost, dglNodeGet_Attr(graph, dglEdgeGet_Head(graph, edge)),
				   sizeof(ncost));
			}
			if (ncost >= 0)
			    stack[stack_size++] = to;
		    }
		}
		dglEdgeset_T_Release(&et);
	    }
	}
    }
    dglNode_T_Release(&nt);

    G_free(stack);
    G_free(order);
    G_free(processed);
    return components;
}