1
1
/*
2
- Network simplex algorithm, inspired by networkx library implementation (https://networkx.org/documentation/stable/_modules/networkx/algorithms/flow/networksimplex.html)
2
+ Network simplex algorithm, adapted from networkx library implementation (https://networkx.org/documentation/stable/_modules/networkx/algorithms/flow/networksimplex.html)
3
3
*/
4
4
use std:: collections:: HashMap ;
5
5
use std:: fmt:: Debug ;
@@ -78,7 +78,7 @@ impl<T: Eq + Hash + Debug> GraphBuilder<T> {
78
78
fn build ( & self ) -> Graph {
79
79
Graph {
80
80
nodes : self . nodes . clone ( ) ,
81
- edges : self . edges . clone ( )
81
+ edges : self . edges . clone ( ) ,
82
82
}
83
83
}
84
84
}
@@ -275,7 +275,7 @@ impl Solution<'_> {
275
275
}
276
276
}
277
277
278
- fn trace_subtree ( & self , u : usize ) -> SubtreeIterator {
278
+ fn trace_subtree ( & mut self , u : usize ) -> SubtreeIterator {
279
279
SubtreeIterator :: init ( u, & self . next_node_dft , & self . last_descendent_dft )
280
280
}
281
281
@@ -383,9 +383,14 @@ impl Solution<'_> {
383
383
} else {
384
384
self . potentials [ p] + self . graph . edges [ i] . cost - self . potentials [ q]
385
385
} ;
386
- let subtree: Vec < usize > = self . trace_subtree ( q) . collect ( ) ;
387
- for q in subtree {
388
- self . potentials [ q] += d;
386
+ let last = self . last_descendent_dft [ q] ;
387
+ let mut u = q;
388
+ loop {
389
+ self . potentials [ u] += d;
390
+ if u == last {
391
+ break ;
392
+ }
393
+ u = self . next_node_dft [ u] ;
389
394
}
390
395
}
391
396
@@ -402,11 +407,12 @@ impl Solution<'_> {
402
407
let mut m = 0 ;
403
408
while m < num_blocks {
404
409
let mut block_end = self . block_start + block_size;
405
- let edges: Vec < usize > = if block_end <= self . edge_count {
406
- ( self . block_start ..block_end) . collect ( )
410
+
411
+ let edges = if block_end <= self . edge_count {
412
+ Box :: new ( self . block_start ..block_end) as Box < dyn Iterator < Item =usize > >
407
413
} else {
408
414
block_end -= self . edge_count ;
409
- ( self . block_start ..self . edge_count ) . chain ( 0 ..block_end) . collect ( )
415
+ Box :: new ( ( self . block_start ..self . edge_count ) . chain ( 0 ..block_end) ) as Box < dyn Iterator < Item = usize > >
410
416
} ;
411
417
self . block_start = block_end;
412
418
@@ -439,23 +445,23 @@ impl Solution<'_> {
439
445
}
440
446
441
447
fn find_leaving_edge ( & self , nodes : & Vec < usize > , edges : & Vec < usize > ) -> ( usize , usize , usize ) {
442
- let nodes_rev: Vec < usize > = nodes. iter ( ) . copied ( ) . rev ( ) . collect ( ) ;
443
- let edges_rev: Vec < usize > = edges. iter ( ) . copied ( ) . rev ( ) . collect ( ) ;
448
+ let nodes_rev = nodes. iter ( ) . rev ( ) ;
449
+ let edges_rev = edges. iter ( ) . rev ( ) ;
444
450
445
- let ind: Vec < ( usize , usize ) > = edges_rev. iter ( ) . copied ( ) . zip ( nodes_rev. iter ( ) . copied ( ) ) . collect ( ) ;
451
+ let ind = edges_rev. zip ( nodes_rev) ;
446
452
let ( j, s) = argmin ( ind,
447
- |( t, u) | self . residual_capacity ( t, u) ) . unwrap ( ) ;
453
+ |( t, u) | self . residual_capacity ( * t, * u) ) . unwrap ( ) ;
448
454
449
- let t = if self . graph . edges [ j] . start == s {
450
- self . graph . edges [ j] . end
455
+ let t = if self . graph . edges [ * j] . start == * s {
456
+ self . graph . edges [ * j] . end
451
457
} else {
452
- self . graph . edges [ j] . start
458
+ self . graph . edges [ * j] . start
453
459
} ;
454
- ( j, s, t)
460
+ ( * j, * s, t)
455
461
}
456
462
}
457
463
458
- fn argmin < S : Copy > ( edges : Vec < S > , func : impl Fn ( S ) -> f64 ) -> Option < S > {
464
+ fn argmin < S : Copy > ( edges : impl Iterator < Item = S > , func : impl Fn ( S ) -> f64 ) -> Option < S > {
459
465
let mut argmin: Option < S > = None ;
460
466
let mut min = f64:: INFINITY ;
461
467
for i in edges {
@@ -468,7 +474,7 @@ fn argmin<S: Copy>(edges: Vec<S>, func: impl Fn(S) -> f64) -> Option<S> {
468
474
argmin
469
475
}
470
476
471
- pub fn network_simplex ( graph : Graph , eps : f64 ) -> Vec < f64 > {
477
+ pub fn network_simplex ( graph : & Graph , eps : f64 ) -> Vec < f64 > {
472
478
let mut graph = graph. clone ( ) ;
473
479
let mut solution = Solution :: new ( & mut graph, eps) ;
474
480
@@ -508,6 +514,7 @@ pub fn network_simplex(graph: Graph, eps: f64) -> Vec<f64> {
508
514
mod tests {
509
515
use ndarray_rand:: rand;
510
516
use ndarray_rand:: rand:: random;
517
+
511
518
use crate :: lp:: network_simplex:: { Graph , GraphBuilder , network_simplex} ;
512
519
513
520
#[ test]
@@ -519,7 +526,7 @@ mod tests {
519
526
graph. add_edge ( String :: from ( "a" ) , String :: from ( "c" ) , 10.0 , 6.0 ) ;
520
527
graph. add_edge ( String :: from ( "b" ) , String :: from ( "d" ) , 9.0 , 1.0 ) ;
521
528
graph. add_edge ( String :: from ( "c" ) , String :: from ( "d" ) , 5.0 , 2.0 ) ;
522
- let flow = super :: network_simplex ( graph. build ( ) , 10e-12 ) ;
529
+ let flow = super :: network_simplex ( & graph. build ( ) , 10e-12 ) ;
523
530
assert_eq ! ( vec![ 4.0 , 1.0 , 4.0 , 1.0 ] , flow) ;
524
531
}
525
532
@@ -539,7 +546,7 @@ mod tests {
539
546
graph. add_edge ( String :: from ( "a" ) , String :: from ( "t" ) , 4.0 , 2.0 ) ;
540
547
graph. add_edge ( String :: from ( "d" ) , String :: from ( "w" ) , 4.0 , 3.0 ) ;
541
548
graph. add_edge ( String :: from ( "t" ) , String :: from ( "w" ) , 1.0 , 4.0 ) ;
542
- let flow = super :: network_simplex ( graph. build ( ) , 10e-12 ) ;
549
+ let flow = super :: network_simplex ( & graph. build ( ) , 10e-12 ) ;
543
550
assert_eq ! ( vec![ 2.0 , 2.0 , 1.0 , 1.0 , 4.0 , 2.0 , 1.0 ] , flow) ;
544
551
}
545
552
}
0 commit comments