示例#1
0
static int _print_node(dglGraph_s * pgraph, dglInt32_t * pnode, void *pvarg)
{
    FILE *f = (FILE *) pvarg;
    dglInt32_t *pedgeset;
    dglInt32_t *pedge;
    dglInt32_t *ptonode;
    dglInt32_t *pnattr;
    int iAttr, cAttr;
    int role;
    int i;
    dglEdgesetTraverser_s edgeaT;

    role = 0;
    if (dglNodeGet_Status(pgraph, pnode) & DGL_NS_HEAD) {
	role |= 1;
    }
    if (dglNodeGet_Status(pgraph, pnode) & DGL_NS_TAIL) {
	role |= 2;
    }

    fprintf(f, "HEAD %-8ld - %-s",
	    dglNodeGet_Id(pgraph, pnode),
	    (role > 2) ? "'H/T'" : (role == 2) ? "'T  '" : (role ==
							    1) ? "'H  '" :
	    "'A  '");

    if ((cAttr = dglGet_NodeAttrSize(pgraph)) > 0) {
	pnattr = dglNodeGet_Attr(pgraph, pnode);
	fprintf(f, " - HEAD ATTR [");
	for (iAttr = 0; iAttr < cAttr; iAttr++) {
	    if (iAttr && !(iAttr % 4))
		fprintf(f, " ");
	    fprintf(f, "%02x", ((unsigned char *)pnattr)[iAttr]);
	}
	fprintf(f, "]\n");
    }
    else {
	fprintf(f, "\n");
    }

    if (role & 1) {
	pedgeset = dglNodeGet_OutEdgeset(pgraph, pnode);

	dglEdgeset_T_Initialize(&edgeaT, pgraph, pedgeset);
	for (i = 0, pedge = dglEdgeset_T_First(&edgeaT);
	     pedge; i++, pedge = dglEdgeset_T_Next(&edgeaT)
	    ) {
	    ptonode = dglEdgeGet_Tail(pgraph, pedge);

	    if (ptonode) {
		role = 0;
		if (dglNodeGet_Status(pgraph, ptonode) & DGL_NS_HEAD) {
		    role |= 1;
		}
		if (dglNodeGet_Status(pgraph, ptonode) & DGL_NS_TAIL) {
		    role |= 2;
		}

		fprintf(f,
			"EDGE #%-8d: TAIL %-8ld - %-s - COST %-8ld - ID %-8ld",
			i, dglNodeGet_Id(pgraph, ptonode),
			(role > 2) ? "'H/T'" : (role ==
						2) ? "'T  '" : (role ==
								1) ? "'H  '" :
			"'A  '", dglEdgeGet_Cost(pgraph, pedge),
			dglEdgeGet_Id(pgraph, pedge)
		    );

		if ((cAttr = dglGet_NodeAttrSize(pgraph)) > 0) {
		    pnattr = dglNodeGet_Attr(pgraph, ptonode);
		    fprintf(f, " - TAIL ATTR [");
		    for (iAttr = 0; iAttr < cAttr; iAttr++) {
			if (iAttr && !(iAttr % 4))
			    fprintf(f, " ");
			fprintf(f, "%02x", ((unsigned char *)pnattr)[iAttr]);
		    }
		    fprintf(f, "]");
		}

		if ((cAttr = dglGet_EdgeAttrSize(pgraph)) > 0) {
		    pnattr = dglEdgeGet_Attr(pgraph, pedge);
		    fprintf(f, " - EDGE ATTR [");
		    for (iAttr = 0; iAttr < cAttr; iAttr++) {
			if (iAttr && !(iAttr % 4))
			    fprintf(f, " ");
			fprintf(f, "%02x", ((unsigned char *)pnattr)[iAttr]);
		    }
		    fprintf(f, "]\n");
		}
		else {
		    fprintf(f, "\n");
		}
	    }
	}
	dglEdgeset_T_Release(&edgeaT);
    }
    return 0;
}
示例#2
0
int main(int argc, char **argv)
{
    dglGraph_s graph;
    dglInt32_t from, to;

    int fd, nret, version;
    dglSPReport_s *pReport;
    dglInt32_t nDistance;
    dglSPCache_s spCache;
    ClipperContext_s clipctx, *pclipctx;

    /* program options
     */
    char *pszFilein;
    char *pszFrom;
    char *pszTo;
    char *pszDiscard;
    char *pszVersion;
    Boolean fDistance;
    Boolean fUnflatten;

    GNO_BEGIN			/*short       long        default     variable        help */
	GNO_OPTION("g", "graph", NULL, &pszFilein, "graph file to view")
	GNO_OPTION("v", "version", NULL, &pszVersion, "alter graph version")
	GNO_OPTION("f", "from", NULL, &pszFrom, "from-node id")
	GNO_OPTION("t", "to", NULL, &pszTo, "to-node id")
	GNO_OPTION("d", "discard", NULL, &pszDiscard,
		   "node to discard in clipper")
	GNO_SWITCH("D", "distance", False, &fDistance,
		   "Report shortest distance only")
	GNO_SWITCH("U", "unflatten", False, &fUnflatten,
		   "Unflatten the graph before processing")
    GNO_END if (GNO_PARSE(argc, argv) < 0)
    {
	return 1;
    }
    /* options parsed
     */

    if (pszFilein == NULL || pszFrom == NULL || pszTo == NULL) {
	GNO_HELP("incomplete parameters");
	return 1;
    }

    if (pszDiscard) {
	clipctx.node_to_discard = atol(pszDiscard);
	pclipctx = &clipctx;
    }
    else
	pclipctx = NULL;

    if (pszVersion) {
	version = atoi(pszVersion);
    }

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

    nret = dglRead(&graph, fd);

    close(fd);

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

    if (fUnflatten)
	dglUnflatten(&graph);

    if (pszVersion)
	dglSet_Version(&graph, version);

    from = atol(pszFrom);
    to = atol(pszTo);

    printf("shortest path: from-node %ld - to-node %ld\n\n", from, to);

    dglInitializeSPCache(&graph, &spCache);

    if (fDistance == False) {
	nret =
	    dglShortestPath(&graph, &pReport, from, to, clipper, pclipctx,
			    &spCache);

	if (nret == 0) {
	    printf("destination node is unreachable\n\n");
	}
	else if (nret < 0) {
	    fprintf(stderr, "dglShortestPath error: %s\n",
		    dglStrerror(&graph));
	}
	else {
	    int i;

	    printf
		("shortest path report: total edges %ld - total distance %ld\n",
		 pReport->cArc, pReport->nDistance);

	    for (i = 0; i < pReport->cArc; i++) {
		printf("edge[%d]: from %ld to %ld - travel cost %ld - user edgeid %ld - distance from start node %ld\n", i, pReport->pArc[i].nFrom, pReport->pArc[i].nTo, dglEdgeGet_Cost(&graph, pReport->pArc[i].pnEdge),	/* this is the cost from clip() */
		       dglEdgeGet_Id(&graph, pReport->pArc[i].pnEdge),
		       pReport->pArc[i].nDistance);
	    }
	    dglFreeSPReport(&graph, pReport);
	}
    }
    else {
	nret =
	    dglShortestDistance(&graph, &nDistance, from, to, clipper,
				pclipctx, &spCache);

	if (nret == 0) {
	    if (dglErrno(&graph) == 0) {
		printf("destination node is unreachable\n\n");
	    }
	}
	else if (nret < 0) {
	    fprintf(stderr, "dglShortestDistance error: %s\n",
		    dglStrerror(&graph));
	}
	else {
	    printf("shortest distance: %ld\n", nDistance);
	}
    }

    dglReleaseSPCache(&graph, &spCache);
    dglRelease(&graph);

    return 0;

}
示例#3
0
/*!
   \brief Find shortest path.

   Costs for 'from' and 'to' nodes are not considered (SP found even if
   'from' or 'to' are 'closed' (costs = -1) and costs of these
   nodes are not added to SP costs result.

   \param graph pointer to graph structure
   \param from from node
   \param to to node
   \param List list of line ids
   \param cost costs value

   \return number of segments
   \return 0 is correct for from = to, or List == NULL ), ? sum of costs is better return value,
   \return -1 destination unreachable
 */
