Skip to content

Commit 45f4676

Browse files
committed
[Improver] Added soft_objective_threshold. An improvement on the soft_objective must be bigger than this threshold. Set it to 10.0
1 parent 40b094e commit 45f4676

File tree

6 files changed

+43
-23
lines changed

6 files changed

+43
-23
lines changed

src/main.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,12 @@ use sbb::run;
55
fn main() {
66
// run("test_instances/21-06-tage-1/");
77
// run("test_instances/21-06-tage-2/");
8-
// run("test_instances/21-06-tage-7/");
8+
run("test_instances/21-06-tage-7/");
99
// run("test_instances/21-09-tage-7/");
1010
// run("test_instances/21-09-tage-14/");
1111
// run("test_instances/21-09-tage-21/");
1212
// run("test_instances/21-09-tage-28/");
1313
// run("test_instances/21-10-tage-1/");
14-
run("test_instances/21-10-tage-2/");
14+
// run("test_instances/21-10-tage-2/");
1515
// run("test_instances/21-10-tage-7/");
1616
}

src/schedule.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,7 @@ impl Schedule {
257257
};
258258

259259
let mut node_sequence = remaining_path.consume();
260-
remaining_path = Path::new(node_sequence.split_off(end_pos+1), self.nw.clone());
260+
remaining_path = Path::new_trusted(node_sequence.split_off(end_pos+1), self.nw.clone());
261261
let sub_segment = Segment::new(sub_segment_start, sub_segment_end);
262262
let remove_result = new_tour_provider.remove(sub_segment);
263263

src/schedule/objective.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,21 @@ impl ObjectiveValue {
7171
}
7272
}
7373

