Contract `lv` by `super_id` (which maps each vertex to one of `next` supervertices) into the next coarser [`CoarseLevel`]. Supervertex weights are member sums; each net's pins are remapped, sorted, and deduplicated, and the net is dropped if it has fewer than two distinct coarse pins (it became internal to a supervertex). Net weights are preserved. `super_id` is stored as the level's `match_map` f
(lv: Level<'_>, super_id: &[u32], next: usize)
| 1130 | super_id[best_u] = next; // matched pair shares a supervertex |
| 1131 | } |
| 1132 | next += 1; |
| 1133 | } |
| 1134 | (super_id, next as usize) |
| 1135 | } |
| 1136 | |
| 1137 | /// Contract `lv` by `super_id` (which maps each vertex to one of `next` |
| 1138 | /// supervertices) into the next coarser [`CoarseLevel`]. Supervertex weights are |
| 1139 | /// member sums; each net's pins are remapped, sorted, and deduplicated, and the |
| 1140 | /// net is dropped if it has fewer than two distinct coarse pins (it became |
| 1141 | /// internal to a supervertex). Net weights are preserved. `super_id` is stored |
| 1142 | /// as the level's `match_map` for the uncoarsening projection. |
| 1143 | fn contract(lv: Level<'_>, super_id: &[u32], next: usize) -> CoarseLevel { |
| 1144 | let mut vw = vec![0u64; next]; |
| 1145 | let mut bw = vec![0u64; next]; |
| 1146 | for v in 0..lv.num_vertices() { |
| 1147 | let s = super_id[v] as usize; |
| 1148 | vw[s] = vw[s].saturating_add(lv.vw[v]); |
| 1149 | bw[s] = bw[s].saturating_add(lv.bw[v]); |
| 1150 | } |
| 1151 | let mut nets: Vec<(u64, Vec<u32>)> = Vec::with_capacity(lv.nets.len()); |
| 1152 | for (w, pins) in lv.nets { |
| 1153 | let mut cp: Vec<u32> = pins.iter().map(|&p| super_id[p as usize]).collect(); |
| 1154 | cp.sort_unstable(); |
| 1155 | cp.dedup(); |
| 1156 | if cp.len() >= 2 { |
| 1157 | nets.push((*w, cp)); |
| 1158 | } |
| 1159 | } |