// // Task 2: Shortest Route // // C version. // #include #include #include #include #include #include #include "args.h" #include "parseints.h" #include "printarray.h" typedef struct { int nroute; // number of routes int **route; // dynarray route[nroute] of int * int *routelen; // dynarray routelen[nroute] int ndistinctnodes; // number of distinct nodes int end; // the desired target (end) of the route } graph; // int nch = countch( target, str ); // Count and return the number of occurrences of target in str. // int countch( char target, char *str ) { int n=0; for( ; *str; str++ ) { if( *str == target ) n++; } return n; } // // bool in = isin( v, list, nel ); // Return true iff v is in list[nel]. // bool isin( int v, int *list, int nel ) { for( int i=0; iroute[g->nroute] // where each g->route[i] is of length g->routelen[i], fill in // g->ndistinctnodes // void count_distinct_nodes( graph *g ) { // dynarray of seen nodes, grown as needed int maxseen = 10; int *seen = malloc( maxseen * sizeof(int) ); assert( seen != NULL ); int nseen = 0; int nnodes = 0; for( int i=0; inroute; i++ ) { for( int j=0; jroutelen[i]; j++ ) { int node = g->route[i][j]; if( debug ) { printf( "debug: route %d, pos %d, node %d\n", i, j, node ); } if( ! isin( node, seen, nseen ) ) { if( nseen == maxseen ) { maxseen += 10; seen = realloc( seen, maxseen * sizeof(int) ); assert( seen != NULL ); } seen[nseen++] = node; nnodes++; } } } free( seen ); g->ndistinctnodes = nnodes; } // int nnext = next_nodes( here, g, visited, nvis, nextnodes ); // Given the graph g, determine all the possible one-step-next-nodes // from here that are not in visited[nvis], store those nodes into // nextnodes[] and return the number of next nodes. // int next_nodes( int here, graph *g, int *vis, int nvis, int *nextnodes ) { int nn = 0; for( int i=0; inroute; i++ ) { int prev = g->route[i][0]; for( int j=1; jroutelen[i]; j++ ) { int node = g->route[i][j]; // prev->node link and node->prev link if( here==prev && ! isin( node, vis, nvis )) { nextnodes[nn++] = node; } else if( here==node && ! isin( prev, vis, nvis )) { nextnodes[nn++] = prev; } prev = node; } } if( debug ) { printf( "debug: %d nextnodes from %d: ", nn, here ); print_int_array( 60, nn, nextnodes, ',', stdout ); putchar( '\n' ); } return nn; } static int *sr; // sr[ndistinctnodes] - curr shortest route static int srnel; // current number of elements in shortest route static int srlen; // current length of shortest route for comparison // // all_routes( start, g, done, ndone ); // Find all routes from start thru graph g to g->end, // where we have already visted done[ndone], setting sr[srlen] // to the shortest route found. // static void all_routes( int start, graph *g, int *done, int ndone ) { if( start == g->end ) { // found route done + end done[ ndone++ ] = g->end; if( debug ) { printf( "debug: found new route " ); print_int_array( 60, ndone, done, ',', stdout ); putchar( '\n' ); } if( ndone < srlen ) { for( int i=ndone; i