microsoft/qdk

Public

mirrored fromhttps://github.com/microsoft/qdkAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
billti/num2-sim

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

source/resource_estimator/src/estimates/optimization/population.rs

224lines · modecode

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4#[cfg(test)]
5mod tests;
6
7use std::cmp::Ordering;
8
9pub trait Point<Rhs = Self> {
10 fn dominates(&self, other: &Rhs) -> bool;
11}
12
13pub struct Point2D<T> {
14 pub item: T,
15 pub value1: f64,
16 pub value2: u64,
17}
18
19impl<T> Point2D<T> {
20 pub fn new(item: T, value1: f64, value2: u64) -> Self {
21 Self {
22 item,
23 value1,
24 value2,
25 }
26 }
27}
28
29impl<T> Point for Point2D<T> {
30 fn dominates(&self, other: &Self) -> bool {
31 (self.value1 < other.value1 && self.value2 <= other.value2)
32 || (self.value1 <= other.value1 && self.value2 < other.value2)
33 }
34}
35
36impl<T> PartialEq for Point2D<T> {
37 fn eq(&self, other: &Self) -> bool {
38 self.value1 == other.value1 && self.value2 == other.value2
39 }
40}
41
42impl<T> Eq for Point2D<T> {}
43
44impl<T> PartialOrd for Point2D<T> {
45 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
46 Some(self.cmp(other))
47 }
48}
49
50impl<T> Ord for Point2D<T> {
51 fn cmp(&self, other: &Self) -> Ordering {
52 if self.value1 < other.value1 {
53 Ordering::Less
54 } else if self.value1 > other.value1 {
55 Ordering::Greater
56 } else if self.value2 < other.value2 {
57 Ordering::Less
58 } else if self.value2 > other.value2 {
59 Ordering::Greater
60 } else {
61 Ordering::Equal
62 }
63 }
64}
65
66pub struct Point4D<T> {
67 pub item: T,
68 pub value1: f64,
69 pub value2: u64,
70 pub value3: f64,
71 pub value4: u64,
72}
73
74impl<T> Point4D<T> {
75 pub fn new(item: T, value1: f64, value2: u64, value3: f64, value4: u64) -> Self {
76 Self {
77 item,
78 value1,
79 value2,
80 value3,
81 value4,
82 }
83 }
84}
85
86impl<T> Point for Point4D<T> {
87 // Allowing == comparison for better speed compared to abs() + cmp
88 #[allow(clippy::float_cmp)]
89 fn dominates(&self, other: &Self) -> bool {
90 self.value1 <= other.value1
91 && self.value2 <= other.value2
92 && self.value3 <= other.value3
93 && self.value4 <= other.value4
94 && !(self.value1 == other.value1
95 && self.value2 == other.value2
96 && self.value3 == other.value3
97 && self.value4 == other.value4)
98 }
99}
100
101impl<T> PartialEq for Point4D<T> {
102 fn eq(&self, other: &Self) -> bool {
103 self.value1 == other.value1
104 && self.value2 == other.value2
105 && self.value3 == other.value3
106 && self.value4 == other.value4
107 }
108}
109
110impl<T> Eq for Point4D<T> {}
111
112impl<T> PartialOrd for Point4D<T> {
113 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
114 Some(self.cmp(other))
115 }
116}
117
118impl<T> Ord for Point4D<T> {
119 fn cmp(&self, other: &Self) -> Ordering {
120 if self.value1 < other.value1 {
121 Ordering::Less
122 } else if self.value1 > other.value1 {
123 Ordering::Greater
124 } else if self.value2 < other.value2 {
125 Ordering::Less
126 } else if self.value2 > other.value2 {
127 Ordering::Greater
128 } else if self.value3 < other.value3 {
129 Ordering::Less
130 } else if self.value3 > other.value3 {
131 Ordering::Greater
132 } else if self.value4 < other.value4 {
133 Ordering::Less
134 } else if self.value4 > other.value4 {
135 Ordering::Greater
136 } else {
137 Ordering::Equal
138 }
139 }
140}
141
142pub struct Population<P>
143where
144 P: Point,
145 P: Ord,
146{
147 items: Vec<P>,
148 nonexecuted_attempts_to_filter_out_dominated: usize,
149}
150
151impl<P> Default for Population<P>
152where
153 P: Point,
154 P: Ord,
155{
156 fn default() -> Self {
157 Self::new()
158 }
159}
160
161impl<P> Population<P>
162where
163 P: Point,
164 P: Ord,
165{
166 const MAX_NONEXECUTED_ATTEMPTS_TO_FILTER_OUT_DOMINATED: usize = 1000;
167
168 #[must_use]
169 pub fn new() -> Self {
170 Self {
171 items: Vec::new(),
172 nonexecuted_attempts_to_filter_out_dominated: 0,
173 }
174 }
175
176 #[must_use]
177 pub fn items(&self) -> &[P] {
178 &self.items
179 }
180
181 pub(crate) fn push(&mut self, point: P) {
182 self.items.push(point);
183 }
184
185 pub(crate) fn sort_items(&mut self) {
186 self.items.sort_by(|a, b| b.cmp(a));
187 }
188
189 pub(crate) fn extract(self) -> Vec<P> {
190 self.items
191 }
192
193 pub(crate) fn attempt_filter_out_dominated(&mut self) {
194 if self.nonexecuted_attempts_to_filter_out_dominated
195 <= Self::MAX_NONEXECUTED_ATTEMPTS_TO_FILTER_OUT_DOMINATED
196 {
197 self.nonexecuted_attempts_to_filter_out_dominated += 1;
198 } else {
199 self.filter_out_dominated();
200 }
201 }
202
203 pub(crate) fn filter_out_dominated(&mut self) {
204 // NOTE: Use drain_filter in the future
205 let mut idx = 0;
206 let mut len = self.items.len();
207 while idx < len {
208 let p = &self.items[idx];
209 if self.dominates(p) {
210 // remove item by swapping with the end
211 self.items.swap(idx, len - 1);
212 len -= 1;
213 } else {
214 idx += 1;
215 }
216 }
217 self.nonexecuted_attempts_to_filter_out_dominated = 0;
218 self.items.truncate(len);
219 }
220
221 pub(crate) fn dominates(&self, other: &P) -> bool {
222 self.items.iter().any(|t| t.dominates(other))
223 }
224}
225