Bisect `sub` into two balanced parts minimizing cut weight. Returns a side (0/1) per local vertex. Multilevel V-cycle: coarsen `sub` into a hierarchy, decide the cut on the tiny coarsest graph (greedy graph-growing + FM to convergence), then uncoarsen — projecting the cut back down and boundary-refining each level. When `sub` is small or won't coarsen, `levels` is empty and we partition it direct
(sub: &SubHyper, epsilon: f64)
| 657 | ); |
| 658 | } |
| 659 | } |
| 660 | } |
| 661 | |
| 662 | /// Bisect `sub` into two balanced parts minimizing cut weight. Returns a side |
| 663 | /// (0/1) per local vertex. |
| 664 | /// |
| 665 | /// Multilevel V-cycle: coarsen `sub` into a hierarchy, decide the cut on the |
| 666 | /// tiny coarsest graph (greedy graph-growing + FM to convergence), then |
| 667 | /// uncoarsen — projecting the cut back down and boundary-refining each level. |
| 668 | /// When `sub` is small or won't coarsen, `levels` is empty and we partition it |
| 669 | /// directly, so the worst case is never worse than a flat bisection. |
| 670 | fn bisect(sub: &SubHyper, epsilon: f64) -> Vec<u8> { |
| 671 | let n = sub.num_vertices(); |
| 672 | if n == 0 { |
| 673 | return Vec::new(); |
| 674 | } |
| 675 | if n == 1 { |
| 676 | return vec![0]; |
| 677 | } |
| 678 | let total_bw: u64 = sub.bw.iter().sum(); |
| 679 | // Balance bounds for side weights (invariant across levels — coarsening sums |
| 680 | // balance weight, so the total is preserved at every level). |
no test coverage detected