GRASS Programmer's Manual  6.5.svn(2014)-r66266
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
flow.c
Go to the documentation of this file.
1 
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <grass/gis.h>
20 #include <grass/Vect.h>
21 #include <grass/glocale.h>
22 #include <grass/dgl/graph.h>
23 #include <grass/neta.h>
24 
26 {
27  if (x >= 0)
28  return 1;
29  return -1;
30 }
31 
47 int NetA_flow(dglGraph_s * graph, struct ilist *source_list,
48  struct ilist *sink_list, int *flow)
49 {
50  int nnodes, nlines, i;
52  dglInt32_t *queue;
53  dglInt32_t **prev;
54  char *is_source, *is_sink;
55  int begin, end, total_flow;
56 
57  nnodes = dglGet_NodeCount(graph);
58  nlines = dglGet_EdgeCount(graph) / 2; /*each line corresponds to two edges. One in each direction */
59  queue = (dglInt32_t *) G_calloc(nnodes + 3, sizeof(dglInt32_t));
60  prev = (dglInt32_t **) G_calloc(nnodes + 3, sizeof(dglInt32_t *));
61  is_source = (char *)G_calloc(nnodes + 3, sizeof(char));
62  is_sink = (char *)G_calloc(nnodes + 3, sizeof(char));
63  if (!queue || !prev || !is_source || !is_sink) {
64  G_fatal_error(_("Out of memory"));
65  return -1;
66  }
67 
68  for (i = 0; i < source_list->n_values; i++)
69  is_source[source_list->value[i]] = 1;
70  for (i = 0; i < sink_list->n_values; i++)
71  is_sink[sink_list->value[i]] = 1;
72 
73  for (i = 0; i <= nlines; i++)
74  flow[i] = 0;
75 
76  total_flow = 0;
77  while (1) {
78  dglInt32_t node, edge_id, min_residue;
79  int found = -1;
80 
81  begin = end = 0;
82  for (i = 0; i < source_list->n_values; i++)
83  queue[end++] = source_list->value[i];
84 
85  for (i = 1; i <= nnodes; i++) {
86  prev[i] = NULL;
87  }
88  while (begin != end && found == -1) {
89  dglInt32_t vertex = queue[begin++];
90  dglInt32_t *edge, *node = dglGetNode(graph, vertex);
91 
92  dglEdgeset_T_Initialize(&et, graph,
93  dglNodeGet_OutEdgeset(graph, node));
94  for (edge = dglEdgeset_T_First(&et); edge;
95  edge = dglEdgeset_T_Next(&et)) {
96  dglInt32_t cap = dglEdgeGet_Cost(graph, edge);
97  dglInt32_t id = dglEdgeGet_Id(graph, edge);
98  dglInt32_t to =
99  dglNodeGet_Id(graph, dglEdgeGet_Tail(graph, edge));
100  if (!is_source[to] && prev[to] == NULL &&
101  cap > sign(id) * flow[abs(id)]) {
102  prev[to] = edge;
103  if (is_sink[to]) {
104  found = to;
105  break;
106  }
107  queue[end++] = to;
108  }
109  }
111  }
112  if (found == -1)
113  break; /*no augmenting path */
114  /*find minimum residual capacity along the augmenting path */
115  node = found;
116  edge_id = dglEdgeGet_Id(graph, prev[node]);
117  min_residue =
118  dglEdgeGet_Cost(graph,
119  prev[node]) - sign(edge_id) * flow[abs(edge_id)];
120  while (!is_source[node]) {
121  dglInt32_t residue;
122 
123  edge_id = dglEdgeGet_Id(graph, prev[node]);
124  residue =
125  dglEdgeGet_Cost(graph,
126  prev[node]) -
127  sign(edge_id) * flow[abs(edge_id)];
128  if (residue < min_residue)
129  min_residue = residue;
130  node = dglNodeGet_Id(graph, dglEdgeGet_Head(graph, prev[node]));
131  }
132  total_flow += min_residue;
133  /*update flow along the augmenting path */
134  node = found;
135  while (!is_source[node]) {
136  edge_id = dglEdgeGet_Id(graph, prev[node]);
137  flow[abs(edge_id)] += sign(edge_id) * min_residue;
138  node = dglNodeGet_Id(graph, dglEdgeGet_Head(graph, prev[node]));
139  }
140  }
141 
142  G_free(queue);
143  G_free(prev);
144  G_free(is_source);
145  G_free(is_sink);
146 
147  return total_flow;
148 }
149 
165 int NetA_min_cut(dglGraph_s * graph, struct ilist *source_list,
166  struct ilist *sink_list, int *flow, struct ilist *cut)
167 {
168  int nnodes, i;
170  dglInt32_t *queue;
171  char *visited;
172  int begin, end, total_flow;
173 
174  nnodes = dglGet_NodeCount(graph);
175  queue = (dglInt32_t *) G_calloc(nnodes + 3, sizeof(dglInt32_t));
176  visited = (char *)G_calloc(nnodes + 3, sizeof(char));
177  if (!queue || !visited) {
178  G_fatal_error(_("Out of memory"));
179  return -1;
180  }
181 
182  total_flow = begin = end = 0;
183 
184  for (i = 1; i <= nnodes; i++)
185  visited[i] = 0;
186 
187  for (i = 0; i < source_list->n_values; i++) {
188  queue[end++] = source_list->value[i];
189  visited[source_list->value[i]] = 1;
190  }
191 
192  /* find vertices reachable from source(s) using only non-saturated edges */
193  while (begin != end) {
194  dglInt32_t vertex = queue[begin++];
195  dglInt32_t *edge, *node = dglGetNode(graph, vertex);
196 
197  dglEdgeset_T_Initialize(&et, graph,
198  dglNodeGet_OutEdgeset(graph, node));
199  for (edge = dglEdgeset_T_First(&et); edge;
200  edge = dglEdgeset_T_Next(&et)) {
201  dglInt32_t cap = dglEdgeGet_Cost(graph, edge);
202  dglInt32_t id = dglEdgeGet_Id(graph, edge);
203  dglInt32_t to =
204  dglNodeGet_Id(graph, dglEdgeGet_Tail(graph, edge));
205  if (!visited[to] && cap > sign(id) * flow[abs(id)]) {
206  visited[to] = 1;
207  queue[end++] = to;
208  }
209  }
211  }
212  /*saturated edges from reachable vertices to non-reachable ones form a minimum cost */
213  Vect_reset_list(cut);
214  for (i = 1; i <= nnodes; i++) {
215  if (!visited[i])
216  continue;
217  dglInt32_t *node, *edgeset, *edge;
218 
219  node = dglGetNode(graph, i);
220  edgeset = dglNodeGet_OutEdgeset(graph, node);
221  dglEdgeset_T_Initialize(&et, graph, edgeset);
222  for (edge = dglEdgeset_T_First(&et); edge;
223  edge = dglEdgeset_T_Next(&et)) {
224  dglInt32_t to, edge_id;
225 
226  to = dglNodeGet_Id(graph, dglEdgeGet_Tail(graph, edge));
227  edge_id = abs(dglEdgeGet_Id(graph, edge));
228  if (!visited[to] && flow[edge_id] != 0) {
229  Vect_list_append(cut, edge_id);
230  total_flow += abs(flow[abs(edge_id)]);
231  }
232  }
234  }
235 
236  G_free(visited);
237  G_free(queue);
238  return total_flow;
239 }
240 
258 int NetA_split_vertices(dglGraph_s * in, dglGraph_s * out, int *node_costs)
259 {
260  dglInt32_t opaqueset[16] =
261  { 360000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
263  dglInt32_t nnodes, edge_cnt;
264  dglInt32_t *cur_node;
265 
266  nnodes = dglGet_NodeCount(in);
267  dglInitialize(out, (dglByte_t) 1, (dglInt32_t) 0, (dglInt32_t) 0,
268  opaqueset);
269  dglNode_T_Initialize(&nt, in);
270  edge_cnt = 0;
271  dglInt32_t max_node_cost = 0;
272 
273  for (cur_node = dglNode_T_First(&nt); cur_node;
274  cur_node = dglNode_T_Next(&nt)) {
275  dglInt32_t v = dglNodeGet_Id(in, cur_node);
276 
277  edge_cnt++;
278  dglInt32_t cost = 1;
279 
280  if (node_costs)
281  cost = node_costs[v];
282  if (cost > max_node_cost)
283  max_node_cost = cost;
284  dglAddEdge(out, 2 * v - 1, 2 * v, cost, edge_cnt);
285  dglAddEdge(out, 2 * v, 2 * v - 1, (dglInt32_t) 0, -edge_cnt);
286  }
287  dglNode_T_Release(&nt);
288  dglNode_T_Initialize(&nt, in);
289  for (cur_node = dglNode_T_First(&nt); cur_node;
290  cur_node = dglNode_T_Next(&nt)) {
292  dglInt32_t *edge;
293  dglInt32_t v = dglNodeGet_Id(in, cur_node);
294 
295  dglEdgeset_T_Initialize(&et, in, dglNodeGet_OutEdgeset(in, cur_node));
296  for (edge = dglEdgeset_T_First(&et); edge;
297  edge = dglEdgeset_T_Next(&et)) {
298  dglInt32_t to;
299 
300  to = dglNodeGet_Id(in, dglEdgeGet_Tail(in, edge));
301  edge_cnt++;
302  dglAddEdge(out, 2 * v, 2 * to - 1, max_node_cost + 1, edge_cnt);
303  dglAddEdge(out, 2 * to - 1, 2 * v, (dglInt32_t) 0, -edge_cnt);
304  }
306  }
307  dglNode_T_Release(&nt);
308  if (dglFlatten(out) < 0)
309  G_fatal_error(_("GngFlatten error"));
310  return edge_cnt;
311 }
dglInt32_t * dglEdgeGet_Tail(dglGraph_s *pGraph, dglInt32_t *pnEdge)
Definition: dglib/graph.c:494
dglInt32_t dglNodeGet_Id(dglGraph_s *pGraph, dglInt32_t *pnNode)
Definition: dglib/graph.c:213
void G_free(void *buf)
Free allocated memory.
Definition: gis/alloc.c:142
unsigned char dglByte_t
Definition: type.h:36
int dglAddEdge(dglGraph_s *pGraph, dglInt32_t nHead, dglInt32_t nTail, dglInt32_t nCost, dglInt32_t nEdge)
Definition: dglib/graph.c:610
int dglEdgeset_T_Initialize(dglEdgesetTraverser_s *pT, dglGraph_s *pGraph, dglInt32_t *pnEdgeset)
Definition: dglib/graph.c:1499
int NetA_flow(dglGraph_s *graph, struct ilist *source_list, struct ilist *sink_list, int *flow)
Get max flow from source to sink.
Definition: flow.c:47
int dglNode_T_Initialize(dglNodeTraverser_s *pT, dglGraph_s *pGraph)
Definition: dglib/graph.c:1356
void dglNode_T_Release(dglNodeTraverser_s *pT)
Definition: dglib/graph.c:1371
int NetA_split_vertices(dglGraph_s *in, dglGraph_s *out, int *node_costs)
Splits each vertex of in graph into two vertices.
Definition: flow.c:258
dglInt32_t dglEdgeGet_Id(dglGraph_s *pGraph, dglInt32_t *pnEdge)
Definition: dglib/graph.c:438
void dglEdgeset_T_Release(dglEdgesetTraverser_s *pT)
Definition: dglib/graph.c:1515
dglInt32_t * dglEdgeset_T_First(dglEdgesetTraverser_s *pT)
Definition: dglib/graph.c:1519
dglInt32_t * dglGetNode(dglGraph_s *pGraph, dglInt32_t nNodeId)
Definition: dglib/graph.c:155
int Vect_reset_list(struct ilist *list)
Reset ilist structure.
long dglInt32_t
Definition: type.h:37
int Vect_list_append(struct ilist *list, int val)
Append new item to the end of list if not yet present.
dglInt32_t * dglNode_T_First(dglNodeTraverser_s *pT)
Definition: dglib/graph.c:1387
dglInt32_t * dglEdgeGet_Head(dglGraph_s *pGraph, dglInt32_t *pnEdge)
Definition: dglib/graph.c:458
int dglGet_EdgeCount(dglGraph_s *pgraph)
Definition: dglib/graph.c:1261
dglInt32_t * dglNodeGet_OutEdgeset(dglGraph_s *pGraph, dglInt32_t *pnNode)
Definition: dglib/graph.c:170
return NULL
Definition: dbfopen.c:1394
int dglInitialize(dglGraph_s *pGraph, dglByte_t Version, dglInt32_t NodeAttrSize, dglInt32_t EdgeAttrSize, dglInt32_t *pOpaqueSet)
Definition: dglib/graph.c:53
dglInt32_t dglEdgeGet_Cost(dglGraph_s *pGraph, dglInt32_t *pnEdge)
Definition: dglib/graph.c:418
int NetA_min_cut(dglGraph_s *graph, struct ilist *source_list, struct ilist *sink_list, int *flow, struct ilist *cut)
Calculates minimum cut between source(s) and sink(s).
Definition: flow.c:165
for(cat=0;;cat++)
Definition: g3dcats.c:140
int dglGet_NodeCount(dglGraph_s *pgraph)
Definition: dglib/graph.c:1241
int G_fatal_error(const char *msg,...)
Print a fatal error message to stderr.
dglInt32_t * dglNode_T_Next(dglNodeTraverser_s *pT)
Definition: dglib/graph.c:1402
dglInt32_t * dglEdgeset_T_Next(dglEdgesetTraverser_s *pT)
Definition: dglib/graph.c:1534
dglInt32_t sign(dglInt32_t x)
Definition: flow.c:25
int dglFlatten(dglGraph_s *pGraph)
Definition: dglib/graph.c:139