123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228 |
- /* LIBDGL -- a Directed Graph Library implementation
- * Copyright (C) 2002 Roberto Micarelli
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
- /* best view tabstop=4
- */
- #include <stdio.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <unistd.h>
- #include <stdlib.h>
- #include <fcntl.h>
- #include <time.h>
- #include <errno.h>
- #include "../type.h"
- #include "../graph.h"
- #include "opt.h"
- extern int errno;
- /* If the clipper function returns 1 , the node is discarded and
- * the traversing of the graph toward its direction is abandoned.
- * Try to change the return value to 1 and see that the program
- * will not find any more paths to destinations.
- * The clipper receives data relating the network segment being examined.
- * The pvarg is a user pointer registered to dglShortestPath() and
- * passed back to the clipper.
- * As a demo, the main uses the ClipperContext_s structure to store a nodeid
- * that must be discarded during the search. The clipper receives
- * that pointer and checks every node against the one specified there.
- * If the node matches return 1 , otherwise return 0.
- */
- typedef struct
- {
- dglInt32_t node_to_discard;
- } ClipperContext_s;
- static int clipper(dglGraph_s * pgraph, dglSPClipInput_s * pIn, dglSPClipOutput_s * pOut, void *pvarg /* caller's pointer */
- )
- {
- ClipperContext_s *pclip = (ClipperContext_s *) pvarg;
- #if 0
- dglInt32_t *pnFromXYZ =
- (dglInt32_t *) dglNodeGet_Attr(pgraph, pIn->pnNodeFrom);
- dglInt32_t *pnToXYZ =
- (dglInt32_t *) dglNodeGet_Attr(pgraph, pIn->pnNodeTo);
- printf("clipper called:\n");
- printf(" from node: %ld - attributes x=%ld y=%ld z=%ld\n",
- dglNodeGet_Id(pgraph, pIn->pnNodeFrom), pnFromXYZ[0], pnFromXYZ[1],
- pnFromXYZ[2]);
- printf(" to node: %ld - attributes x=%ld y=%ld z=%ld\n",
- dglNodeGet_Id(pgraph, pIn->pnNodeTo), pnToXYZ[0], pnToXYZ[1],
- pnToXYZ[2]);
- printf(" edge : %ld\n", dglEdgeGet_Id(pgraph, pIn->pnEdge));
- #endif
- if (pclip) {
- if (dglNodeGet_Id(pgraph, pIn->pnNodeTo) == pclip->node_to_discard) {
- /*
- printf( " discarder.\n" );
- */
- return 1;
- }
- }
- /*
- printf( " accepted.\n" );
- */
- return 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;
- }
|