alloc.c 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346
  1. #include <stdlib.h>
  2. #include <string.h>
  3. #include <time.h>
  4. #include <grass/gis.h>
  5. #include <grass/vector.h>
  6. #include <grass/dbmi.h>
  7. #include <grass/dgl/graph.h>
  8. #include <grass/glocale.h>
  9. #include "alloc.h"
  10. int alloc_from_centers_loop_tt(struct Map_info *Map, NODE *Nodes,
  11. CENTER *Centers, int ncenters,
  12. int tucfield)
  13. {
  14. int center, line, nlines, i;
  15. int node1;
  16. int cat;
  17. struct line_cats *Cats;
  18. struct line_pnts *Points;
  19. double cost, n1cost, n2cost;
  20. int ret;
  21. Cats = Vect_new_cats_struct();
  22. Points = Vect_new_line_struct();
  23. nlines = Vect_get_num_lines(Map);
  24. for (i = 2; i <= (nlines * 2 + 2); i++) {
  25. Nodes[i].center = -1;/* NOTE: first two items of Nodes are not used */
  26. Nodes[i].cost = -1;
  27. Nodes[i].edge = 0;
  28. }
  29. for (center = 0; center < ncenters; center++) {
  30. G_percent(center, ncenters, 1);
  31. node1 = Centers[center].node;
  32. Vect_net_get_node_cost(Map, node1, &n1cost);
  33. G_debug(2, "center = %d node = %d cat = %d", center, node1,
  34. Centers[center].cat);
  35. for (line = 1; line <= nlines; line++) {
  36. G_debug(5, " node1 = %d line = %d", node1, line);
  37. Vect_net_get_node_cost(Map, line, &n2cost);
  38. /* closed, left it as not attached */
  39. if (Vect_read_line(Map, Points, Cats, line) < 0)
  40. continue;
  41. if (Vect_get_line_type(Map, line) != GV_LINE)
  42. continue;
  43. if (!Vect_cat_get(Cats, tucfield, &cat))
  44. continue;
  45. for (i = 0; i < 2; i++) {
  46. if (i == 1)
  47. cat *= -1;
  48. ret =
  49. Vect_net_ttb_shortest_path(Map, node1, 0, cat, 1,
  50. tucfield, NULL,
  51. &cost);
  52. if (ret == -1) {
  53. continue;
  54. } /* node unreachable */
  55. /* We must add center node costs (not calculated by Vect_net_shortest_path() ), but
  56. * only if center and node are not identical, because at the end node cost is add later */
  57. if (ret != 1)
  58. cost += n1cost;
  59. G_debug(5,
  60. "Arc nodes: %d %d cost: %f (x old cent: %d old cost %f",
  61. node1, line, cost, Nodes[line * 2 + i].center,
  62. Nodes[line * 2 + i].cost);
  63. if (Nodes[line * 2 + i].center == -1 ||
  64. Nodes[line * 2 + i].cost > cost) {
  65. Nodes[line * 2 + i].cost = cost;
  66. Nodes[line * 2 + i].center = center;
  67. }
  68. }
  69. }
  70. }
  71. G_percent(1, 1, 1);
  72. Vect_destroy_cats_struct(Cats);
  73. Vect_destroy_line_struct(Points);
  74. return 0;
  75. }
  76. int alloc_to_centers_loop_tt(struct Map_info *Map, NODE *Nodes,
  77. CENTER *Centers, int ncenters,
  78. int tucfield)
  79. {
  80. int center, line, nlines, i;
  81. int node1;
  82. int cat;
  83. struct line_cats *Cats;
  84. struct line_pnts *Points;
  85. double cost, n1cost, n2cost;
  86. int ret;
  87. Cats = Vect_new_cats_struct();
  88. Points = Vect_new_line_struct();
  89. nlines = Vect_get_num_lines(Map);
  90. for (i = 2; i <= (nlines * 2 + 2); i++) {
  91. Nodes[i].center = -1;/* NOTE: first two items of Nodes are not used */
  92. Nodes[i].cost = -1;
  93. Nodes[i].edge = 0;
  94. }
  95. for (line = 1; line <= nlines; line++) {
  96. G_debug(5, " line = %d", line);
  97. Vect_net_get_node_cost(Map, line, &n2cost);
  98. /* closed, left it as not attached */
  99. if (Vect_read_line(Map, Points, Cats, line) < 0)
  100. continue;
  101. if (Vect_get_line_type(Map, line) != GV_LINE)
  102. continue;
  103. if (!Vect_cat_get(Cats, tucfield, &cat))
  104. continue;
  105. for (center = 0; center < ncenters; center++) {
  106. G_percent(center, ncenters, 1);
  107. node1 = Centers[center].node;
  108. Vect_net_get_node_cost(Map, node1, &n1cost);
  109. G_debug(2, "center = %d node = %d cat = %d", center, node1,
  110. Centers[center].cat);
  111. for (i = 0; i < 2; i++) {
  112. if (i == 1)
  113. cat *= -1;
  114. ret =
  115. Vect_net_ttb_shortest_path(Map, cat, 1, node1, 0,
  116. tucfield, NULL,
  117. &cost);
  118. if (ret == -1) {
  119. continue;
  120. } /* node unreachable */
  121. /* We must add center node costs (not calculated by Vect_net_shortest_path() ), but
  122. * only if center and node are not identical, because at the end node cost is add later */
  123. if (ret != 1)
  124. cost += n1cost;
  125. G_debug(5,
  126. "Arc nodes: %d %d cost: %f (x old cent: %d old cost %f",
  127. node1, line, cost, Nodes[line * 2 + i].center,
  128. Nodes[line * 2 + i].cost);
  129. if (Nodes[line * 2 + i].center == -1 ||
  130. Nodes[line * 2 + i].cost > cost) {
  131. Nodes[line * 2 + i].cost = cost;
  132. Nodes[line * 2 + i].center = center;
  133. }
  134. }
  135. }
  136. }
  137. G_percent(1, 1, 1);
  138. Vect_destroy_cats_struct(Cats);
  139. Vect_destroy_line_struct(Points);
  140. return 0;
  141. }
  142. int alloc_from_centers(dglGraph_s *graph, NODE *Nodes, CENTER *Centers, int ncenters)
  143. {
  144. int i, nnodes;
  145. dglHeap_s heap;
  146. dglEdgesetTraverser_s et;
  147. int have_node_costs;
  148. dglInt32_t ncost;
  149. nnodes = dglGet_NodeCount(graph);
  150. /* initialize nodes */
  151. for (i = 1; i <= nnodes; i++) {
  152. Nodes[i].cost = -1;
  153. Nodes[i].center = -1;
  154. Nodes[i].edge = 0;
  155. }
  156. ncost = 0;
  157. have_node_costs = dglGet_NodeAttrSize(graph);
  158. dglHeapInit(&heap);
  159. for (i = 0; i < ncenters; i++) {
  160. int v = Centers[i].node;
  161. if (Nodes[v].cost == 0)
  162. continue; /* ignore duplicates */
  163. Nodes[v].cost = 0; /* make sure all centers are processed first */
  164. Nodes[v].center = i;
  165. dglHeapData_u heap_data;
  166. heap_data.ul = v;
  167. dglHeapInsertMin(&heap, 0, ' ', heap_data);
  168. }
  169. while (1) {
  170. dglInt32_t v, dist;
  171. dglHeapNode_s heap_node;
  172. dglHeapData_u heap_data;
  173. dglInt32_t *edge;
  174. dglInt32_t *node;
  175. if (!dglHeapExtractMin(&heap, &heap_node))
  176. break;
  177. v = heap_node.value.ul;
  178. dist = heap_node.key;
  179. if (Nodes[v].cost < dist)
  180. continue;
  181. node = dglGetNode(graph, v);
  182. if (have_node_costs && Nodes[v].edge) {
  183. memcpy(&ncost, dglNodeGet_Attr(graph, node),
  184. sizeof(ncost));
  185. if (ncost > 0)
  186. dist += ncost;
  187. /* do not go through closed nodes */
  188. if (ncost < 0)
  189. continue;
  190. }
  191. dglEdgeset_T_Initialize(&et, graph,
  192. dglNodeGet_OutEdgeset(graph, node));
  193. for (edge = dglEdgeset_T_First(&et); edge;
  194. edge = dglEdgeset_T_Next(&et)) {
  195. dglInt32_t *to = dglEdgeGet_Tail(graph, edge);
  196. dglInt32_t to_id = dglNodeGet_Id(graph, to);
  197. dglInt32_t d = dglEdgeGet_Cost(graph, edge);
  198. if (Nodes[to_id].cost < 0 || Nodes[to_id].cost > dist + d) {
  199. Nodes[to_id].cost = dist + d;
  200. Nodes[to_id].edge = dglEdgeGet_Id(graph, edge);
  201. Nodes[to_id].center = Nodes[v].center;
  202. heap_data.ul = to_id;
  203. dglHeapInsertMin(&heap, dist + d, ' ', heap_data);
  204. }
  205. }
  206. dglEdgeset_T_Release(&et);
  207. }
  208. dglHeapFree(&heap, NULL);
  209. return 0;
  210. }
  211. int alloc_to_centers(dglGraph_s *graph, NODE *Nodes, CENTER *Centers, int ncenters)
  212. {
  213. int i, nnodes;
  214. dglHeap_s heap;
  215. dglEdgesetTraverser_s et;
  216. int have_node_costs;
  217. dglInt32_t ncost;
  218. if (graph->Version < 2) {
  219. G_warning("Directed graph must be version 2 or 3 for distances to centers");
  220. return -1;
  221. }
  222. nnodes = dglGet_NodeCount(graph);
  223. /* initialize nodes */
  224. for (i = 1; i <= nnodes; i++) {
  225. Nodes[i].cost = -1;
  226. Nodes[i].center = -1;
  227. Nodes[i].edge = 0;
  228. }
  229. ncost = 0;
  230. have_node_costs = dglGet_NodeAttrSize(graph);
  231. dglHeapInit(&heap);
  232. for (i = 0; i < ncenters; i++) {
  233. int v = Centers[i].node;
  234. if (Nodes[v].cost == 0)
  235. continue; /* ignore duplicates */
  236. Nodes[v].cost = 0; /* make sure all centers are processed first */
  237. Nodes[v].center = i;
  238. dglHeapData_u heap_data;
  239. heap_data.ul = v;
  240. dglHeapInsertMin(&heap, 0, ' ', heap_data);
  241. }
  242. while (1) {
  243. dglInt32_t v, dist;
  244. dglHeapNode_s heap_node;
  245. dglHeapData_u heap_data;
  246. dglInt32_t *edge;
  247. dglInt32_t *node;
  248. if (!dglHeapExtractMin(&heap, &heap_node))
  249. break;
  250. v = heap_node.value.ul;
  251. dist = heap_node.key;
  252. if (Nodes[v].cost < dist)
  253. continue;
  254. node = dglGetNode(graph, v);
  255. if (have_node_costs && Nodes[v].edge) {
  256. memcpy(&ncost, dglNodeGet_Attr(graph, node),
  257. sizeof(ncost));
  258. if (ncost > 0)
  259. dist += ncost;
  260. /* do not go through closed nodes */
  261. if (ncost < 0)
  262. continue;
  263. }
  264. dglEdgeset_T_Initialize(&et, graph,
  265. dglNodeGet_InEdgeset(graph, node));
  266. for (edge = dglEdgeset_T_First(&et); edge;
  267. edge = dglEdgeset_T_Next(&et)) {
  268. dglInt32_t *from = dglEdgeGet_Head(graph, edge);
  269. dglInt32_t from_id = dglNodeGet_Id(graph, from);
  270. dglInt32_t d = dglEdgeGet_Cost(graph, edge);
  271. if (Nodes[from_id].cost < 0 || Nodes[from_id].cost > dist + d) {
  272. Nodes[from_id].cost = dist + d;
  273. Nodes[from_id].edge = dglEdgeGet_Id(graph, edge);
  274. Nodes[from_id].center = Nodes[v].center;
  275. heap_data.ul = from_id;
  276. dglHeapInsertMin(&heap, dist + d, ' ', heap_data);
  277. }
  278. }
  279. dglEdgeset_T_Release(&et);
  280. }
  281. dglHeapFree(&heap, NULL);
  282. return 0;
  283. }