Skip to main content

chai/operators/
default.rs

1use super::变异;
2use crate::contexts::default::{
3    默认上下文, 默认决策, 默认决策变化, 默认决策空间, 默认安排
4};
5use crate::optimizers::决策;
6use crate::错误;
7use crate::{元素图, 棱镜};
8use rand::seq::{IndexedRandom, IteratorRandom};
9use rand::{random_range, rng};
10use serde::{Deserialize, Serialize};
11use serde_with::skip_serializing_none;
12use std::collections::VecDeque;
13use tracing::debug;
14
15pub struct 默认操作 {
16    决策空间: 默认决策空间,
17    元素图: 元素图,
18    棱镜: 棱镜,
19}
20
21#[skip_serializing_none]
22#[derive(Debug, Copy, Clone, Serialize, Deserialize)]
23pub struct 变异配置 {
24    pub random_move: f64,
25    pub random_swap: f64,
26    pub random_full_key_swap: f64,
27}
28
29pub const DEFAULT_MUTATE: 变异配置 = 变异配置 {
30    random_move: 0.9,
31    random_swap: 0.09,
32    random_full_key_swap: 0.01,
33};
34
35impl 变异 for 默认操作 {
36    type 决策 = 默认决策;
37    fn 变异(&mut self, 决策: &mut Self::决策) -> <默认决策 as 决策>::变化 {
38        let mut 变化 = self.随机移动元素(决策);
39        self.传播(&mut 变化, 决策);
40        变化
41    }
42}
43
44// 默认的问题实现,使用配置文件中的约束来定义各种算子
45impl 默认操作 {
46    pub fn 新建(上下文: &默认上下文) -> Result<Self, 错误> {
47        Ok(Self {
48            决策空间: 上下文.决策空间.clone(),
49            元素图: 上下文.元素图.clone(),
50            棱镜: 上下文.棱镜.clone(),
51        })
52    }
53
54    fn 传播(&self, 变化: &mut <默认决策 as 决策>::变化, 决策: &mut 默认决策) {
55        // 初始化队列
56        let mut 队列 = VecDeque::new();
57        for 元素 in 变化
58            .增加元素
59            .iter()
60            .chain(变化.减少元素.iter())
61            .chain(变化.移动元素.iter())
62        {
63            for 下游元素 in self.元素图.get(元素).unwrap_or(&vec![]) {
64                if !队列.contains(下游元素) {
65                    队列.push_back(下游元素.clone());
66                }
67            }
68        }
69        // 传播直到队列为空
70        let mut iters = 0;
71        while !队列.is_empty() {
72            iters += 1;
73            if iters > 100 {
74                panic!("传播超过 100 次仍未结束,可能出现死循环");
75            }
76            let 元素 = 队列.pop_front().unwrap();
77            let 当前安排 = 决策.元素[元素];
78            let mut 合法 = false;
79            let mut 新安排列表 = vec![];
80            for 条件安排 in &self.决策空间.元素[元素] {
81                if 决策.允许(条件安排) {
82                    if 条件安排.安排 == 当前安排 {
83                        合法 = true;
84                        break;
85                    }
86                    新安排列表.push(条件安排.安排.clone());
87                }
88            }
89            if !合法 {
90                if 新安排列表.is_empty() {
91                    panic!("没有合法的安排,传播失败");
92                } else {
93                    let 新安排 = *新安排列表.choose(&mut rng()).unwrap();
94                    if let 默认安排::未选取 = 当前安排 {
95                        变化.增加元素.push(元素);
96                    } else if let 默认安排::未选取 = 新安排 {
97                        变化.减少元素.push(元素);
98                    } else {
99                        变化.移动元素.push(元素);
100                    }
101                    决策.元素[元素] = 新安排;
102                }
103            }
104            for 下游元素 in self.元素图.get(&元素).unwrap_or(&vec![]) {
105                if !队列.contains(下游元素) {
106                    队列.push_back(*下游元素);
107                }
108            }
109        }
110    }
111
112    pub fn 随机移动元素(&self, 决策: &mut 默认决策) -> 默认决策变化 {
113        let mut rng = rng();
114        const MAX_TRIES: usize = 100;
115        for _ in 0..MAX_TRIES {
116            let 元素 = (0..决策.元素.len()).choose(&mut rng).unwrap();
117            let 当前安排 = 决策.元素[元素];
118            // 蓄水池抽样
119            let mut 下一个安排 = None;
120            let mut count = 0;
121            for 条件安排 in &self.决策空间.元素[元素] {
122                if 条件安排.安排 != 当前安排 && 决策.允许(条件安排) {
123                    count += 1;
124                    if random_range(0..count) == 0 {
125                        下一个安排 = Some(&条件安排.安排);
126                    }
127                }
128            }
129            if let Some(下一个安排) = 下一个安排 {
130                决策.元素[元素] = *下一个安排;
131                debug!(
132                    "随机移动元素 {:?} 从 {:?} 到 {:?}",
133                    self.棱镜.数字转元素[&元素], 当前安排, 下一个安排
134                );
135                let mut 增加元素 = vec![];
136                let mut 减少元素 = vec![];
137                let mut 移动元素 = vec![];
138                if let 默认安排::未选取 = 当前安排 {
139                    增加元素.push(元素);
140                } else if let 默认安排::未选取 = 下一个安排 {
141                    减少元素.push(元素);
142                } else {
143                    移动元素.push(元素);
144                }
145                return 默认决策变化::新建(增加元素, 减少元素, 移动元素);
146            }
147        }
148        默认决策变化::不变()
149    }
150}