1use super::{One, Zero};
2use std::{
3 mem::swap,
4 ops::{Add, AddAssign, Mul, Neg, Sub, SubAssign},
5};
6
7#[derive(Debug, Clone)]
8pub struct NetworkSimplex<F, C> {
9 n: usize,
10 edges: Vec<Edge<F, C>>,
11 lowers: Vec<F>,
12 dss: Vec<F>,
13 bucket_size: Option<usize>,
14 minor_limit: Option<usize>,
15}
16
17impl<F, C> NetworkSimplex<F, C>
18where
19 F: Copy + PartialOrd + Zero + Add<Output = F> + Sub<Output = F> + AddAssign + SubAssign,
20 C: Copy
21 + PartialOrd
22 + Zero
23 + One
24 + Add<Output = C>
25 + Sub<Output = C>
26 + AddAssign
27 + SubAssign
28 + Neg<Output = C>
29 + Mul<Output = C>
30 + From<F>,
31{
32 pub fn new(n: usize) -> Self {
33 Self {
34 n,
35 edges: vec![],
36 lowers: vec![],
37 dss: vec![F::zero(); n],
38 bucket_size: None,
39 minor_limit: None,
40 }
41 }
42
43 pub fn add_demand(&mut self, vid: usize, demand: F) {
45 assert!(vid < self.n);
46 assert!(demand >= F::zero());
47 self.dss[vid] -= demand;
48 }
49
50 pub fn add_supply(&mut self, vid: usize, supply: F) {
52 assert!(vid < self.n);
53 assert!(supply >= F::zero());
54 self.dss[vid] += supply;
55 }
56
57 pub fn add_demand_supply(&mut self, vid: usize, ds: F) {
59 assert!(vid < self.n);
60 self.dss[vid] += ds;
61 }
62
63 pub fn add_edge(&mut self, from: usize, to: usize, lower: F, upper: F, cost: C) {
65 assert!(from < self.n);
66 assert!(to < self.n);
67 assert!(lower <= upper);
68 self.edges.push(Edge {
69 to,
70 cap: upper - lower,
71 cost,
72 });
73 self.edges.push(Edge {
74 to: from,
75 cap: F::zero(),
76 cost: -cost,
77 });
78 self.lowers.push(lower);
79 self.dss[from] -= lower;
80 self.dss[to] += lower;
81 }
82
83 pub fn set_bucket_size(&mut self, size: usize) {
84 self.bucket_size = Some(size);
85 }
86
87 pub fn set_minor_limit(&mut self, limit: usize) {
88 self.minor_limit = Some(limit);
89 }
90
91 pub fn solve_minimize(self) -> Option<NetworkSimplexSolution<F, C>> {
92 NetworkSimplexSolver::build(self).solve()
93 }
94}
95
96#[derive(Debug, Clone)]
97struct Edge<F, C> {
98 to: usize,
99 cap: F,
100 cost: C,
101}
102
103#[derive(Debug, Clone)]
104struct Parent<F> {
105 par: usize,
106 eid: usize,
107 up: F,
108 down: F,
109}
110
111#[derive(Debug)]
112pub struct NetworkSimplexSolution<F, C> {
113 pub cost: C,
114 pub flows: Vec<F>,
115 pub potentials: Vec<C>,
116}
117
118#[derive(Debug)]
119struct NetworkSimplexSolver<F, C> {
120 n: usize,
121 m: usize,
122 edges: Vec<Edge<F, C>>, lowers: Vec<F>, dss: Vec<F>, bucket_size: usize,
127 minor_limit: usize,
128 potentials: Vec<C>, parents: Vec<Parent<F>>, depth: Vec<usize>, next: Vec<usize>, prev: Vec<usize>,
133 candidates: Vec<usize>,
134}
135
136impl<F, C> NetworkSimplexSolver<F, C>
137where
138 F: Copy + PartialOrd + Zero + Add<Output = F> + Sub<Output = F> + AddAssign + SubAssign,
139 C: Copy
140 + PartialOrd
141 + Zero
142 + One
143 + Add<Output = C>
144 + Sub<Output = C>
145 + AddAssign
146 + SubAssign
147 + Neg<Output = C>
148 + Mul<Output = C>
149 + From<F>,
150{
151 fn connect(&mut self, a: usize, b: usize) {
152 self.next[a] = b;
153 self.prev[b] = a;
154 }
155
156 fn build(ns: NetworkSimplex<F, C>) -> Self {
157 let NetworkSimplex {
158 n,
159 mut edges,
160 lowers,
161 dss,
162 bucket_size,
163 minor_limit,
164 } = ns;
165
166 let m = edges.len();
167 let bucket_size =
168 bucket_size.unwrap_or_else(|| (((m as f64).sqrt() * 0.2) as usize).max(10));
169 let minor_limit =
170 minor_limit.unwrap_or_else(|| (((bucket_size as f64) * 0.1) as usize).max(3));
171
172 let mut potentials = vec![C::zero(); n + 1];
173 let mut parents = vec![
174 Parent {
175 par: 0,
176 eid: 0,
177 up: F::zero(),
178 down: F::zero(),
179 };
180 n
181 ];
182 let inf_cost = edges.iter().step_by(2).fold(C::one(), |acc, edge| {
183 acc + if edge.cost >= C::zero() {
184 edge.cost
185 } else {
186 -edge.cost
187 }
188 });
189 edges.reserve(m + n * 2);
190 let super_node = n;
191 for v in 0..n {
192 let eid = edges.len();
193 if dss[v] >= F::zero() {
194 edges.push(Edge {
195 to: super_node,
196 cap: F::zero(),
197 cost: inf_cost,
198 });
199 edges.push(Edge {
200 to: v,
201 cap: dss[v],
202 cost: -inf_cost,
203 });
204 potentials[v] = -inf_cost;
205 } else {
206 edges.push(Edge {
207 to: super_node,
208 cap: F::zero() - dss[v],
209 cost: -inf_cost,
210 });
211 edges.push(Edge {
212 to: v,
213 cap: F::zero(),
214 cost: inf_cost,
215 });
216 potentials[v] = inf_cost;
217 }
218 parents[v] = Parent {
219 par: super_node,
220 eid,
221 up: edges[eid].cap,
222 down: edges[eid ^ 1].cap,
223 };
224 }
225
226 let mut depth = vec![1; n + 1];
227 depth[super_node] = 0;
228
229 let mut this = NetworkSimplexSolver {
230 n,
231 m,
232 edges,
233 lowers,
234 dss,
235 bucket_size,
236 minor_limit,
237 parents,
238 depth,
239 next: vec![0; (n + 1) * 2],
240 prev: vec![0; (n + 1) * 2],
241 candidates: Vec::with_capacity(bucket_size),
242 potentials,
243 };
244 for v in 0..=n {
245 this.connect(v * 2, v * 2 + 1);
246 }
247 for v in 0..n {
248 this.connect(v * 2 + 1, this.next[super_node * 2]);
249 this.connect(super_node * 2, v * 2);
250 }
251 this
252 }
253
254 fn solve(mut self) -> Option<NetworkSimplexSolution<F, C>> {
255 let mut eid = 0usize;
256 loop {
257 for _ in 0..self.minor_limit {
258 if !self.minor() {
259 break;
260 }
261 }
262 let mut best = C::zero();
263 let mut best_eid: Option<usize> = None;
264 self.candidates.clear();
265 for _ in 0..self.edges.len() {
266 if !self.edges[eid].cap.is_zero() {
267 let clen = self.edges[eid].cost + self.potentials[self.edges[eid ^ 1].to]
268 - self.potentials[self.edges[eid].to];
269 if clen < C::zero() {
270 if best_eid.is_none() || clen < best {
271 best = clen;
272 best_eid = Some(eid);
273 }
274 self.candidates.push(eid);
275 if self.candidates.len() == self.bucket_size {
276 break;
277 }
278 }
279 }
280 eid += 1;
281 if eid == self.edges.len() {
282 eid = 0;
283 }
284 }
285 if self.candidates.is_empty() {
286 break;
287 }
288 if let Some(be) = best_eid {
289 self.push_flow(be);
290 }
291 }
292 for i in 0..self.n {
293 let eid = self.parents[i].eid;
294 self.edges[eid].cap = self.parents[i].up;
295 self.edges[eid ^ 1].cap = self.parents[i].down;
296 }
297 self.generate_solution()
298 }
299
300 fn minor(&mut self) -> bool {
301 if self.candidates.is_empty() {
302 return false;
303 }
304 let mut best = C::zero();
305 let mut best_eid: Option<usize> = None;
306 let mut i = 0usize;
307 while i < self.candidates.len() {
308 let eid = self.candidates[i];
309 if self.edges[eid].cap.is_zero() {
310 self.candidates.swap_remove(i);
311 continue;
312 }
313 let clen = self.edges[eid].cost + self.potentials[self.edges[eid ^ 1].to]
314 - self.potentials[self.edges[eid].to];
315 if clen >= C::zero() {
316 self.candidates.swap_remove(i);
317 continue;
318 }
319 if best_eid.is_none() || clen < best {
320 best = clen;
321 best_eid = Some(eid);
322 }
323 i += 1;
324 }
325 if let Some(best_eid) = best_eid {
326 self.push_flow(best_eid);
327 true
328 } else {
329 false
330 }
331 }
332
333 fn get_lca(
334 &self,
335 mut u: usize,
336 mut v: usize,
337 flow: &mut F,
338 del_u_side: &mut bool,
339 del_u: &mut usize,
340 ) -> usize {
341 if self.depth[u] >= self.depth[v] {
342 for _ in 0..self.depth[u] - self.depth[v] {
343 if self.parents[u].down < *flow {
344 *flow = self.parents[u].down;
345 *del_u = u;
346 *del_u_side = true;
347 }
348 u = self.parents[u].par;
349 }
350 } else {
351 for _ in 0..self.depth[v] - self.depth[u] {
352 if self.parents[v].up <= *flow {
353 *flow = self.parents[v].up;
354 *del_u = v;
355 *del_u_side = false;
356 }
357 v = self.parents[v].par;
358 }
359 }
360 while u != v {
361 if self.parents[u].down < *flow {
362 *flow = self.parents[u].down;
363 *del_u = u;
364 *del_u_side = true;
365 }
366 u = self.parents[u].par;
367 if self.parents[v].up <= *flow {
368 *flow = self.parents[v].up;
369 *del_u = v;
370 *del_u_side = false;
371 }
372 v = self.parents[v].par;
373 }
374 u
375 }
376
377 fn push_flow(&mut self, eid: usize) {
378 let u0 = self.edges[eid ^ 1].to;
379 let v0 = self.edges[eid].to;
380 let mut del_u = v0;
381 let mut flow = self.edges[eid].cap;
382 let mut del_u_side = true;
383 let lca = self.get_lca(u0, v0, &mut flow, &mut del_u_side, &mut del_u);
384 if !flow.is_zero() {
385 let mut u = u0;
386 let mut v = v0;
387 while u != lca {
388 self.parents[u].up += flow;
389 self.parents[u].down -= flow;
390 u = self.parents[u].par;
391 }
392 while v != lca {
393 self.parents[v].up -= flow;
394 self.parents[v].down += flow;
395 v = self.parents[v].par;
396 }
397 }
398 let mut u = u0;
399 let mut par = v0;
400 let mut p_caps = (self.edges[eid].cap - flow, self.edges[eid ^ 1].cap + flow);
401 let mut p_diff = -(self.edges[eid].cost + self.potentials[u0] - self.potentials[v0]);
402 if !del_u_side {
403 swap(&mut u, &mut par);
404 swap(&mut p_caps.0, &mut p_caps.1);
405 p_diff = -p_diff;
406 }
407 let mut par_eid = eid ^ if del_u_side { 0 } else { 1 };
408 while par != del_u {
409 let mut d = self.depth[par];
410 let mut idx = u * 2;
411 while idx != u * 2 + 1 {
412 if idx % 2 == 0 {
413 d += 1;
414 self.potentials[idx / 2] += p_diff;
415 self.depth[idx / 2] = d;
416 } else {
417 d -= 1;
418 }
419 idx = self.next[idx];
420 }
421 self.connect(self.prev[u * 2], self.next[u * 2 + 1]);
422 self.connect(u * 2 + 1, self.next[par * 2]);
423 self.connect(par * 2, u * 2);
424 swap(&mut self.parents[u].eid, &mut par_eid);
425 par_eid ^= 1;
426 swap(&mut self.parents[u].up, &mut p_caps.0);
427 swap(&mut self.parents[u].down, &mut p_caps.1);
428 swap(&mut p_caps.0, &mut p_caps.1);
429 let next_u = self.parents[u].par;
430 self.parents[u].par = par;
431 par = u;
432 u = next_u;
433 }
434 self.edges[par_eid].cap = p_caps.0;
435 self.edges[par_eid ^ 1].cap = p_caps.1;
436 }
437
438 fn generate_solution(mut self) -> Option<NetworkSimplexSolution<F, C>> {
439 for v in 0..self.n {
440 if self.dss[v] >= F::zero() {
441 if !self.edges[self.m + v * 2 + 1].cap.is_zero() {
442 return None;
443 }
444 } else if !self.edges[self.m + v * 2].cap.is_zero() {
445 return None;
446 }
447 }
448 let mut cost = C::zero();
449 let mut flows = Vec::with_capacity(self.m / 2);
450 for eid in (0..self.m).step_by(2) {
451 let f = self.lowers[eid / 2] + self.edges[eid ^ 1].cap;
452 flows.push(f);
453 cost += C::from(f) * self.edges[eid].cost;
454 }
455 self.potentials.pop();
456 Some(NetworkSimplexSolution {
457 cost,
458 flows,
459 potentials: self.potentials,
460 })
461 }
462}
463
464#[cfg(test)]
465mod tests {
466 use super::*;
467
468 #[test]
469 fn test_feasible_b_flow() {
470 let mut ns = NetworkSimplex::<i32, i32>::new(3);
471 ns.add_supply(0, 5);
472 ns.add_demand(1, 5);
473 ns.add_edge(0, 2, 0, 10, -1);
474 ns.add_edge(2, 1, 0, 10, -1);
475 ns.add_edge(0, 1, 0, 10, 10);
476 let sol = ns.solve_minimize();
477 assert!(sol.is_some(), "should be feasible");
478 let sol = sol.unwrap();
479 assert_eq!(sol.cost, -10);
480 assert_eq!(sol.flows, vec![5, 5, 0]);
481 }
482
483 #[test]
484 fn test_infeasible_b_flow() {
485 let mut ns = NetworkSimplex::<i32, i32>::new(2);
486 ns.add_demand(0, 5);
487 ns.add_supply(1, 5);
488 ns.add_edge(0, 1, 0, 3, 2);
489 let sol = ns.solve_minimize();
490 assert!(sol.is_none(), "should be infeasible");
491 }
492}