problemreductions/rules/
multiprocessorscheduling_ilp.rs1use crate::models::algebraic::{LinearConstraint, ObjectiveSense, ILP};
10use crate::models::misc::MultiprocessorScheduling;
11use crate::reduction;
12use crate::rules::traits::{ReduceTo, ReductionResult};
13
14#[derive(Debug, Clone)]
21pub struct ReductionMSToILP {
22 target: ILP<bool>,
23 num_tasks: usize,
24 num_processors: usize,
25}
26
27impl ReductionResult for ReductionMSToILP {
28 type Source = MultiprocessorScheduling;
29 type Target = ILP<bool>;
30
31 fn target_problem(&self) -> &ILP<bool> {
32 &self.target
33 }
34
35 fn extract_solution(&self, target_solution: &[usize]) -> Vec<usize> {
37 let num_processors = self.num_processors;
38 (0..self.num_tasks)
39 .map(|j| {
40 (0..num_processors)
41 .find(|&p| target_solution[j * num_processors + p] == 1)
42 .unwrap_or(0)
43 })
44 .collect()
45 }
46}
47
48#[reduction(
49 overhead = {
50 num_vars = "num_tasks * num_processors",
51 num_constraints = "num_tasks + num_processors",
52 }
53)]
54impl ReduceTo<ILP<bool>> for MultiprocessorScheduling {
55 type Result = ReductionMSToILP;
56
57 fn reduce_to(&self) -> Self::Result {
58 let num_tasks = self.num_tasks();
59 let num_processors = self.num_processors();
60 let num_vars = num_tasks * num_processors;
61
62 let mut constraints = Vec::with_capacity(num_tasks + num_processors);
63
64 for j in 0..num_tasks {
66 let terms: Vec<(usize, f64)> = (0..num_processors)
67 .map(|p| (j * num_processors + p, 1.0))
68 .collect();
69 constraints.push(LinearConstraint::eq(terms, 1.0));
70 }
71
72 let deadline = self.deadline() as f64;
74 for p in 0..num_processors {
75 let terms: Vec<(usize, f64)> = (0..num_tasks)
76 .map(|j| (j * num_processors + p, self.lengths()[j] as f64))
77 .collect();
78 constraints.push(LinearConstraint::le(terms, deadline));
79 }
80
81 let target = ILP::new(num_vars, constraints, vec![], ObjectiveSense::Minimize);
82
83 ReductionMSToILP {
84 target,
85 num_tasks,
86 num_processors,
87 }
88 }
89}
90
91#[cfg(feature = "example-db")]
92pub(crate) fn canonical_rule_example_specs() -> Vec<crate::example_db::specs::RuleExampleSpec> {
93 vec![crate::example_db::specs::RuleExampleSpec {
94 id: "multiprocessorscheduling_to_ilp",
95 build: || {
96 let source = MultiprocessorScheduling::new(vec![4, 5, 3], 2, 7);
102 crate::example_db::specs::rule_example_via_ilp::<_, bool>(source)
103 },
104 }]
105}
106
107#[cfg(test)]
108#[path = "../unit_tests/rules/multiprocessorscheduling_ilp.rs"]
109mod tests;