problemreductions/models/misc/
sequencing_within_intervals.rs1use crate::registry::{FieldInfo, ProblemSchemaEntry};
8use crate::traits::Problem;
9use serde::{Deserialize, Serialize};
10
11inventory::submit! {
12 ProblemSchemaEntry {
13 name: "SequencingWithinIntervals",
14 display_name: "Sequencing Within Intervals",
15 aliases: &[],
16 dimensions: &[],
17 module_path: module_path!(),
18 description: "Schedule tasks non-overlappingly within their time windows",
19 fields: &[
20 FieldInfo { name: "release_times", type_name: "Vec<u64>", description: "Release time r(t) for each task" },
21 FieldInfo { name: "deadlines", type_name: "Vec<u64>", description: "Deadline d(t) for each task" },
22 FieldInfo { name: "lengths", type_name: "Vec<u64>", description: "Processing length l(t) for each task" },
23 ],
24 }
25}
26
27#[derive(Debug, Clone, Serialize, Deserialize)]
57pub struct SequencingWithinIntervals {
58 release_times: Vec<u64>,
60 deadlines: Vec<u64>,
62 lengths: Vec<u64>,
64}
65
66impl SequencingWithinIntervals {
67 pub fn new(release_times: Vec<u64>, deadlines: Vec<u64>, lengths: Vec<u64>) -> Self {
73 assert_eq!(
74 release_times.len(),
75 deadlines.len(),
76 "release_times and deadlines must have the same length"
77 );
78 assert_eq!(
79 release_times.len(),
80 lengths.len(),
81 "release_times and lengths must have the same length"
82 );
83 for i in 0..release_times.len() {
84 let sum = release_times[i]
85 .checked_add(lengths[i])
86 .expect("overflow computing r(i) + l(i)");
87 assert!(
88 sum <= deadlines[i],
89 "Task {i}: r({}) + l({}) > d({}), time window is empty",
90 release_times[i],
91 lengths[i],
92 deadlines[i]
93 );
94 }
95 Self {
96 release_times,
97 deadlines,
98 lengths,
99 }
100 }
101
102 pub fn release_times(&self) -> &[u64] {
104 &self.release_times
105 }
106
107 pub fn deadlines(&self) -> &[u64] {
109 &self.deadlines
110 }
111
112 pub fn lengths(&self) -> &[u64] {
114 &self.lengths
115 }
116
117 pub fn num_tasks(&self) -> usize {
119 self.release_times.len()
120 }
121}
122
123impl Problem for SequencingWithinIntervals {
124 const NAME: &'static str = "SequencingWithinIntervals";
125 type Value = crate::types::Or;
126
127 fn variant() -> Vec<(&'static str, &'static str)> {
128 crate::variant_params![]
129 }
130
131 fn dims(&self) -> Vec<usize> {
132 (0..self.num_tasks())
133 .map(|i| (self.deadlines[i] - self.release_times[i] - self.lengths[i] + 1) as usize)
134 .collect()
135 }
136
137 fn evaluate(&self, config: &[usize]) -> crate::types::Or {
138 crate::types::Or({
139 let n = self.num_tasks();
140 if config.len() != n {
141 return crate::types::Or(false);
142 }
143
144 let mut starts = Vec::with_capacity(n);
146 for (i, &c) in config.iter().enumerate() {
147 let dim =
148 (self.deadlines[i] - self.release_times[i] - self.lengths[i] + 1) as usize;
149 if c >= dim {
150 return crate::types::Or(false);
151 }
152 let start = self.release_times[i] + c as u64;
155 starts.push(start);
156 }
157
158 for i in 0..n {
160 for j in (i + 1)..n {
161 let end_i = starts[i] + self.lengths[i];
162 let end_j = starts[j] + self.lengths[j];
163 if !(end_i <= starts[j] || end_j <= starts[i]) {
165 return crate::types::Or(false);
166 }
167 }
168 }
169
170 true
171 })
172 }
173}
174
175crate::declare_variants! {
176 default SequencingWithinIntervals => "2^num_tasks",
177}
178
179#[cfg(feature = "example-db")]
180pub(crate) fn canonical_model_example_specs() -> Vec<crate::example_db::specs::ModelExampleSpec> {
181 vec![crate::example_db::specs::ModelExampleSpec {
182 id: "sequencing_within_intervals",
183 instance: Box::new(SequencingWithinIntervals::new(
184 vec![0, 1, 3, 6, 0],
185 vec![5, 8, 9, 12, 12],
186 vec![2, 2, 2, 3, 2],
187 )),
188 optimal_config: vec![0, 1, 1, 0, 9],
189 optimal_value: serde_json::json!(true),
190 }]
191}
192
193#[cfg(test)]
194#[path = "../../unit_tests/models/misc/sequencing_within_intervals.rs"]
195mod tests;