~ruther/ctu-fee-eoa

ref: dfddcfde9cade6fd94ace5bca2f846f48c230e3c ctu-fee-eoa/env/src/terminating/mod.rs -rw-r--r-- 2.5 KiB
dfddcfde — Rutherther chore: split types and functions to separate module files a day ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
use crate::{binary_string::BinaryString, local_search::LocalSearchCandidate};

pub trait TerminatingCondition<T>
    where T: Clone
{
    fn should_terminate(
        self: &mut Self,
        candidate: &LocalSearchCandidate<T>,
        stats: &Vec<LocalSearchCandidate<T>>,
        cycle: usize
    ) -> bool;
}

pub struct EqualTerminatingCondition {
    target: BinaryString,
    remember_match: bool,
    matched: bool,
}

impl EqualTerminatingCondition {
    pub fn new(target: BinaryString) -> Self {
        Self {
            target,
            remember_match: false,
            matched: false,
        }
    }

    pub fn new_remembered(target: BinaryString) -> Self {
        Self {
            target,
            remember_match: true,
            matched: false,
        }
    }

    pub fn reset_match(self: &mut Self) {
        self.matched = false;
    }
}

impl<T: Clone> TerminatingCondition<T> for EqualTerminatingCondition {
    fn should_terminate(
        self: &mut Self,
        candidate: &LocalSearchCandidate<T>,
        _: &Vec<LocalSearchCandidate<T>>,
        _: usize
    ) -> bool {
        let matched = candidate.pos == self.target;

        if matched && self.remember_match {
            self.matched = true;
        }

        matched || self.matched
    }
}

pub struct NoBetterForCyclesTerminatingCondition {
    cycles: usize
}

impl NoBetterForCyclesTerminatingCondition {
    pub fn new(cycles: usize) -> Self {
        Self {
            cycles
        }
    }
}

pub struct AndTerminatingConditions<'a, T: Clone> {
    terminating_conditions: Vec<&'a mut dyn TerminatingCondition<T>>
}

impl<'a, T: Clone> AndTerminatingConditions<'a, T> {
    pub fn new(terminating_conditions: Vec<&'a mut dyn TerminatingCondition<T>>) -> Self {
        Self {
            terminating_conditions
        }
    }
}

impl<'a, T: Clone> TerminatingCondition<T> for AndTerminatingConditions<'a, T> {
    fn should_terminate(
        self: &mut Self,
        candidate: &LocalSearchCandidate<T>,
        stats: &Vec<LocalSearchCandidate<T>>,
        cycle: usize
    ) -> bool {
        return self.terminating_conditions.iter_mut()
            .all(
                |cond| cond.should_terminate(candidate, stats, cycle)
            )
    }
}

impl<T: Clone> TerminatingCondition<T> for NoBetterForCyclesTerminatingCondition {
    fn should_terminate (
        self: &mut Self,
        candidate: &LocalSearchCandidate<T>,
        _: &Vec<LocalSearchCandidate<T>>,
        cycle: usize
    ) -> bool {
        (cycle - candidate.cycle) > self.cycles
    }
}