int
Vect_graph_shortest_path(dglGraph_s * graph, int from, int to, struct ilist *List,
			 double *cost)
{
    int i, line, *pclip, cArc, nRet;
    dglSPReport_s *pSPReport;
    dglInt32_t nDistance;

    G_debug(3, "Vect_graph_shortest_path(): from = %d, to = %d", from, to);

    /* Note : if from == to dgl goes to nearest node and returns back (dgl feature) => 
     *         check here for from == to */

    if (List != NULL)
	Vect_reset_list(List);

    /* Check if from and to are identical, otherwise dglib returns path to neares node and back! */
    if (from == to) {
	if (cost != NULL)
	    *cost = 0;
	return 0;
    }

    From_node = from;

    pclip = NULL;
    if (List != NULL) {
	nRet =
	    dglShortestPath(graph, &pSPReport, (dglInt32_t) from,
			    (dglInt32_t) to, clipper, pclip, NULL);
    }
    else {
	nRet =
	    dglShortestDistance(graph, &nDistance, (dglInt32_t) from,
				(dglInt32_t) to, clipper, pclip, NULL);
    }

    if (nRet == 0) {
	if (cost != NULL)
	    *cost = PORT_DOUBLE_MAX;
	return -1;
    }
    else if (nRet < 0) {
	G_warning(_("dglShortestPath error: %s"), dglStrerror(graph));
	return -1;
    }

    if (List != NULL) {
	for (i = 0; i < pSPReport->cArc; i++) {
	    line = dglEdgeGet_Id(graph, pSPReport->pArc[i].pnEdge);
	    G_debug(2, "From %ld to %ld - cost %ld user %d distance %ld",
		    pSPReport->pArc[i].nFrom, pSPReport->pArc[i].nTo,
		    /* this is the cost from clip() */
		    dglEdgeGet_Cost(graph, pSPReport->pArc[i].pnEdge) / 1000,
		    line, pSPReport->pArc[i].nDistance);
	    Vect_list_append(List, line);
	}
    }

    if (cost != NULL) {
	if (List != NULL)
	    *cost = (double)pSPReport->nDistance / 1000;
	else
	    *cost = (double)nDistance / 1000;
    }

    if (List != NULL) {
	cArc = pSPReport->cArc;
	dglFreeSPReport(graph, pSPReport);
    }
    else
	cArc = 0;

    return (cArc);
}
示例#4
0
文件: path.c 项目: caomw/grass
/*!
   \brief Computes shortests paths to every node from nodes in "from".

   Array "dst" contains the length of the path or -1 if the node is not
   reachable. Prev contains edges from predecessor along the shortest
   path.

   \param graph input graph
   \param from list of 'from' positions
   \param dst list of 'to' positions
   \param[out] prev list of edges from predecessor along the shortest path

   \return 0 on success
   \return -1 on failure
 */
