Skip to content

Commit a8d15bc

Browse files
committed
Reduce memory usage
1 parent 2858f0e commit a8d15bc

File tree

2 files changed

+32
-25
lines changed

2 files changed

+32
-25
lines changed

src/lp/mod.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,15 @@ use ndarray::prelude::*;
44
use crate::lp::network_simplex::{Graph, network_simplex};
55

66
pub fn solve(u: &Array1<f64>, v: &Array1<f64>, cost_matrix: &Array2<f64>, eps: f64) -> Array2<f64> {
7-
let mut graph: Graph<usize> = Graph::new();
7+
let mut graph: Graph = Graph::new();
88
let m = u.len();
99
let n = v.len();
1010

1111
for i in 0..m {
12-
graph.add_node(i, u[i]);
12+
graph.add_node(u[i]);
1313
}
1414
for j in 0..n {
15-
graph.add_node(m + j, -v[j]);
15+
graph.add_node(-v[j]);
1616
}
1717

1818
for i in 0..m {
@@ -21,7 +21,7 @@ pub fn solve(u: &Array1<f64>, v: &Array1<f64>, cost_matrix: &Array2<f64>, eps: f
2121
}
2222
}
2323

24-
let flow = Array1::from_vec(network_simplex(graph, eps));
24+
let flow = Array1::from_vec(network_simplex(&graph, eps));
2525

2626
let mut result: Array2<f64> = Array::zeros((m, n));
2727

src/lp/network_simplex.rs

Lines changed: 28 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
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)
33
*/
44
use std::collections::HashMap;
55
use std::fmt::Debug;
@@ -78,7 +78,7 @@ impl<T: Eq + Hash + Debug> GraphBuilder<T> {
7878
fn build(&self) -> Graph {
7979
Graph {
8080
nodes: self.nodes.clone(),
81-
edges: self.edges.clone()
81+
edges: self.edges.clone(),
8282
}
8383
}
8484
}
@@ -275,7 +275,7 @@ impl Solution<'_> {
275275
}
276276
}
277277

278-
fn trace_subtree(&self, u: usize) -> SubtreeIterator {
278+
fn trace_subtree(&mut self, u: usize) -> SubtreeIterator {
279279
SubtreeIterator::init(u, &self.next_node_dft, &self.last_descendent_dft)
280280
}
281281

@@ -383,9 +383,14 @@ impl Solution<'_> {
383383
} else {
384384
self.potentials[p] + self.graph.edges[i].cost - self.potentials[q]
385385
};
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];
389394
}
390395
}
391396

@@ -402,11 +407,12 @@ impl Solution<'_> {
402407
let mut m = 0;
403408
while m < num_blocks {
404409
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>>
407413
} else {
408414
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>>
410416
};
411417
self.block_start = block_end;
412418

@@ -439,23 +445,23 @@ impl Solution<'_> {
439445
}
440446

441447
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();
444450

445-
let ind: Vec<(usize, usize)> = edges_rev.iter().copied().zip(nodes_rev.iter().copied()).collect();
451+
let ind = edges_rev.zip(nodes_rev);
446452
let (j, s) = argmin(ind,
447-
|(t, u)| self.residual_capacity(t, u)).unwrap();
453+
|(t, u)| self.residual_capacity(*t, *u)).unwrap();
448454

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
451457
} else {
452-
self.graph.edges[j].start
458+
self.graph.edges[*j].start
453459
};
454-
(j, s, t)
460+
(*j, *s, t)
455461
}
456462
}
457463

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> {
459465
let mut argmin: Option<S> = None;
460466
let mut min = f64::INFINITY;
461467
for i in edges {
@@ -468,7 +474,7 @@ fn argmin<S: Copy>(edges: Vec<S>, func: impl Fn(S) -> f64) -> Option<S> {
468474
argmin
469475
}
470476

471-
pub fn network_simplex(graph: Graph, eps: f64) -> Vec<f64> {
477+
pub fn network_simplex(graph: &Graph, eps: f64) -> Vec<f64> {
472478
let mut graph = graph.clone();
473479
let mut solution = Solution::new(&mut graph, eps);
474480

@@ -508,6 +514,7 @@ pub fn network_simplex(graph: Graph, eps: f64) -> Vec<f64> {
508514
mod tests {
509515
use ndarray_rand::rand;
510516
use ndarray_rand::rand::random;
517+
511518
use crate::lp::network_simplex::{Graph, GraphBuilder, network_simplex};
512519

513520
#[test]
@@ -519,7 +526,7 @@ mod tests {
519526
graph.add_edge(String::from("a"), String::from("c"), 10.0, 6.0);
520527
graph.add_edge(String::from("b"), String::from("d"), 9.0, 1.0);
521528
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);
523530
assert_eq!(vec![4.0, 1.0, 4.0, 1.0], flow);
524531
}
525532

@@ -539,7 +546,7 @@ mod tests {
539546
graph.add_edge(String::from("a"), String::from("t"), 4.0, 2.0);
540547
graph.add_edge(String::from("d"), String::from("w"), 4.0, 3.0);
541548
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);
543550
assert_eq!(vec![2.0, 2.0, 1.0, 1.0, 4.0, 2.0, 1.0], flow);
544551
}
545552
}

0 commit comments

Comments
 (0)