ai-0/lab3/src/algo/update_state.rs

62 lines
1.9 KiB
Rust

use crate::algo::Ant;
use crate::algo::state::AntsSimulationState;
use bgtu_ai_utility::weighted_random;
use rand::Rng;
use std::collections::HashSet;
use std::ptr;
impl AntsSimulationState<'_> {
pub fn is_ended(&self) -> bool {
return self.ants.iter().all(|a| a.allowed_vertices.len() == 0);
}
pub fn update1(&mut self, rng: &mut impl Rng) {
self._move_ants(rng);
self._evaporate_ferments();
}
fn _move_ants(&mut self, rng: &mut impl Rng) {
for ant in unsafe { (*ptr::from_mut(&mut self.ants)).iter_mut() } {
let outbound_weights =
self._get_outbounds_weights(ant.current_vertex, &ant.allowed_vertices);
match weighted_random(rng, &outbound_weights, |e| e.2) {
None => {}
Some((ei, nvi, _)) => {
self.ferments[*ei] += self._calculate_ferment(*ei);
ant.current_vertex = *nvi;
ant.allowed_vertices.remove(nvi);
}
}
}
}
fn _get_outbounds_weights(
&self,
location: usize,
allowed_outbounds: &HashSet<usize>,
) -> Vec<(usize, usize, f64)> {
let mut weights = Vec::with_capacity(allowed_outbounds.len());
for ei in self.graph.vertices[location].iter().map(|ei| *ei) {
let outbound = self.graph.edges[ei].another(location);
if !allowed_outbounds.contains(&outbound) {
continue;
}
weights.push((ei, outbound, self._calculate_weight(ei)))
}
return weights;
}
fn _calculate_weight(&self, edge: usize) -> f64 {
let a = self.ferments[edge].powf(self.cfg.ferment_weight);
let b = (1.0 / self.graph.edges[edge].length).powf(self.cfg.heuristic_coefficient);
return a * b;
}
fn _calculate_ferment(&self, edge: usize) -> f64 {
return self.cfg.q;
}
fn _evaporate_ferments(&mut self) {}
}