diff --git a/lab3/src/algo/state.rs b/lab3/src/algo/state.rs index c6a8c44..bcf6851 100644 --- a/lab3/src/algo/state.rs +++ b/lab3/src/algo/state.rs @@ -1,8 +1,8 @@ -use super::EdgesVec; +use super::{EdgeExtraData, EdgesVec}; use rand::Rng; use std::collections::HashSet; use std::ops::Mul; -use bgtu_ai_utility::graph::VerticesVec; +use bgtu_ai_utility::graph::{CompleteGraph, VerticesVec}; #[derive(Clone, Copy)] pub enum AntDirection { @@ -40,8 +40,7 @@ pub enum AntLocation { } pub struct AntsSimulationState { - pub vertices: VerticesVec, - pub edges: EdgesVec, + pub graph: CompleteGraph, pub ants: Vec, } @@ -74,7 +73,7 @@ fn _updateState( offset, direction, } => { - let edge = &mut state.edges[*edge_index]; + let edge = &mut state.graph.edges[*edge_index]; edge.extra.ferment_intensity += (cfg.q / edge.length) * cfg.r; let vertex_index; match direction { @@ -84,9 +83,9 @@ fn _updateState( ant.location = AntLocation::OnVertex { vertex_index } } AntLocation::OnVertex { vertex_index } => { - let allowed_outbounds = state.vertices[*vertex_index] + let allowed_outbounds = state.graph.vertices[*vertex_index] .iter() - .map(|ei| (*ei, &state.edges[*ei])) + .map(|ei| (*ei, &state.graph.edges[*ei])) .map(|(ei, e)| { if *vertex_index == e.vertex1_index { return (ei, e, e.vertex2_index, AntDirection::ToSecond); diff --git a/lab3/src/main.rs b/lab3/src/main.rs index ec6e066..4f7b5ac 100644 --- a/lab3/src/main.rs +++ b/lab3/src/main.rs @@ -3,22 +3,22 @@ mod algo; use crate::algo::{ - updateState, Ant, AntsSimulationConfig, AntsSimulationState, EdgeExtraData, EdgesVec, - VerticesVec, + Ant, AntsSimulationConfig, AntsSimulationState, EdgeExtraData, EdgesVec, VerticesVec, + updateState, }; -use bgtu_ai_utility::gui::lengths_table::{draw_lengths_table}; +use bgtu_ai_utility::UpdatePending; +use bgtu_ai_utility::gui::lengths_table::draw_lengths_table; use bgtu_ai_utility::gui::render::render_graph; use bgtu_ai_utility::gui::{boot_eframe, labeled_slider}; use eframe::egui; use eframe::egui::{Frame, Ui}; use std::collections::HashSet; -use bgtu_ai_utility::UpdatePending; +use bgtu_ai_utility::graph::CompleteGraph; fn main() -> eframe::Result { return boot_eframe(|| MyApp::new()); } - enum GlobalState { Edit, Running, @@ -37,8 +37,7 @@ impl MyApp { fn new() -> Self { return Self { simulation: AntsSimulationState { - edges: EdgesVec::new(), - vertices: VerticesVec::new(), + graph: CompleteGraph::new(), ants: Vec::new(), }, vertex_update: UpdatePending::NoChange, @@ -55,7 +54,6 @@ impl MyApp { } } - impl eframe::App for MyApp { fn update(&mut self, ui: &eframe::egui::Context, _frame: &mut eframe::Frame) { egui::CentralPanel::default().show(ui, |ui| match self.state { @@ -63,37 +61,13 @@ impl eframe::App for MyApp { match self.vertex_update { UpdatePending::NoChange => {} UpdatePending::Add => { - let new_vi = self.simulation.vertices.add(HashSet::new()); - let mut newEdgesSet = HashSet::new(); - for (vi, v) in self.simulation.vertices.iter_indexed_mut() { - if (vi == new_vi) { - continue; - } - let ei = self.simulation.edges.add( - new_vi, - vi, - 1.0, - EdgeExtraData { - ferment_intensity: 0.0, - }, - ); - newEdgesSet.insert(ei); - v.insert(ei); - } - self.simulation.vertices[new_vi] = newEdgesSet; + self.simulation.graph.add_vertex(|| EdgeExtraData { + ferment_intensity: 0.0, + }); self.vertex_update = UpdatePending::NoChange; } UpdatePending::Remove(vi) => { - let mut eis = Vec::with_capacity(self.simulation.vertices[vi].len()); - for ei in self.simulation.vertices[vi].iter() { - eis.push(*ei) - } - for ei in eis { - self.simulation.vertices[self.simulation.edges[ei].another(vi)] - .remove(&ei); - self.simulation.edges.remove(ei); - } - self.simulation.vertices.remove(vi); + self.simulation.graph.remove_vertex(vi); self.vertex_update = UpdatePending::NoChange; } } @@ -159,15 +133,15 @@ fn edit_panel(data: &mut MyApp, ui: &mut Ui) { draw_lengths_table( ui, - &mut data.simulation.vertices, - &mut data.simulation.edges, + &mut data.simulation.graph.vertices, + &mut data.simulation.graph.edges, &mut data.vertex_update, ); if run { - let mut coords = vec![(0.0, 0.0); data.simulation.vertices.capacity()]; + let mut coords = vec![(0.0, 0.0); data.simulation.graph.vertices.capacity()]; - for (i, _) in data.simulation.vertices.iter_indexed() { + for (i, _) in data.simulation.graph.vertices.iter_indexed() { coords[i] = ( rand::random::() * 0.8 + 0.1, rand::random::() * 0.8 + 0.1, @@ -179,13 +153,13 @@ fn edit_panel(data: &mut MyApp, ui: &mut Ui) { let allowed_locations = data .simulation - .vertices + .graph.vertices .iter_indexed() .map(|(i, _)| i) .collect::>(); let mut ants = Vec::new(); - for (i, _) in data.simulation.vertices.iter_indexed() { + for (i, _) in data.simulation.graph.vertices.iter_indexed() { for _ in 0..data.ants_per_vertex { ants.push(Ant::new(i, allowed_locations.clone())) } @@ -218,7 +192,7 @@ fn draw_ants(data: &mut MyApp, ui: &mut Ui) { for w in data .simulation - .edges + .graph.edges .iter() .map(|e| e.extra.ferment_intensity) { @@ -229,9 +203,9 @@ fn draw_ants(data: &mut MyApp, ui: &mut Ui) { render_graph( ui, - &data.simulation.vertices, + &data.simulation.graph.vertices, data.vertex_locations.as_mut_slice(), - &data.simulation.edges, + &data.simulation.graph.edges, |e| e.extra.ferment_intensity / cap, ) } diff --git a/utility/src/graph/_preserve_index_vec.rs b/utility/src/graph/_preserve_index_vec.rs index e0df4bd..e47c8f8 100644 --- a/utility/src/graph/_preserve_index_vec.rs +++ b/utility/src/graph/_preserve_index_vec.rs @@ -23,17 +23,23 @@ impl _PreserveIndexVec { return self.len; } - pub fn add(&mut self, value: T) -> usize { + pub fn add(&mut self, constructor: impl FnOnce(&mut Self, usize) -> T) -> usize { match self.next_free { None => { - self.buffer.push(Cell::Value { value }); + let cell = Cell::Value { + value: constructor(self, self.len), + }; + self.buffer.push(cell); self.len += 1; return self.buffer.len() - 1; } Some(i) => match self.buffer[i] { Cell::Free { next_free_cell_id } => { self.next_free = next_free_cell_id; - self.buffer[i] = Cell::Value { value }; + let cell = Cell::Value { + value: constructor(self, i), + }; + self.buffer[i] = cell; self.len += 1; return i; } @@ -55,41 +61,36 @@ impl _PreserveIndexVec { } } - - pub fn iter(&self) -> impl Iterator{ - return self.buffer.iter().filter_map(|c| { - match c { - Cell::Free { .. } => return None, - Cell::Value { value } => return Some(value) - } - }) + pub fn iter(&self) -> impl Iterator { + return self.buffer.iter().filter_map(|c| match c { + Cell::Free { .. } => return None, + Cell::Value { value } => return Some(value), + }); } - pub fn iter_mut(&mut self) -> impl Iterator{ - return self.buffer.iter_mut().filter_map(|c| { - match c { - Cell::Free { .. } => return None, - Cell::Value { value } => return Some(value) - } - }) + pub fn iter_mut(&mut self) -> impl Iterator { + return self.buffer.iter_mut().filter_map(|c| match c { + Cell::Free { .. } => return None, + Cell::Value { value } => return Some(value), + }); } - pub fn iter_indexed(&self) -> impl Iterator{ - return self.buffer.iter().enumerate().filter_map(|(i, c)| { - match c { - Cell::Free { .. } => return None, - Cell::Value { value } => return Some((i, value)) - } - }) + pub fn iter_indexed(&self) -> impl Iterator { + return self.buffer.iter().enumerate().filter_map(|(i, c)| match c { + Cell::Free { .. } => return None, + Cell::Value { value } => return Some((i, value)), + }); } - pub fn iter_indexed_mut(&mut self) -> impl Iterator{ - return self.buffer.iter_mut().enumerate().filter_map(|(i, c)| { - match c { + pub fn iter_indexed_mut(&mut self) -> impl Iterator { + return self + .buffer + .iter_mut() + .enumerate() + .filter_map(|(i, c)| match c { Cell::Free { .. } => return None, - Cell::Value { value } => return Some((i, value)) - } - }) + Cell::Value { value } => return Some((i, value)), + }); } pub fn capacity(&self) -> usize { @@ -120,4 +121,3 @@ impl IndexMut for _PreserveIndexVec { } } } - diff --git a/utility/src/graph/complete_graph.rs b/utility/src/graph/complete_graph.rs new file mode 100644 index 0000000..478b033 --- /dev/null +++ b/utility/src/graph/complete_graph.rs @@ -0,0 +1,39 @@ +use super::{EdgesVec, VerticesVec}; + +use std::collections::HashSet; + +pub struct CompleteGraph { + pub vertices: VerticesVec, + pub edges: EdgesVec, +} + +impl CompleteGraph { + pub fn new() -> Self { + return Self { + vertices: VerticesVec::new(), + edges: EdgesVec::new(), + }; + } +} + +impl CompleteGraph { + pub fn add_vertex(&mut self, edge_constructor: impl Fn() -> E) { + self.vertices.add(|vertices, new_vi| { + let mut new_edges_set = HashSet::new(); + for (vi, v) in vertices { + let ei = self.edges.add(new_vi, vi, 1.0, edge_constructor()); + new_edges_set.insert(ei); + v.insert(ei); + } + return new_edges_set; + }); + } + + pub fn remove_vertex(&mut self, vi: usize) { + for ei in self.vertices[vi].iter().map(|i| *i).collect::>() { + self.vertices[self.edges[ei].another(vi)].remove(&ei); + self.edges.remove(ei); + } + self.vertices.remove(vi); + } +} diff --git a/utility/src/graph/edges.rs b/utility/src/graph/edges.rs index c62d0bb..cb7fa5e 100644 --- a/utility/src/graph/edges.rs +++ b/utility/src/graph/edges.rs @@ -38,7 +38,7 @@ impl EdgesVec { length, extra }; - return self.data.add(data); + return self.data.add(|_, _| data); } pub fn remove(&mut self, edge_index: usize) { diff --git a/utility/src/graph/mod.rs b/utility/src/graph/mod.rs index b42a450..1a68c25 100644 --- a/utility/src/graph/mod.rs +++ b/utility/src/graph/mod.rs @@ -1,7 +1,9 @@ mod _preserve_index_vec; +mod complete_graph; pub mod edges; pub mod vertices; use _preserve_index_vec::_PreserveIndexVec; +pub use complete_graph::CompleteGraph; pub use edges::{Edge, EdgesVec}; pub use vertices::VerticesVec; diff --git a/utility/src/graph/vertices.rs b/utility/src/graph/vertices.rs index b44a5bd..2a5e4d8 100644 --- a/utility/src/graph/vertices.rs +++ b/utility/src/graph/vertices.rs @@ -16,8 +16,16 @@ impl VerticesVec { pub fn len(&self) -> usize { return self.data.len(); } - pub fn add(&mut self, edges: HashSet) -> usize { - return self.data.add(edges); + pub fn add( + &mut self, + edges_constructor: impl FnOnce( + &mut dyn Iterator)>, + usize, + ) -> HashSet, + ) -> usize { + return self + .data + .add(|r, x| edges_constructor(&mut r.iter_indexed_mut(), x)); } pub fn remove(&mut self, edge_index: usize) { @@ -35,7 +43,7 @@ impl VerticesVec { } pub fn capacity(&self) -> usize { - return self.data.capacity() + return self.data.capacity(); } }