[GRASS-SVN] r51584 - grass/trunk/vector/v.net.salesman
svn_grass at osgeo.org
svn_grass at osgeo.org
Tue May 1 08:15:31 EDT 2012
Author: mmetz
Date: 2012-05-01 05:15:30 -0700 (Tue, 01 May 2012)
New Revision: 51584
Modified:
grass/trunk/vector/v.net.salesman/main.c
Log:
v.net.salesman: add option to print out node sequence; add code comments
Modified: grass/trunk/vector/v.net.salesman/main.c
===================================================================
--- grass/trunk/vector/v.net.salesman/main.c 2012-05-01 08:37:26 UTC (rev 51583)
+++ grass/trunk/vector/v.net.salesman/main.c 2012-05-01 12:15:30 UTC (rev 51584)
@@ -82,7 +82,7 @@
int node, node1, node2, line;
double **cost_cache; /* pointer to array of pointers to arrays of cached costs */
struct Option *map, *output, *afield_opt, *tfield_opt, *afcol, *abcol,
- *type_opt, *term_opt;
+ *seq, *type_opt, *term_opt;
struct Flag *geo_f;
struct GModule *module;
struct Map_info Map, Out;
@@ -96,6 +96,7 @@
struct line_pnts *Points;
const char *dstr;
char buf[2000], buf2[2000];
+ FILE *fp;
/* Initialize the GIS calls */
G_gisinit(argv[0]);
@@ -140,6 +141,12 @@
abcol->required = NO;
abcol->description = _("EXPERIMENTAL: Arc backward direction cost column (number)");
+ seq = G_define_standard_option(G_OPT_F_OUTPUT);
+ seq->key = "sequence";
+ seq->type = TYPE_STRING;
+ seq->required = NO;
+ seq->description = _("Name for output file holding node sequence (\"-\" for stdout)");
+
term_opt = G_define_standard_option(G_OPT_V_CATS);
term_opt->key = "ccats";
term_opt->required = YES;
@@ -255,7 +262,9 @@
/* Create sorted lists of costs */
/* for a large number of cities this will become very slow, can not be fixed */
+ G_message(_("Creating cost cache..."));
for (i = 0; i < ncities; i++) {
+ G_percent(i, ncities, 2);
k = 0;
for (j = 0; j < ncities; j++) {
if (i == j)
@@ -268,7 +277,7 @@
G_fatal_error(_("Destination node [%d] is unreachable "
"from node [%d]"), cities[i], cities[j]);
- /* TODO: add to directional cost cache: from, to, cost */
+ /* add to directional cost cache: from, to, cost */
costs[i][k].city = j;
costs[i][k].cost = cost;
cost_cache[i][j] = cost;
@@ -277,9 +286,11 @@
}
qsort((void *)costs[i], k, sizeof(COST), cmp);
}
+ G_percent(1, 1, 2);
if (bcosts) {
for (i = 0; i < ncities; i++) {
+ /* this should be fast, no need for G_percent() */
k = 0;
for (j = 0; j < ncities; j++) {
if (i == j)
@@ -305,6 +316,7 @@
}
}
+ G_message(_("Searching for the shortest cycle..."));
/* find 2 cities with largest distance */
cost = city = -1;
for (i = 0; i < ncities; i++) {
@@ -393,9 +405,7 @@
cost = tmpcost;
}
}
-
add_city(city, city1);
-
}
if (debug_level >= 2) {
@@ -408,29 +418,32 @@
/* Create list of arcs */
cycle[ncities] = cycle[0]; /* close the cycle */
+ cost = 0.0;
for (i = 0; i < ncities; i++) {
node1 = cities[cycle[i]];
node2 = cities[cycle[i + 1]];
G_debug(2, " %d -> %d", node1, node2);
- ret = Vect_net_shortest_path(&Map, node1, node2, List, NULL);
+ ret = Vect_net_shortest_path(&Map, node1, node2, List, &tmpcost);
+ cost += tmpcost;
for (j = 0; j < List->n_values; j++) {
line = abs(List->value[j]);
Vect_list_append(StArcs, line);
Vect_get_line_nodes(&Map, line, &node1, &node2);
+ /* Vect_list_append() appends only if value not yet present !!!
+ * this breaks the correct sequence */
Vect_list_append(StNodes, node1);
Vect_list_append(StNodes, node2);
}
}
-
-
/* Write arcs to new map */
Vect_open_new(&Out, output->answer, Vect_is_3d(&Map));
Vect_hist_command(&Out);
- G_verbose_message(_("Cycle:"));
+ G_verbose_message(_("Cycle with total cost %f:"), cost);
G_verbose_message(_("Arcs' categories (layer %d, %d arcs):"), afield,
StArcs->n_values);
+
for (i = 0; i < StArcs->n_values; i++) {
line = StArcs->value[i];
ltype = Vect_read_line(&Map, Points, Cats, line);
@@ -443,15 +456,30 @@
else
sprintf(buf, "%d", cat);
}
+ /* buffer overflow in buf for many cities */
G_verbose_message("%s\n\n", buf);
+
+ if (seq->answer) {
+ if (strcmp(seq->answer, "-")) {
+ fp = fopen(seq->answer, "w");
+ if (!fp)
+ G_fatal_error(_("Unable to open file '%s' for writing"),
+ seq->answer);
+ }
+ else
+ fp = stdout;
- G_verbose_message(_("Nodes' categories (layer %d, %d nodes):"), tfield,
- StNodes->n_values);
+ fprintf(fp, "sequence;category\n");
+ }
+ else
+ fp = NULL;
+
k = 0;
- for (i = 0; i < TList->n_values; i++) {
+ /* this writes out only user-selected nodes, not all visited nodes */
+ for (i = 0; i < ncities; i++) {
double coor_x, coor_y, coor_z;
- node = TList->value[i];
+ node = cities[cycle[i]];
Vect_get_node_coor(&Map, node, &coor_x, &coor_y, &coor_z);
line = Vect_find_line(&Map, coor_x, coor_y, coor_z, GV_POINT, 0, 0, 0);
@@ -471,8 +499,16 @@
else
sprintf(buf, "%d", cat);
k++;
+ if (fp)
+ fprintf(fp, "%d;%d\n", k, cat);
}
+ G_verbose_message(_("Nodes' categories (layer %d, %d nodes):"), tfield,
+ ncities);
+ /* buffer overflow in buf for many cities */
G_verbose_message("%s\n\n", buf);
+
+ if (fp && fp != stdout)
+ fclose(fp);
Vect_build(&Out);
More information about the grass-commit
mailing list