浏览代码

avoid buffer overflow, fix sequence lists

git-svn-id: https://svn.osgeo.org/grass/grass/trunk@51587 15284696-431f-4ddb-bdfa-cd5b030d7da7
Markus Metz 13 年之前
父节点
当前提交
03a3557109
共有 1 个文件被更改,包括 43 次插入31 次删除
  1. 43 31
      vector/v.net.salesman/main.c

+ 43 - 31
vector/v.net.salesman/main.c

@@ -74,6 +74,26 @@ void add_city(int city, int after)
 
 }
 
+/* like Vect_list_append(), but allows duplicates */
+int tsp_list_append(struct ilist *list, int val)
+{
+    size_t size;
+
+    if (list == NULL)
+	return 1;
+
+    if (list->n_values == list->alloc_values) {
+	size = (list->n_values + 1000) * sizeof(int);
+	list->value = (int *)G_realloc((void *)list->value, size);
+	list->alloc_values = list->n_values + 1000;
+    }
+
+    list->value[list->n_values] = val;
+    list->n_values++;
+
+    return 0;
+}
+
 
 int main(int argc, char **argv)
 {
@@ -95,7 +115,7 @@ int main(int argc, char **argv)
     struct line_cats *Cats;
     struct line_pnts *Points;
     const char *dstr;
-    char buf[2000], buf2[2000];
+/*    char buf[2000], buf2[2000]; */
     FILE *fp;
 
     /* Initialize the GIS calls */
@@ -218,7 +238,7 @@ int main(int argc, char **argv)
 	if (!(Vect_cat_get(Cats, tfield, &cat)))
 	    continue;
 	if (Vect_cat_in_cat_list(cat, Clist)) {
-	    Vect_list_append(TList, node);
+	    tsp_list_append(TList, node);
 	}
 	
     }
@@ -267,8 +287,10 @@ int main(int argc, char **argv)
 	G_percent(i, ncities, 2);
 	k = 0;
 	for (j = 0; j < ncities; j++) {
+	    cost_cache[i][j] = 0.0;
 	    if (i == j)
 		continue;
+
 	    ret =
 		Vect_net_shortest_path(&Map, cities[i], cities[j], NULL,
 				       &cost);
@@ -407,6 +429,8 @@ int main(int argc, char **argv)
 	}
 	add_city(city, city1);
     }
+    
+    /* TODO: optimize tour (some Lin–Kernighan method) */
 
     if (debug_level >= 2) {
 	/* debug print */
@@ -423,16 +447,16 @@ int main(int argc, char **argv)
 	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, &tmpcost);
-	cost += tmpcost;
+	ret = Vect_net_shortest_path(&Map, node1, node2, List, NULL);
+	cost += cost_cache[cycle[i]][cycle[i + 1]];
 	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);
+	    tsp_list_append(StArcs, line);
+	    Vect_get_line_nodes(&Map, line, &node1, &node2);
+	    tsp_list_append(StNodes, node1);
+	    tsp_list_append(StNodes, node2);
 	}
     }
 
@@ -440,8 +464,8 @@ int main(int argc, char **argv)
     Vect_open_new(&Out, output->answer, Vect_is_3d(&Map));
     Vect_hist_command(&Out);
 
-    G_verbose_message(_("Cycle with total cost %f:"), cost);
-    G_verbose_message(_("Arcs' categories (layer %d, %d arcs):"), afield,
+    G_verbose_message(_("Cycle with total cost %.3f"), cost);
+    G_debug(2, "Arcs' categories (layer %d, %d arcs):", afield,
 	    StArcs->n_values);
 
     for (i = 0; i < StArcs->n_values; i++) {
@@ -449,15 +473,8 @@ int main(int argc, char **argv)
 	ltype = Vect_read_line(&Map, Points, Cats, line);
 	Vect_write_line(&Out, ltype, Points, Cats);
 	Vect_cat_get(Cats, afield, &cat);
-	if (i > 0) {
-	    sprintf(buf2, ", %d", cat);
-	    strcat(buf, buf2);
-	}
-	else
-	    sprintf(buf, "%d", cat);
+	G_debug(2, "%d. arc: cat %d", i + 1, cat);
     }
-    /* buffer overflow in buf for many cities */
-    G_verbose_message("%s\n\n", buf);
     
     if (seq->answer) {
 	if (strcmp(seq->answer, "-")) {
@@ -469,13 +486,15 @@ int main(int argc, char **argv)
 	else
 	    fp = stdout;
 
-	fprintf(fp, "sequence;category\n");
+	fprintf(fp, "sequence;category;cost_to_next\n");
     }
     else
 	fp = NULL;
 
     k = 0;
     /* this writes out only user-selected nodes, not all visited nodes */
+    G_debug(2, "Nodes' categories (layer %d, %d nodes):", tfield,
+	    ncities);
     for (i = 0; i < ncities; i++) {
 	double coor_x, coor_y, coor_z;
 	
@@ -492,20 +511,13 @@ int main(int argc, char **argv)
 	if (!(Vect_cat_get(Cats, tfield, &cat)))
 	    continue;
 	Vect_write_line(&Out, ltype, Points, Cats);
-	if (k > 0) {
-	    sprintf(buf2, ", %d", cat);
-	    strcat(buf, buf2);
-	}
-	else
-	    sprintf(buf, "%d", cat);
 	k++;
-	if (fp)
-	    fprintf(fp, "%d;%d\n", k, cat);
+	if (fp) {
+	    fprintf(fp, "%d;%d;%.3f\n", k, cat, cost_cache[cycle[i]][cycle[i + 1]]);
+	}
+
+	G_debug(2, "%d. node: cat %d", 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);