int NetA_distance_from_points(dglGraph_s *graph, struct ilist *from,
			      int *dst, dglInt32_t **prev)
{
    int i, nnodes;
    dglHeap_s heap;

    nnodes = dglGet_NodeCount(graph);
    dglEdgesetTraverser_s et;

    /* initialize costs and edge list */
    for (i = 1; i <= nnodes; i++) {
	dst[i] = -1;
	prev[i] = NULL;
    }

    dglHeapInit(&heap);

    for (i = 0; i < from->n_values; i++) {
	int v = from->value[i];

	if (dst[v] == 0)
	    continue;		/*ingore duplicates */
	dst[v] = 0;		/* make sure all from nodes are processed first */
	dglHeapData_u heap_data;

	heap_data.ul = v;
	dglHeapInsertMin(&heap, 0, ' ', heap_data);
    }
    while (1) {
	dglInt32_t v, dist;
	dglHeapNode_s heap_node;
	dglHeapData_u heap_data;

	if (!dglHeapExtractMin(&heap, &heap_node))
	    break;
	v = heap_node.value.ul;
	dist = heap_node.key;
	if (dst[v] < dist)
	    continue;

	dglInt32_t *edge;

	dglEdgeset_T_Initialize(&et, graph,
				dglNodeGet_OutEdgeset(graph,
						      dglGetNode(graph, v)));

	for (edge = dglEdgeset_T_First(&et); edge;
	     edge = dglEdgeset_T_Next(&et)) {
	    dglInt32_t *to = dglEdgeGet_Tail(graph, edge);
	    dglInt32_t to_id = dglNodeGet_Id(graph, to);
	    dglInt32_t d = dglEdgeGet_Cost(graph, edge);

	    if (dst[to_id] < 0 || dst[to_id] > dist + d) {
		dst[to_id] = dist + d;
		prev[to_id] = edge;
		heap_data.ul = to_id;
		dglHeapInsertMin(&heap, dist + d, ' ', heap_data);
	    }
	}

	dglEdgeset_T_Release(&et);
    }

    dglHeapFree(&heap, NULL);

    return 0;
}