74+
impl ObjectiveValue {
75+
pub fn cmp_with_threshold(&self, other: &Self, threshold: Cost) -> Ordering {
76+
self.overhead_time.cmp(&other.overhead_time)
77+
.then(self.number_of_dummy_units.cmp(&other.number_of_dummy_units))
78+
.then(self.dummy_overhead_time.cmp(&other.dummy_overhead_time))
79+
.then(self.maintenance_penalty.cmp(&other.maintenance_penalty))
80+
.then(
81+
match self.soft_objective_cost - other.soft_objective_cost {
82+
diff if diff > threshold => Ordering::Greater,
83+
diff if diff < -threshold => Ordering::Less,
84+
_ => Ordering::Equal
85+
})
86+
}
87+
}
88+
7489
impl Ord for ObjectiveValue {
7590
fn cmp(&self, other: &Self) -> Ordering {
7691
self.overhead_time.cmp(&other.overhead_time)

src/schedule/path.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,10 @@ impl Path {
3232
/// crates a new Path and asserts that it is a path in the network
3333
pub(crate) fn new(node_sequence: Vec<NodeId>, nw: Arc<Network>) -> Path {
3434
for (&a,&b) in node_sequence.iter().tuple_windows() {
35-
assert!(nw.can_reach(a,b),"Not a valid Path");
35+
assert!(nw.can_reach(a,b),"Not a valid Path: {} cannot reach {}.", a, b);
36+
// if !nw.can_reach(a,b) {
37+
// println!("Not a valid Path: {} cannot reach {}.", a, b);
38+
// }
3639
}
3740
Path{node_sequence, nw}
3841
}

src/solver/local_search.rs

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,6 @@ use local_improver::LocalImprover;
1818
// use local_improver::TakeFirstRecursion;
1919
// use local_improver::TakeFirstParallelRecursion;
2020
use local_improver::TakeAnyParallelRecursion;
21-
// use super::greedy_1::Greedy1;
22-
// use super::greedy_2::Greedy2;
23-
use super::greedy_3::Greedy3;
2421

2522

2623

@@ -66,11 +63,12 @@ impl Solver for LocalSearch {
6663

6764
let recursion_depth = 5;
6865
let recursion_width = 5;
66+
let soft_objective_threshold = 10.0;
6967

7068
// let limited_local_improver = Minimizer::new(swap_factory);
71-
// let limited_local_improver = TakeFirstRecursion::new(swap_factory,recursion_depth, Some(25));
72-
// let limited_local_improver = TakeFirstParallelRecursion::new(swap_factory,recursion_depth, Some(recursion_width));
73-
let limited_local_improver = TakeAnyParallelRecursion::new(swap_factory,recursion_depth, Some(recursion_width));
69+
// let limited_local_improver = TakeFirstRecursion::new(swap_factory,recursion_depth, Some(25), soft_objective_threshold);
70+
// let limited_local_improver = TakeFirstParallelRecursion::new(swap_factory,recursion_depth, Some(recursion_width), soft_objective_threshold);
71+
let limited_local_improver = TakeAnyParallelRecursion::new(swap_factory,recursion_depth, Some(recursion_width), soft_objective_threshold);
7472

7573
schedule = self.find_local_optimum(schedule, limited_local_improver);
7674
// self.find_local_optimum(schedule, limited_local_improver)
@@ -82,9 +80,9 @@ impl Solver for LocalSearch {
8280
let swap_factory = LimitedExchanges::new(Some(segment_limit), None, false, self.nw.clone());
8381

8482
// let unlimited_local_improver = Minimizer::new(swap_factory);
85-
// let unlimited_local_improver = TakeFirstRecursion::new(swap_factory,0,None);
86-
// let unlimited_local_improver = TakeFirstParallelRecursion::new(swap_factory,0,None);
87-
let unlimited_local_improver = TakeAnyParallelRecursion::new(swap_factory,0,Some(recursion_width));
83+
// let unlimited_local_improver = TakeFirstRecursion::new(swap_factory,0,None,soft_objective_threshold);
84+
// let unlimited_local_improver = TakeFirstParallelRecursion::new(swap_factory,0,None,soft_objective_threshold);
85+
let unlimited_local_improver = TakeAnyParallelRecursion::new(swap_factory,0,Some(recursion_width), soft_objective_threshold);
8886

8987
self.find_local_optimum(schedule, unlimited_local_improver)
9088

src/solver/local_search/local_improver.rs

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use crate::schedule::Schedule;
2+
use crate::base_types::Cost;
23

34
use super::swap_factory::SwapFactory;
45
use crate::schedule::objective::ObjectiveValue;
@@ -61,6 +62,7 @@ pub(crate) struct TakeFirstRecursion<F: SwapFactory> {
6162
swap_factory: F,
6263
recursion_depth: u8,
6364
recursion_width: Option<usize>, // number of schedule that are considered for recursion (the one with best value are taken)
65+
soft_objective_threshold: Cost,
6466
}
6567

6668

@@ -73,8 +75,8 @@ impl<F: SwapFactory> LocalImprover for TakeFirstRecursion<F> {
7375

7476
impl<F: SwapFactory> TakeFirstRecursion<F> {
7577

76-
pub(crate) fn new(swap_factory: F, recursion_depth: u8, recursion_width: Option<usize>) -> TakeFirstRecursion<F> {
77-
TakeFirstRecursion{swap_factory, recursion_depth, recursion_width}
78+
pub(crate) fn new(swap_factory: F, recursion_depth: u8, recursion_width: Option<usize>, soft_objective_threshold: Cost) -> TakeFirstRecursion<F> {
79+
TakeFirstRecursion{swap_factory, recursion_depth, recursion_width, soft_objective_threshold}
7880
}
7981

8082

@@ -98,7 +100,7 @@ impl<F: SwapFactory> TakeFirstRecursion<F> {
98100
schedules_for_recursion.truncate(width);
99101
}
100102
}
101-
new_sched.objective_value() < objective_to_beat
103+
new_sched.objective_value().cmp_with_threshold(&objective_to_beat, self.soft_objective_threshold).is_lt()
102104
});
103105

104106
if result.is_none() {
@@ -137,6 +139,7 @@ pub(crate) struct TakeFirstParallelRecursion<F: SwapFactory + Send + Sync> {
137139
swap_factory: F,
138140
recursion_depth: u8,
139141
recursion_width: Option<usize>, // number of schedule that are considered per schedule for the next recursion (the one with best objectivevalue are taken for each schedule, dublicates are removed)
142+
soft_objective_threshold: Cost, // improvement must be better than this threshold
140143
}
141144

142145

@@ -149,8 +152,8 @@ impl<F: SwapFactory + Send + Sync> LocalImprover for TakeFirstParallelRecursion<
149152

150153
impl<F: SwapFactory + Send + Sync> TakeFirstParallelRecursion<F> {
151154

152-
pub(crate) fn new(swap_factory: F, recursion_depth: u8, recursion_width: Option<usize>) -> TakeFirstParallelRecursion<F> {
153-
TakeFirstParallelRecursion{swap_factory, recursion_depth, recursion_width}
155+
pub(crate) fn new(swap_factory: F, recursion_depth: u8, recursion_width: Option<usize>, soft_objective_threshold: Cost) -> TakeFirstParallelRecursion<F> {
156+
TakeFirstParallelRecursion{swap_factory, recursion_depth, recursion_width, soft_objective_threshold}
154157
}
155158

156159

@@ -194,7 +197,7 @@ impl<F: SwapFactory + Send + Sync> TakeFirstParallelRecursion<F> {
194197
if let Ok(best_i) = found_receiver.try_recv() {
195198
counter_limit = best_i;
196199
}
197-
new_sched.objective_value() < objective_to_beat || *i > counter_limit
200+
new_sched.objective_value().cmp_with_threshold(&objective_to_beat, self.soft_objective_threshold).is_lt() || *i > counter_limit
198201
});
199202

200203
match result {
@@ -267,7 +270,7 @@ impl<F: SwapFactory + Send + Sync> TakeFirstParallelRecursion<F> {
267270

268271

269272
///////////////////////////////////////////////////////////
270-
/////////////////// TakeAnyParallelRecursion //////////////////////
273+
/////////////// TakeAnyParallelRecursion //////////////////
271274
///////////////////////////////////////////////////////////
272275

273276
/// This improver uses parallel computation at two steps. In the recursion when multiple schedules
@@ -283,6 +286,7 @@ pub(crate) struct TakeAnyParallelRecursion<F: SwapFactory + Send + Sync> {
283286
swap_factory: F,
284287
recursion_depth: u8,
285288
recursion_width: Option<usize>, // number of schedule that are considered per schedule for the next recursion (the one with best objectivevalue are taken for each schedule, dublicates are removed)
289+
soft_objective_threshold: Cost, // improvement must be better than this threshold
286290
}
287291

288292

@@ -295,8 +299,8 @@ impl<F: SwapFactory + Send + Sync> LocalImprover for TakeAnyParallelRecursion<F>
295299

296300
impl<F: SwapFactory + Send + Sync> TakeAnyParallelRecursion<F> {
297301

298-
pub(crate) fn new(swap_factory: F, recursion_depth: u8, recursion_width: Option<usize>) -> TakeAnyParallelRecursion<F> {
299-
TakeAnyParallelRecursion{swap_factory, recursion_depth, recursion_width}
302+
pub(crate) fn new(swap_factory: F, recursion_depth: u8, recursion_width: Option<usize>, soft_objective_threshold: Cost) -> TakeAnyParallelRecursion<F> {
303+
TakeAnyParallelRecursion{swap_factory, recursion_depth, recursion_width, soft_objective_threshold}
300304
}
301305

302306

@@ -344,7 +348,7 @@ impl<F: SwapFactory + Send + Sync> TakeAnyParallelRecursion<F> {
344348

345349
let found_receiver_mutex = found_receiver_mutex.lock().unwrap();
346350
let found = found_receiver_mutex.try_recv();
347-
new_sched.objective_value() < objective_to_beat || found.is_ok()
351+
new_sched.objective_value().cmp_with_threshold(&objective_to_beat, self.soft_objective_threshold).is_lt() || found.is_ok()
348352
});
349353

350354

0 commit comments

Comments
 (0)