[lab3] Extracted add/remove vertex to complex graph
This commit is contained in:
parent
178007edee
commit
ed55515d26
@ -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<EdgeExtraData>,
|
||||
pub ants: Vec<Ant>,
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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::<f32>() * 0.8 + 0.1,
|
||||
rand::random::<f32>() * 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::<HashSet<usize>>();
|
||||
|
||||
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,
|
||||
)
|
||||
}
|
||||
|
||||
@ -23,17 +23,23 @@ impl<T> _PreserveIndexVec<T> {
|
||||
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<T> _PreserveIndexVec<T> {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pub fn iter(&self) -> impl Iterator<Item=&T>{
|
||||
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<Item = &T> {
|
||||
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<Item=&mut T>{
|
||||
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<Item = &mut T> {
|
||||
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<Item=(usize, &T)>{
|
||||
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<Item = (usize, &T)> {
|
||||
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<Item=(usize, &mut T)>{
|
||||
return self.buffer.iter_mut().enumerate().filter_map(|(i, c)| {
|
||||
match c {
|
||||
pub fn iter_indexed_mut(&mut self) -> impl Iterator<Item = (usize, &mut T)> {
|
||||
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<T> IndexMut<usize> for _PreserveIndexVec<T> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
39
utility/src/graph/complete_graph.rs
Normal file
39
utility/src/graph/complete_graph.rs
Normal file
@ -0,0 +1,39 @@
|
||||
use super::{EdgesVec, VerticesVec};
|
||||
|
||||
use std::collections::HashSet;
|
||||
|
||||
pub struct CompleteGraph<E> {
|
||||
pub vertices: VerticesVec,
|
||||
pub edges: EdgesVec<E>,
|
||||
}
|
||||
|
||||
impl<E> CompleteGraph<E> {
|
||||
pub fn new() -> Self {
|
||||
return Self {
|
||||
vertices: VerticesVec::new(),
|
||||
edges: EdgesVec::new(),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
impl<E> CompleteGraph<E> {
|
||||
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::<Vec<usize>>() {
|
||||
self.vertices[self.edges[ei].another(vi)].remove(&ei);
|
||||
self.edges.remove(ei);
|
||||
}
|
||||
self.vertices.remove(vi);
|
||||
}
|
||||
}
|
||||
@ -38,7 +38,7 @@ impl<D> EdgesVec<D> {
|
||||
length,
|
||||
extra
|
||||
};
|
||||
return self.data.add(data);
|
||||
return self.data.add(|_, _| data);
|
||||
}
|
||||
|
||||
pub fn remove(&mut self, edge_index: usize) {
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -16,8 +16,16 @@ impl VerticesVec {
|
||||
pub fn len(&self) -> usize {
|
||||
return self.data.len();
|
||||
}
|
||||
pub fn add(&mut self, edges: HashSet<usize>) -> usize {
|
||||
return self.data.add(edges);
|
||||
pub fn add(
|
||||
&mut self,
|
||||
edges_constructor: impl FnOnce(
|
||||
&mut dyn Iterator<Item = (usize, &mut HashSet<usize>)>,
|
||||
usize,
|
||||
) -> HashSet<usize>,
|
||||
) -> 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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user