~ruther/ctu-fee-eoa

ref: 79c83af97c81934e0a00b46126f6cea215dc77dc ctu-fee-eoa/env/src/terminating/mod.rs -rw-r--r-- 2.8 KiB
79c83af9 — Rutherther feat: add real fitness functions 2 months 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
107
108
109
use crate::{binary_string::BinaryString, local_search::LocalSearchCandidate};

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

pub struct EqualTerminatingCondition<T> {
    target: T,
    remember_match: bool,
    matched: bool,
}

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

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

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

impl<TInput, TResult> TerminatingCondition<TInput, TResult> for EqualTerminatingCondition<TInput>
where
    TInput: Clone + PartialEq,
    TResult: Clone
{
    fn should_terminate(
        self: &mut Self,
        candidate: &LocalSearchCandidate<TInput, TResult>,
        _: &Vec<LocalSearchCandidate<TInput, TResult>>,
        _: 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, TInput, TResult> {
    terminating_conditions: Vec<&'a mut dyn TerminatingCondition<TInput, TResult>>
}

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

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

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