Finds an optimal path from the source to the nearest sink node, by definition * a node i is a sink if node_balance[i]<0. It uses a reduced cost: * reduced_cost[i,j] = cost[i,j] - potential[i] + potential[j] * * */
| 340 | * |
| 341 | * */ |
| 342 | static struct node dijkstra_nearest_sink(const tal_t *ctx, |
| 343 | const struct graph *graph, |
| 344 | const struct node source, |
| 345 | const s64 *node_balance, |
| 346 | const s64 *capacity, |
| 347 | const s64 cap_threshold, |
| 348 | const s64 *cost, |
| 349 | const s64 *potential, |
| 350 | struct arc *prev, |
| 351 | s64 *distance) |
| 352 | { |
| 353 | struct node target = {.idx = INVALID_INDEX}; |
| 354 | const tal_t *this_ctx = tal(ctx, tal_t); |
| 355 | |
| 356 | /* check preconditions */ |
| 357 | assert(graph); |
| 358 | assert(node_balance); |
| 359 | assert(capacity); |
| 360 | assert(cost); |
| 361 | assert(potential); |
| 362 | assert(prev); |
| 363 | assert(distance); |
| 364 | |
| 365 | const size_t max_num_arcs = graph_max_num_arcs(graph); |
| 366 | const size_t max_num_nodes = graph_max_num_nodes(graph); |
| 367 | |
| 368 | assert(source.idx < max_num_nodes); |
| 369 | assert(tal_count(node_balance) == max_num_nodes); |
| 370 | assert(tal_count(capacity) == max_num_arcs); |
| 371 | assert(tal_count(cost) == max_num_arcs); |
| 372 | assert(tal_count(potential) == max_num_nodes); |
| 373 | assert(tal_count(prev) == max_num_nodes); |
| 374 | assert(tal_count(distance) == max_num_nodes); |
| 375 | |
| 376 | for (size_t i = 0; i < max_num_arcs; i++) { |
| 377 | /* is this arc saturated? */ |
| 378 | if (capacity[i] < cap_threshold) |
| 379 | continue; |
| 380 | |
| 381 | struct arc arc = {.idx = i}; |
| 382 | struct node tail = arc_tail(graph, arc); |
| 383 | struct node head = arc_head(graph, arc); |
| 384 | s64 red_cost = |
| 385 | cost[i] - potential[tail.idx] + potential[head.idx]; |
| 386 | |
| 387 | /* reducted cost cannot be negative for non saturated arcs, |
| 388 | * otherwise Dijkstra does not work. */ |
| 389 | if (red_cost < 0) |
| 390 | goto finish; |
| 391 | } |
| 392 | |
| 393 | for (size_t i = 0; i < max_num_nodes; ++i) |
| 394 | prev[i].idx = INVALID_INDEX; |
| 395 | |
| 396 | /* Only in debug mode we keep track of visited nodes. */ |
| 397 | #ifdef ASKRENE_UNITTEST |
| 398 | bitmap *visited = |
| 399 | tal_arrz(this_ctx, bitmap, BITMAP_NWORDS(max_num_nodes)); |
no test coverage detected