rs_graph/mcf/
simplex.rs

1/*
2 * Copyright (c) 2021-2023 Frank Fischer <frank-fischer@shadow-soft.de>
3 *
4 * This program is free software: you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation, either version 3 of the
7 * License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12 * General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program.  If not, see  <http://www.gnu.org/licenses/>
16 */
17
18//! A primal network simplex implementation.
19
20use super::SolutionState;
21use crate::adjacencies::Adjacencies;
22use crate::collections::NodeVecMap;
23use crate::search::dfs;
24use crate::traits::{FiniteGraph, GraphType, IndexDigraph};
25use num_traits::{Bounded, FromPrimitive, NumAssign, NumCast, Signed, ToPrimitive, Zero};
26
27type ID = u32;
28
29pub enum Pricing {
30    RoundRobin,
31    Complete,
32    Block,
33    MultiplePartial,
34}
35
36/// A primal network simplex algorithm.
37pub struct NetworkSimplex<G, F> {
38    graph: G,
39
40    balances: Vec<F>,
41    potentials: Vec<F>,
42    subtrees: Vec<ID>,
43    parent_edges: Vec<ID>,
44    parent_nodes: Vec<ID>,
45
46    prev_preorder: Vec<ID>, // Previous node in preorder node list
47    next_preorder: Vec<ID>, // Next node in preorder node list
48    last_preorder: Vec<ID>, // Last successor in preorder node list that is a child node
49
50    sources: Vec<ID>,
51    sinks: Vec<ID>,
52    lower: Vec<F>,
53    upper: Vec<F>,
54    costs: Vec<F>,
55    caps: Vec<F>,
56    flows: Vec<F>,
57    state: Vec<i8>,
58
59    pub pricing: Pricing,
60    current_edge: ID,
61    block_size: usize,
62    /// The (flow) value to be considered zero. Defaults to `F::zero()`.
63    pub zero: F,
64
65    niter: usize,
66    solution_state: SolutionState,
67    need_new_basis: bool,
68
69    /// The artificial cost value.
70    ///
71    /// Should be larger than the value of any augmenting cycle. If
72    /// `None` (the default) the artificial cost is set to
73    /// `(max(max(cost), 0) + 1) * n`, which should be large enough.
74    pub artificial_cost: Option<F>,
75    /// The infinite flow value.
76    ///
77    /// Capacities greater than or equal to this are considered
78    /// unbounded and flows are considered infinite. The default is
79    /// `F::max_value()`. For floating-point types `F::infinity()` can
80    /// be used as well.
81    pub infinite: F,
82}
83
84impl<G, F> NetworkSimplex<G, F>
85where
86    G: IndexDigraph,
87    F: Bounded + NumCast + NumAssign + PartialOrd + Copy + FromPrimitive + Signed,
88{
89    pub fn new(g: G) -> Self {
90        let n = FiniteGraph::num_nodes(&g);
91        let m = FiniteGraph::num_edges(&g);
92        let mut spx = NetworkSimplex {
93            graph: g,
94            balances: vec![F::zero(); n],
95            potentials: vec![F::zero(); n + 1],
96            subtrees: vec![0; n + 1],
97            parent_edges: vec![0; n + 1],
98            parent_nodes: vec![0; n + 1],
99
100            prev_preorder: vec![0; n + 1],
101            next_preorder: vec![0; n + 1],
102            last_preorder: vec![0; n + 1],
103
104            sources: vec![0; m + n],
105            sinks: vec![0; m + n],
106            lower: vec![F::zero(); m + n],
107            upper: vec![F::zero(); m + n],
108            costs: vec![F::zero(); m + n],
109            caps: vec![F::zero(); m + n],
110            flows: vec![F::zero(); m + n],
111            state: vec![0; m + n],
112
113            pricing: Pricing::Block,
114            current_edge: 0,
115            block_size: 0,
116            zero: F::zero(),
117
118            niter: 0,
119            solution_state: SolutionState::Unknown,
120            need_new_basis: true,
121
122            artificial_cost: None,
123            infinite: F::max_value(),
124        };
125        spx.init();
126        spx
127    }
128
129    pub fn as_graph(&self) -> &G {
130        &self.graph
131    }
132
133    pub fn balance(&self, u: <G as GraphType>::Node<'_>) -> F {
134        self.balances[self.graph.node_id(u)]
135    }
136
137    pub fn set_balance(&mut self, u: <G as GraphType>::Node<'_>, balance: F) {
138        self.need_new_basis = true;
139        self.balances[self.graph.node_id(u)] = balance;
140    }
141
142    pub fn set_balances<'a, Bs>(&'a mut self, balance: Bs)
143    where
144        Bs: Fn(<G as GraphType>::Node<'a>) -> F,
145    {
146        for u in self.graph.nodes() {
147            self.balances[self.graph.node_id(u)] = (balance)(u);
148        }
149    }
150
151    pub fn lower(&self, e: <G as GraphType>::Edge<'_>) -> F {
152        self.lower[self.graph.edge_id(e)]
153    }
154
155    pub fn set_lower(&mut self, e: <G as GraphType>::Edge<'_>, lb: F) {
156        self.need_new_basis = true;
157        self.lower[self.graph.edge_id(e)] = lb;
158    }
159
160    pub fn set_lowers<'a, Ls>(&'a mut self, lower: Ls)
161    where
162        Ls: Fn(<G as GraphType>::Edge<'a>) -> F,
163    {
164        for e in self.graph.edges() {
165            self.lower[self.graph.edge_id(e)] = (lower)(e);
166        }
167    }
168
169    pub fn upper(&self, e: <G as GraphType>::Edge<'_>) -> F {
170        self.upper[self.graph.edge_id(e)]
171    }
172
173    pub fn set_upper(&mut self, e: <G as GraphType>::Edge<'_>, ub: F) {
174        self.need_new_basis = true;
175        self.upper[self.graph.edge_id(e)] = ub;
176    }
177
178    pub fn set_uppers<'a, Us>(&'a mut self, upper: Us)
179    where
180        Us: Fn(<G as GraphType>::Edge<'a>) -> F,
181    {
182        for e in self.graph.edges() {
183            self.upper[self.graph.edge_id(e)] = (upper)(e);
184        }
185    }
186
187    pub fn cost(&self, e: <G as GraphType>::Edge<'_>) -> F {
188        self.costs[self.graph.edge_id(e)]
189    }
190
191    pub fn set_cost(&mut self, e: <G as GraphType>::Edge<'_>, cost: F) {
192        self.costs[self.graph.edge_id(e)] = cost;
193    }
194
195    pub fn set_costs<'a, Cs>(&'a mut self, cost: Cs)
196    where
197        Cs: Fn(<G as GraphType>::Edge<'a>) -> F,
198    {
199        for e in self.graph.edges() {
200            self.costs[self.graph.edge_id(e)] = (cost)(e);
201        }
202    }
203
204    /// Return the value of the latest computed flow value.
205    pub fn value(&self) -> F {
206        let mut v = F::zero();
207        for e in FiniteGraph::edges(&self.graph) {
208            v += self.flow(e) * self.costs[self.graph.edge_id(e)];
209        }
210        v
211    }
212
213    /// The flow of an Edge.
214    pub fn flow(&self, a: <G as GraphType>::Edge<'_>) -> F {
215        let eid = self.graph.edge_id(a);
216        self.flows[eid] + self.lower[eid]
217    }
218
219    /// Solve the min-cost-flow problem.
220    pub fn solve(&mut self) -> SolutionState {
221        self.niter = 0;
222        self.solution_state = SolutionState::Unknown;
223
224        // check trivial cases
225        if FiniteGraph::num_nodes(&self.graph).is_zero() {
226            self.solution_state = SolutionState::Optimal;
227            return self.solution_state;
228        }
229
230        if FiniteGraph::num_edges(&self.graph).is_zero() {
231            // check if all balances are zero, that's the only way to be feasible
232            self.solution_state = if self.balances.iter().all(Zero::is_zero) {
233                SolutionState::Optimal
234            } else {
235                SolutionState::Infeasible
236            };
237            return self.solution_state;
238        }
239
240        self.initialize_pricing();
241
242        if self.need_new_basis && !self.prepare_initial_basis() {
243            self.solution_state = SolutionState::Infeasible;
244            return self.solution_state;
245        }
246
247        self.initialize_node_potentials();
248
249        // heuristic initial pivot
250        if !self.compute_initial_pivots() {
251            self.solution_state = SolutionState::Unbounded;
252            return self.solution_state;
253        }
254
255        loop {
256            self.niter += 1;
257            if let Some(eid) = self.find_entering_edge() {
258                if !self.augment_cycle(eid) {
259                    self.solution_state = SolutionState::Unbounded;
260                    return self.solution_state;
261                }
262            } else {
263                break;
264            }
265        }
266
267        self.solution_state = if self.check_feasibility() {
268            SolutionState::Optimal
269        } else {
270            SolutionState::Infeasible
271        };
272
273        self.solution_state
274    }
275
276    /// Return the solution state of the latest computation.
277    pub fn solution_state(&self) -> SolutionState {
278        if self.need_new_basis {
279            SolutionState::Unknown
280        } else {
281            self.solution_state
282        }
283    }
284
285    fn init(&mut self) {
286        let m = self.graph.num_edges();
287        // Initialize edges
288        for eid in 0..m {
289            self.sources[eid] = NumCast::from(self.graph.node_id(self.graph.src(self.graph.id2edge(eid)))).unwrap();
290            self.sinks[eid] = NumCast::from(self.graph.node_id(self.graph.snk(self.graph.id2edge(eid)))).unwrap();
291        }
292
293        // The artificial edges will be initialized when the initial
294        // basis is prepared.
295    }
296
297    pub fn num_iterations(&self) -> usize {
298        self.niter
299    }
300
301    fn initialize_pricing(&mut self) {
302        match self.pricing {
303            Pricing::RoundRobin => self.current_edge = 0,
304            Pricing::Complete => (),
305            Pricing::Block => {
306                self.current_edge = 0;
307                // The following code is analogous to my Pascal implementation.
308                // We could also use
309                self.block_size = ((self.graph.num_edges() as f64).sqrt() * 0.5)
310                    .round()
311                    .to_usize()
312                    .unwrap()
313                    .max(10);
314            }
315            Pricing::MultiplePartial => todo!(),
316        }
317    }
318
319    fn prepare_initial_basis(&mut self) -> bool {
320        let n = self.graph.num_nodes();
321        let m = self.graph.num_edges() * 2;
322        // The artificial node is always the root of the basis tree
323        let uid = self.graph.num_nodes();
324
325        // modified balances of each node
326        let mut balances = self.balances.clone();
327        balances.push(F::zero());
328
329        // compute the cost value for the artificial edges
330        let artificial_cost = self.artificial_cost.unwrap_or_else(|| {
331            let mut value = F::zero();
332            for &c in &self.costs[0..self.graph.num_edges()] {
333                if c > value {
334                    value = c;
335                }
336            }
337            F::from(n).unwrap() * (F::one() + value)
338        });
339
340        self.subtrees[uid] = n as ID + 1;
341        self.parent_edges[uid] = ID::max_value();
342        self.parent_nodes[uid] = ID::max_value();
343
344        self.prev_preorder[uid] = ID::max_value();
345        self.next_preorder[uid] = 0;
346        self.last_preorder[uid] = n as ID - 1;
347
348        // Initial flow on all non-artificial edges is at lower or upper bound depending on the cost
349        for e in self.graph.edges() {
350            let eid = self.graph.edge_id(e);
351            // We set the initial flow on edges with non-negative costs at the lower bound ...
352            let cap = self.upper[eid] - self.lower[eid];
353
354            // The current edge is always infeasible.
355            if cap < self.zero {
356                return false;
357            }
358
359            let flw: F;
360            if self.costs[eid] >= F::zero() {
361                self.state[eid] = 1;
362                flw = F::zero();
363            } else {
364                self.state[eid] = -1;
365                flw = cap;
366            }
367
368            self.flows[eid] = flw;
369            self.caps[eid] = cap;
370
371            // Update artificial balances
372            let flw = flw + self.lower[eid];
373            balances[self.graph.node_id(self.graph.src(e))] -= flw;
374            balances[self.graph.node_id(self.graph.snk(e))] += flw;
375        }
376
377        // The initial basis consists of the artificial edges only
378        #[allow(clippy::needless_range_loop)]
379        for vid in 0..n {
380            self.subtrees[vid] = 1;
381            // Set the initial flow on the artificial edges
382            let eid = m + vid * 2;
383            let fid; // the parent edge, oriented from the artificial node (the root) to v
384            let b; // the balance / initial flow on the artificial edge
385            if balances[vid] >= F::zero() {
386                fid = eid ^ 1;
387                b = balances[vid];
388                self.costs[eid / 2] = F::zero();
389                // this edge is oriented from v the artificial node
390                self.sources[eid / 2] = ID::from_usize(eid - m).unwrap();
391                self.sinks[eid / 2] = ID::from_usize(n).unwrap();
392            } else {
393                fid = eid;
394                b = -balances[vid];
395                self.costs[eid / 2] = artificial_cost;
396                // this edge is oriented from the artificial node to v
397                self.sources[eid / 2] = ID::from_usize(n).unwrap();
398                self.sinks[eid / 2] = ID::from_usize(eid - m).unwrap();
399            }
400
401            self.caps[eid / 2] = self.infinite;
402            self.flows[eid / 2] = b;
403            self.state[eid / 2] = 0;
404
405            self.parent_nodes[vid] = uid as ID;
406            self.parent_edges[vid] = fid as ID;
407            self.prev_preorder[vid] = if vid > 0 { vid as ID - 1 } else { n as ID };
408            self.next_preorder[vid] = if vid + 1 < n { vid as ID + 1 } else { ID::max_value() };
409            self.last_preorder[vid] = vid as ID; // all subtrees are empty
410        }
411
412        self.need_new_basis = false;
413
414        true
415    }
416
417    /// Heuristic initial pivots
418    ///
419    /// Returns `false` if unboundedness has been detected and `true` otherwise.
420    fn compute_initial_pivots(&mut self) -> bool {
421        let n = self.graph.num_nodes();
422        let mut supply_nodes = Vec::new();
423        let mut demand_nodes = Vec::new();
424        let mut total_supply = F::zero();
425        for uid in 0..n {
426            let b = self.balances[uid];
427            if b > F::zero() {
428                total_supply += b;
429                supply_nodes.push(uid);
430            } else if b < F::zero() {
431                demand_nodes.push(uid);
432            }
433        }
434
435        // No supply -> no flow
436        if total_supply.is_zero() {
437            return true;
438        }
439
440        let edges: Vec<usize> = if supply_nodes.len() == 1 && demand_nodes.len() == 1 {
441            // special case: exactly one source and one sink.
442            // do a DFS from sink to source
443            let s = self.graph.id2node(supply_nodes[0]);
444            let t = self.graph.id2node(demand_nodes[0]);
445            let mut edges = Vec::new();
446            for (_, e) in dfs::start_with_data(
447                self.graph
448                    .incoming()
449                    .filter(|&(e, _)| self.caps[self.graph.edge_id(e)] >= total_supply && self.graph.snk(e) != s),
450                t,
451                (NodeVecMap::new(&self.graph), Vec::new()),
452            ) {
453                edges.push(self.graph.edge_id(e));
454            }
455            edges
456        } else {
457            // Find the minimal cost incoming edge for each demand node
458            demand_nodes
459                .iter()
460                .filter_map(|&vid| {
461                    self.graph
462                        .inedges(self.graph.id2node(vid))
463                        .map(|(e, _)| self.graph.edge_id(e))
464                        .min_by(|&eid, &fid| self.costs[eid].partial_cmp(&self.costs[fid]).unwrap())
465                })
466                .collect()
467        };
468
469        // Perform heuristic initial pivots
470        for eid in edges {
471            if self.reduced_cost(eid) >= F::zero() {
472                continue;
473            }
474            let eid = self.oriented_edge(eid);
475            if !self.augment_cycle(eid) {
476                return false;
477            }
478        }
479
480        true
481    }
482
483    fn initialize_node_potentials(&mut self) {
484        let rootid = self.graph.num_nodes();
485        self.potentials[rootid] = F::zero();
486
487        let mut uid = self.next_preorder[rootid] as usize;
488        while uid != ID::max_value() as usize {
489            let eid = self.parent_edges[uid] as usize;
490            let vid = self.parent_nodes[uid] as usize;
491            self.potentials[uid] = self.potentials[vid] + oriented_flow(eid, self.costs[eid / 2]);
492            uid = self.next_preorder[uid] as usize;
493        }
494    }
495
496    fn update_node_potentials(&mut self, uentering: usize) {
497        let eid = self.parent_edges[uentering] as usize;
498        let vid = self.parent_nodes[uentering] as usize;
499        let sigma = self.potentials[vid] - self.potentials[uentering] + oriented_flow(eid, self.costs[eid / 2]);
500        let uend = self.next_preorder[self.last_preorder[uentering] as usize] as usize;
501        let mut uid = uentering;
502        while uid != uend {
503            self.potentials[uid] += sigma;
504            uid = self.next_preorder[uid] as usize;
505        }
506    }
507
508    fn augment_cycle(&mut self, e_in: ID) -> bool {
509        let e_in = e_in as usize;
510
511        // e = (u,v)
512        let (mut u_in, mut v_in) = if (e_in & 1) == 0 {
513            (self.sources[e_in / 2] as usize, self.sinks[e_in / 2] as usize)
514        } else {
515            (self.sinks[e_in / 2] as usize, self.sources[e_in / 2] as usize)
516        };
517
518        // Obtain free capacity on entering edge
519        let mut d = self.caps[e_in / 2];
520
521        // Compute maximal flow augmentation value and determine base-leaving-edge.
522        let mut v_out = None;
523        let mut e_out_fwd = true;
524        let mut uid = u_in;
525        let mut vid = v_in;
526        while uid != vid {
527            let fwd = self.subtrees[uid] < self.subtrees[vid];
528            // Edges on the side of u are in forward direction on the cycle
529            // Edges on the side of v are in backward direction on the cycle
530            let nodeid = if fwd { uid } else { vid };
531
532            let f = self.parent_edges[nodeid] as usize;
533
534            let flw = if ((f & 1) != 0) == fwd {
535                self.flows[f / 2]
536            } else if self.caps[f / 2] != self.infinite {
537                self.caps[f / 2] - self.flows[f / 2]
538            } else {
539                self.infinite
540            };
541
542            if flw < d {
543                d = flw;
544                v_out = Some(nodeid);
545                e_out_fwd = fwd;
546            }
547
548            if fwd {
549                uid = self.parent_nodes[uid] as usize
550            } else {
551                vid = self.parent_nodes[vid] as usize
552            };
553        }
554
555        if d >= self.infinite {
556            return false;
557        }
558
559        // vid is the common ancestor, i.e. the "top-most" node on the
560        // cycle in the basis tree.
561        let ancestorid = vid;
562
563        // Augment the flow one the basis entering edge.
564        self.flows[e_in / 2] = if self.state[e_in / 2] == 1 {
565            d
566        } else {
567            self.caps[e_in / 2] - d
568        };
569
570        // Check if e_in stays in non-basis
571        let v_out = if let Some(m) = v_out {
572            m
573        } else {
574            // switch bound
575            self.state[e_in / 2] = -self.state[e_in / 2];
576            // update flow on cycle
577            let mut uid = u_in;
578            let mut vid = v_in;
579            while uid != ancestorid {
580                let f = self.parent_edges[uid] as usize;
581                self.flows[f / 2] += oriented_flow(f, d);
582                uid = self.parent_nodes[uid] as usize;
583            }
584            while vid != ancestorid {
585                let f = self.parent_edges[vid] as usize;
586                self.flows[f / 2] -= oriented_flow(f, d);
587                vid = self.parent_nodes[vid] as usize;
588            }
589            // done
590            return true;
591        };
592        let u_out = self.parent_nodes[v_out] as usize;
593
594        // ************************************************************
595        // update the basis tree
596        // ************************************************************
597
598        self.state[e_in / 2] = 0; // e_in enters the basis
599
600        // The basis leaving edge e_in should be on the side of u, so possibly reverse e_in.
601        let e_in = if e_out_fwd {
602            let e_out = self.parent_edges[v_out] as usize;
603            self.state[e_out / 2] = if (e_out & 1) == 0 { -1 } else { 1 };
604            e_in
605        } else {
606            let e_out = self.parent_edges[v_out] as usize;
607            self.state[e_out / 2] = if (e_out & 1) == 0 { 1 } else { -1 };
608            // swap this edge
609            d = -d;
610            std::mem::swap(&mut u_in, &mut v_in);
611            e_in ^ 1
612        };
613
614        let mut uid = u_in;
615        let mut vid = v_in;
616        let orig_v_out_last = self.last_preorder[v_out];
617        let orig_v_out_prev = self.prev_preorder[v_out];
618        let orig_v_in_last = self.last_preorder[v_in];
619        let orig_ancestor_last = self.last_preorder[ancestorid];
620
621        // Special case: entering and leaving edges are parallel
622        if u_in == v_out && v_in == self.parent_nodes[v_out] as usize {
623            let fid = self.parent_edges[v_out] as usize;
624            self.flows[fid / 2] += oriented_flow(fid, d);
625            self.parent_edges[u_in] = e_in as ID ^ 1;
626            self.update_node_potentials(u_in);
627            return true;
628        }
629
630        // All subtree sizes from v up to the ancestor are increased.
631        // The flow on these edges is reduced.
632        let subtreediff = self.subtrees[v_out];
633        let mut childsubtree = 0;
634
635        // Traverse all nodes u from u_in .. v_out. At the beginning
636        // of each iteration
637        //
638        // - there are two successive nodes (w, u, v)
639        // - u_last is the original last[u]
640        // - u_prev is the original prev[u]
641        // - e_add = (u, v) the edge to be added
642        //
643        // In each iteration
644        //
645        // - the edge (u, v) is added to basis.
646        // - the edge (w, u) is removed from basis.
647        // - the flow on (w, u) is increased
648        // - the preorder list is updated
649        // - EXCEPTION: last[v] might not be correct after each iteration
650        let mut e_add = e_in;
651        let mut orig_u_last = self.last_preorder[u_in] as usize;
652        let mut orig_u_prev = self.prev_preorder[u_in] as usize;
653        while vid != v_out {
654            let wid = self.parent_nodes[uid] as usize;
655            let w_last = self.last_preorder[wid] as usize;
656            let w_prev = self.prev_preorder[wid] as usize;
657
658            // First remove the (original) subtree of u from its parent w.
659            // This need an update of last[w] if u was the "last" subtree of w
660            if w_last == orig_u_last {
661                self.last_preorder[wid] = orig_u_prev as ID;
662            }
663
664            // Remove u (and its subtree) from the preorder list ...
665            let u_last = self.last_preorder[uid] as usize;
666            let u_prev = self.prev_preorder[uid] as usize;
667            self.next_preorder[u_prev] = self.next_preorder[u_last];
668            if self.next_preorder[u_last] != ID::max_value() {
669                self.prev_preorder[self.next_preorder[u_last] as usize] = u_prev as ID;
670            }
671
672            // Next attach u below v (between v and self.next_preorder[v])
673            self.prev_preorder[uid] = vid as ID;
674            self.next_preorder[u_last] = self.next_preorder[vid];
675            if self.next_preorder[vid] != ID::max_value() {
676                self.prev_preorder[self.next_preorder[vid] as usize] = u_last as ID;
677            }
678            self.next_preorder[vid] = uid as ID;
679
680            let e_del = self.parent_edges[uid] as usize;
681            self.parent_edges[uid] = e_add as ID ^ 1; // the edge is reversed to (v -> u)
682            self.parent_nodes[uid] = vid as ID;
683
684            self.flows[e_del / 2] += oriented_flow(e_del, d);
685
686            // What is currently below u stays below u but is not added again
687            // Everything else is added
688            let usubtree = self.subtrees[uid];
689            self.subtrees[uid] = subtreediff - childsubtree;
690            childsubtree = usubtree;
691
692            // Go up one edge.
693            vid = uid;
694            uid = wid;
695            orig_u_last = w_last;
696            orig_u_prev = w_prev;
697            e_add = e_del;
698        }
699
700        // The last[v] information for nodes v_out .. u_in may be wrong, because
701        // we added more nodes to their subtrees. We fix this now.
702        {
703            // v_out itself is actually correct because nothing has
704            // been added below v_out, so we start with its (new)
705            // parent.
706            let mut vid = self.parent_nodes[v_out] as usize;
707            let mut last = self.last_preorder[v_out];
708            while vid != v_in {
709                // Only nodes that had nothing below them must be
710                // updated because now their subtree is not empty
711                // anymore.
712                if self.last_preorder[vid] as usize == vid {
713                    self.last_preorder[vid] = last;
714                } else {
715                    last = self.last_preorder[vid];
716                }
717                vid = self.parent_nodes[vid] as usize;
718            }
719        }
720
721        // Now update the nodes from u_out ... ancestor.
722        //
723        // These nodes may have lost a subtree. They must be updated
724        // if and only if their last node was last[v_out].
725        {
726            let mut uid = u_out;
727            while uid != ancestorid {
728                if self.last_preorder[uid] == orig_v_out_last {
729                    self.last_preorder[uid] = orig_v_out_prev;
730                }
731                // Update the flow and the subtree size.
732                let eid = self.parent_edges[uid] as usize;
733                self.flows[eid / 2] += oriented_flow(eid, d);
734                self.subtrees[uid] -= subtreediff;
735                uid = self.parent_nodes[uid] as usize;
736            }
737        }
738
739        // Now update the nodes from v_in ... ancestor.
740        //
741        // These nodes may have got new nodes in their subtree. They
742        // must be updated if and only if their last node was
743        // last[v_in] and last[v_in] has changed.
744        {
745            let u_in_last = self.last_preorder[u_in];
746            let bad_last = if v_in == orig_v_in_last as usize {
747                orig_v_in_last
748            } else {
749                ID::max_value() // no not change if last[v_in] has not changed
750            };
751            let mut vid = v_in;
752            while vid != ancestorid {
753                if self.last_preorder[vid] == bad_last {
754                    self.last_preorder[vid] = u_in_last;
755                }
756                let eid = self.parent_edges[vid] as usize;
757                self.flows[eid / 2] -= oriented_flow(eid, d);
758                self.subtrees[vid] += subtreediff;
759                vid = self.parent_nodes[vid] as usize;
760            }
761        }
762
763        // Finally it remains to update the nodes from ancestor
764        // upwards.
765
766        let (old, new) = if u_out == ancestorid && orig_ancestor_last == orig_v_out_last {
767            // This is the only case in which ancestor may have lost a
768            // subtree.
769            if orig_v_out_prev as usize == v_in {
770                self.last_preorder[ancestorid] = orig_ancestor_last;
771                (orig_v_out_last, self.last_preorder[u_in])
772            } else {
773                self.last_preorder[ancestorid] = orig_ancestor_last;
774                (orig_v_out_last, orig_v_out_prev)
775            }
776        } else if orig_ancestor_last == orig_v_out_last {
777            (orig_v_out_last, orig_v_out_prev)
778        } else if orig_ancestor_last == orig_v_in_last {
779            if u_out == ancestorid {
780                // Reset last[ancestor] because it has already been changed.
781                self.last_preorder[ancestorid] = orig_ancestor_last;
782            }
783            (orig_v_in_last, self.last_preorder[v_in])
784        } else {
785            (ID::max_value(), ID::max_value())
786        };
787
788        if old != ID::max_value() {
789            let mut uid = ancestorid;
790            while uid != ID::max_value() as usize && self.last_preorder[uid] == old {
791                self.last_preorder[uid] = new;
792                uid = self.parent_nodes[uid] as usize;
793            }
794        }
795
796        // Finally update the node potentials for the changed subtree
797        self.update_node_potentials(u_in);
798
799        true
800    }
801
802    fn check_feasibility(&mut self) -> bool {
803        self.flows[self.graph.num_edges()..].iter().all(|&x| x <= self.zero)
804    }
805
806    fn find_entering_edge(&mut self) -> Option<ID> {
807        match self.pricing {
808            Pricing::RoundRobin => self.round_robin_pricing(),
809            Pricing::Complete => self.complete_pricing(),
810            Pricing::Block => self.block_pricing(),
811            Pricing::MultiplePartial => self.multiple_partial_pricing(),
812        }
813    }
814
815    fn round_robin_pricing(&mut self) -> Option<ID> {
816        let mut eid = self.current_edge as usize;
817        loop {
818            if self.reduced_cost(eid) < F::zero() {
819                self.current_edge = eid as ID;
820                return Some(self.oriented_edge(eid));
821            }
822            eid = (eid + 1) % self.graph.num_edges();
823            if eid == self.current_edge as usize {
824                return None;
825            }
826        }
827    }
828
829    fn complete_pricing(&mut self) -> Option<ID> {
830        let mut min_cost = F::zero();
831        let mut min_edge = None;
832        for eid in 0..self.graph.num_edges() {
833            let c = self.reduced_cost(eid);
834            if c < min_cost {
835                min_cost = c;
836                min_edge = Some(eid);
837            }
838        }
839
840        min_edge.map(|eid| self.oriented_edge(eid))
841    }
842
843    fn block_pricing(&mut self) -> Option<ID> {
844        let mut end = self.graph.num_edges();
845        let mut eid = self.current_edge as usize % end;
846        let mut min_edge = None;
847        let mut min_cost = F::zero();
848        let mut m = (eid + self.block_size).min(end);
849        let mut cnt = self.block_size.min(end);
850
851        loop {
852            while eid < m {
853                let c = self.reduced_cost(eid);
854                if c < min_cost {
855                    min_cost = c;
856                    min_edge = Some(eid);
857                }
858                cnt -= 1;
859                eid += 1;
860            }
861
862            if cnt == 0 {
863                // reached regular end of the current block, start new block
864                m = (eid + self.block_size).min(end);
865                cnt = self.block_size.min(end);
866            } else if eid != self.current_edge as usize {
867                // reached non-regular end of the final block, start
868                // from the beginning
869                end = self.current_edge as usize;
870                eid = 0;
871                m = cnt.min(end);
872                continue;
873            }
874
875            if let Some(enteringid) = min_edge {
876                self.current_edge = eid as ID;
877                return Some(self.oriented_edge(enteringid));
878            }
879
880            if eid == self.current_edge as usize {
881                return None;
882            }
883        }
884    }
885
886    fn multiple_partial_pricing(&mut self) -> Option<ID> {
887        todo!()
888    }
889
890    fn reduced_cost(&self, eid: usize) -> F {
891        unsafe {
892            F::from(*self.state.get_unchecked(eid)).unwrap()
893                * (*self.costs.get_unchecked(eid)
894                    - *self.potentials.get_unchecked(*self.sinks.get_unchecked(eid) as usize)
895                    + *self.potentials.get_unchecked(*self.sources.get_unchecked(eid) as usize))
896        }
897    }
898
899    fn oriented_edge(&self, eid: usize) -> ID {
900        let eid = if self.state[eid] == 1 { eid * 2 } else { (eid * 2) | 1 };
901        eid as ID
902    }
903}
904
905fn oriented_flow<F>(eid: usize, d: F) -> F
906where
907    F: NumAssign + NumCast,
908{
909    (F::one() - F::from((eid & 1) * 2).unwrap()) * d
910}
911
912/// Solve a min-cost-flow problem with a network simplex algorithm.
913///
914/// The function returns the objective value and the optimal flow.
915pub fn network_simplex<G, F, Bs, Ls, Us, Cs>(
916    g: &G,
917    balances: Bs,
918    lower: Ls,
919    upper: Us,
920    costs: Cs,
921) -> Option<(F, Vec<(G::Edge<'_>, F)>)>
922where
923    G: IndexDigraph,
924    F: NumAssign + NumCast + FromPrimitive + Ord + Signed + Bounded + Copy,
925    Bs: Fn(G::Node<'_>) -> F,
926    Ls: Fn(G::Edge<'_>) -> F,
927    Us: Fn(G::Edge<'_>) -> F,
928    Cs: Fn(G::Edge<'_>) -> F,
929{
930    let mut spx = NetworkSimplex::new(g);
931    spx.set_balances(balances);
932    spx.set_lowers(lower);
933    spx.set_uppers(upper);
934    spx.set_costs(costs);
935    if spx.solve() == SolutionState::Optimal {
936        Some((spx.value(), g.edges().map(|e| (e, spx.flow(e))).collect()))
937    } else {
938        None
939    }
940}