struct NetworkSimplexSolver<F, C> {}Fields§
§n: usize§m: usize§edges: Vec<Edge<F, C>>§lowers: Vec<F>§dss: Vec<F>§bucket_size: usize§minor_limit: usize§potentials: Vec<C>§parents: Vec<Parent<F>>§depth: Vec<usize>§next: Vec<usize>§prev: Vec<usize>§candidates: Vec<usize>Implementations§
Source§impl<F, C> NetworkSimplexSolver<F, C>
impl<F, C> NetworkSimplexSolver<F, C>
Sourcefn connect(&mut self, a: usize, b: usize)
fn connect(&mut self, a: usize, b: usize)
Examples found in repository?
crates/competitive/src/graph/network_simplex.rs (line 245)
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.is_multiple_of(2) {
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 }Sourcefn build(ns: NetworkSimplex<F, C>) -> Self
fn build(ns: NetworkSimplex<F, C>) -> Self
Sourcefn solve(self) -> Option<NetworkSimplexSolution<F, C>>
fn solve(self) -> Option<NetworkSimplexSolution<F, C>>
Sourcefn minor(&mut self) -> bool
fn minor(&mut self) -> bool
Examples found in repository?
crates/competitive/src/graph/network_simplex.rs (line 258)
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 }Sourcefn get_lca(
&self,
u: usize,
v: usize,
flow: &mut F,
del_u_side: &mut bool,
del_u: &mut usize,
) -> usize
fn get_lca( &self, u: usize, v: usize, flow: &mut F, del_u_side: &mut bool, del_u: &mut usize, ) -> usize
Examples found in repository?
crates/competitive/src/graph/network_simplex.rs (line 383)
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.is_multiple_of(2) {
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 }Sourcefn push_flow(&mut self, eid: usize)
fn push_flow(&mut self, eid: usize)
Examples found in repository?
crates/competitive/src/graph/network_simplex.rs (line 289)
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 }Sourcefn generate_solution(self) -> Option<NetworkSimplexSolution<F, C>>
fn generate_solution(self) -> Option<NetworkSimplexSolution<F, C>>
Examples found in repository?
crates/competitive/src/graph/network_simplex.rs (line 297)
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 }Trait Implementations§
Auto Trait Implementations§
impl<F, C> Freeze for NetworkSimplexSolver<F, C>
impl<F, C> RefUnwindSafe for NetworkSimplexSolver<F, C>where
F: RefUnwindSafe,
C: RefUnwindSafe,
impl<F, C> Send for NetworkSimplexSolver<F, C>
impl<F, C> Sync for NetworkSimplexSolver<F, C>
impl<F, C> Unpin for NetworkSimplexSolver<F, C>
impl<F, C> UnwindSafe for NetworkSimplexSolver<F, C>where
F: UnwindSafe,
C: UnwindSafe,
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more