solverforge_solver/heuristic/selector/k_opt/
iterators.rs1use crate::heuristic::r#move::CutPoint;
4
5pub struct CutCombinationIterator {
7 k: usize,
8 len: usize,
9 min_seg: usize,
10 entity_idx: usize,
11 positions: Vec<usize>,
13 done: bool,
15}
16
17impl CutCombinationIterator {
18 pub fn new(k: usize, len: usize, min_seg: usize, entity_idx: usize) -> Self {
19 let min_len = (k + 1) * min_seg;
21
22 if len < min_len {
23 return Self {
24 k,
25 len,
26 min_seg,
27 entity_idx,
28 positions: vec![],
29 done: true,
30 };
31 }
32
33 let mut positions = Vec::with_capacity(k);
36 for i in 0..k {
37 positions.push(min_seg * (i + 1));
38 }
39
40 Self {
41 k,
42 len,
43 min_seg,
44 entity_idx,
45 positions,
46 done: false,
47 }
48 }
49
50 fn advance(&mut self) -> bool {
51 if self.done || self.positions.is_empty() {
52 return false;
53 }
54
55 let k = self.k;
57 let len = self.len;
58 let min_seg = self.min_seg;
59
60 for i in (0..k).rev() {
61 let max_pos = len - min_seg * (k - i);
66
67 if self.positions[i] < max_pos {
68 self.positions[i] += 1;
69 for j in (i + 1)..k {
71 self.positions[j] = self.positions[j - 1] + min_seg;
72 }
73 return true;
74 }
75 }
76
77 self.done = true;
78 false
79 }
80}
81
82impl Iterator for CutCombinationIterator {
83 type Item = Vec<CutPoint>;
84
85 fn next(&mut self) -> Option<Self::Item> {
86 if self.done {
87 return None;
88 }
89
90 let cuts: Vec<CutPoint> = self
91 .positions
92 .iter()
93 .map(|&pos| CutPoint::new(self.entity_idx, pos))
94 .collect();
95
96 self.advance();
97
98 Some(cuts)
99 }
100}
101
102pub fn count_cut_combinations(k: usize, len: usize, min_seg: usize) -> usize {
104 let min_len = (k + 1) * min_seg;
107 if len < min_len {
108 return 0;
109 }
110
111 let free_slots = len - min_len + k;
112 binomial(free_slots, k)
113}
114
115pub fn binomial(n: usize, k: usize) -> usize {
117 if k > n {
118 return 0;
119 }
120 if k == 0 || k == n {
121 return 1;
122 }
123
124 let k = k.min(n - k); let mut result = 1;
126 for i in 0..k {
127 result = result * (n - i) / (i + 1);
128 }
129 result
130}