[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 rand::Rng;
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use std::ops::Mul;
|
use std::ops::Mul;
|
||||||
use bgtu_ai_utility::graph::VerticesVec;
|
use bgtu_ai_utility::graph::{CompleteGraph, VerticesVec};
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
pub enum AntDirection {
|
pub enum AntDirection {
|
||||||
@ -40,8 +40,7 @@ pub enum AntLocation {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct AntsSimulationState {
|
pub struct AntsSimulationState {
|
||||||
pub vertices: VerticesVec,
|
pub graph: CompleteGraph<EdgeExtraData>,
|
||||||
pub edges: EdgesVec,
|
|
||||||
pub ants: Vec<Ant>,
|
pub ants: Vec<Ant>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -74,7 +73,7 @@ fn _updateState(
|
|||||||
offset,
|
offset,
|
||||||
direction,
|
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;
|
edge.extra.ferment_intensity += (cfg.q / edge.length) * cfg.r;
|
||||||
let vertex_index;
|
let vertex_index;
|
||||||
match direction {
|
match direction {
|
||||||
@ -84,9 +83,9 @@ fn _updateState(
|
|||||||
ant.location = AntLocation::OnVertex { vertex_index }
|
ant.location = AntLocation::OnVertex { vertex_index }
|
||||||
}
|
}
|
||||||
AntLocation::OnVertex { vertex_index } => {
|
AntLocation::OnVertex { vertex_index } => {
|
||||||
let allowed_outbounds = state.vertices[*vertex_index]
|
let allowed_outbounds = state.graph.vertices[*vertex_index]
|
||||||
.iter()
|
.iter()
|
||||||
.map(|ei| (*ei, &state.edges[*ei]))
|
.map(|ei| (*ei, &state.graph.edges[*ei]))
|
||||||
.map(|(ei, e)| {
|
.map(|(ei, e)| {
|
||||||
if *vertex_index == e.vertex1_index {
|
if *vertex_index == e.vertex1_index {
|
||||||
return (ei, e, e.vertex2_index, AntDirection::ToSecond);
|
return (ei, e, e.vertex2_index, AntDirection::ToSecond);
|
||||||
|
|||||||
@ -3,22 +3,22 @@
|
|||||||
mod algo;
|
mod algo;
|
||||||
|
|
||||||
use crate::algo::{
|
use crate::algo::{
|
||||||
updateState, Ant, AntsSimulationConfig, AntsSimulationState, EdgeExtraData, EdgesVec,
|
Ant, AntsSimulationConfig, AntsSimulationState, EdgeExtraData, EdgesVec, VerticesVec,
|
||||||
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::render::render_graph;
|
||||||
use bgtu_ai_utility::gui::{boot_eframe, labeled_slider};
|
use bgtu_ai_utility::gui::{boot_eframe, labeled_slider};
|
||||||
use eframe::egui;
|
use eframe::egui;
|
||||||
use eframe::egui::{Frame, Ui};
|
use eframe::egui::{Frame, Ui};
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use bgtu_ai_utility::UpdatePending;
|
use bgtu_ai_utility::graph::CompleteGraph;
|
||||||
|
|
||||||
fn main() -> eframe::Result {
|
fn main() -> eframe::Result {
|
||||||
return boot_eframe(|| MyApp::new());
|
return boot_eframe(|| MyApp::new());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
enum GlobalState {
|
enum GlobalState {
|
||||||
Edit,
|
Edit,
|
||||||
Running,
|
Running,
|
||||||
@ -37,8 +37,7 @@ impl MyApp {
|
|||||||
fn new() -> Self {
|
fn new() -> Self {
|
||||||
return Self {
|
return Self {
|
||||||
simulation: AntsSimulationState {
|
simulation: AntsSimulationState {
|
||||||
edges: EdgesVec::new(),
|
graph: CompleteGraph::new(),
|
||||||
vertices: VerticesVec::new(),
|
|
||||||
ants: Vec::new(),
|
ants: Vec::new(),
|
||||||
},
|
},
|
||||||
vertex_update: UpdatePending::NoChange,
|
vertex_update: UpdatePending::NoChange,
|
||||||
@ -55,7 +54,6 @@ impl MyApp {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl eframe::App for MyApp {
|
impl eframe::App for MyApp {
|
||||||
fn update(&mut self, ui: &eframe::egui::Context, _frame: &mut eframe::Frame) {
|
fn update(&mut self, ui: &eframe::egui::Context, _frame: &mut eframe::Frame) {
|
||||||
egui::CentralPanel::default().show(ui, |ui| match self.state {
|
egui::CentralPanel::default().show(ui, |ui| match self.state {
|
||||||
@ -63,37 +61,13 @@ impl eframe::App for MyApp {
|
|||||||
match self.vertex_update {
|
match self.vertex_update {
|
||||||
UpdatePending::NoChange => {}
|
UpdatePending::NoChange => {}
|
||||||
UpdatePending::Add => {
|
UpdatePending::Add => {
|
||||||
let new_vi = self.simulation.vertices.add(HashSet::new());
|
self.simulation.graph.add_vertex(|| EdgeExtraData {
|
||||||
let mut newEdgesSet = HashSet::new();
|
ferment_intensity: 0.0,
|
||||||
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.vertex_update = UpdatePending::NoChange;
|
self.vertex_update = UpdatePending::NoChange;
|
||||||
}
|
}
|
||||||
UpdatePending::Remove(vi) => {
|
UpdatePending::Remove(vi) => {
|
||||||
let mut eis = Vec::with_capacity(self.simulation.vertices[vi].len());
|
self.simulation.graph.remove_vertex(vi);
|
||||||
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.vertex_update = UpdatePending::NoChange;
|
self.vertex_update = UpdatePending::NoChange;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -159,15 +133,15 @@ fn edit_panel(data: &mut MyApp, ui: &mut Ui) {
|
|||||||
|
|
||||||
draw_lengths_table(
|
draw_lengths_table(
|
||||||
ui,
|
ui,
|
||||||
&mut data.simulation.vertices,
|
&mut data.simulation.graph.vertices,
|
||||||
&mut data.simulation.edges,
|
&mut data.simulation.graph.edges,
|
||||||
&mut data.vertex_update,
|
&mut data.vertex_update,
|
||||||
);
|
);
|
||||||
|
|
||||||
if run {
|
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] = (
|
coords[i] = (
|
||||||
rand::random::<f32>() * 0.8 + 0.1,
|
rand::random::<f32>() * 0.8 + 0.1,
|
||||||
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
|
let allowed_locations = data
|
||||||
.simulation
|
.simulation
|
||||||
.vertices
|
.graph.vertices
|
||||||
.iter_indexed()
|
.iter_indexed()
|
||||||
.map(|(i, _)| i)
|
.map(|(i, _)| i)
|
||||||
.collect::<HashSet<usize>>();
|
.collect::<HashSet<usize>>();
|
||||||
|
|
||||||
let mut ants = Vec::new();
|
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 {
|
for _ in 0..data.ants_per_vertex {
|
||||||
ants.push(Ant::new(i, allowed_locations.clone()))
|
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
|
for w in data
|
||||||
.simulation
|
.simulation
|
||||||
.edges
|
.graph.edges
|
||||||
.iter()
|
.iter()
|
||||||
.map(|e| e.extra.ferment_intensity)
|
.map(|e| e.extra.ferment_intensity)
|
||||||
{
|
{
|
||||||
@ -229,9 +203,9 @@ fn draw_ants(data: &mut MyApp, ui: &mut Ui) {
|
|||||||
|
|
||||||
render_graph(
|
render_graph(
|
||||||
ui,
|
ui,
|
||||||
&data.simulation.vertices,
|
&data.simulation.graph.vertices,
|
||||||
data.vertex_locations.as_mut_slice(),
|
data.vertex_locations.as_mut_slice(),
|
||||||
&data.simulation.edges,
|
&data.simulation.graph.edges,
|
||||||
|e| e.extra.ferment_intensity / cap,
|
|e| e.extra.ferment_intensity / cap,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -23,17 +23,23 @@ impl<T> _PreserveIndexVec<T> {
|
|||||||
return self.len;
|
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 {
|
match self.next_free {
|
||||||
None => {
|
None => {
|
||||||
self.buffer.push(Cell::Value { value });
|
let cell = Cell::Value {
|
||||||
|
value: constructor(self, self.len),
|
||||||
|
};
|
||||||
|
self.buffer.push(cell);
|
||||||
self.len += 1;
|
self.len += 1;
|
||||||
return self.buffer.len() - 1;
|
return self.buffer.len() - 1;
|
||||||
}
|
}
|
||||||
Some(i) => match self.buffer[i] {
|
Some(i) => match self.buffer[i] {
|
||||||
Cell::Free { next_free_cell_id } => {
|
Cell::Free { next_free_cell_id } => {
|
||||||
self.next_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;
|
self.len += 1;
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
@ -55,41 +61,36 @@ impl<T> _PreserveIndexVec<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn iter(&self) -> impl Iterator<Item = &T> {
|
||||||
pub fn iter(&self) -> impl Iterator<Item=&T>{
|
return self.buffer.iter().filter_map(|c| match c {
|
||||||
return self.buffer.iter().filter_map(|c| {
|
Cell::Free { .. } => return None,
|
||||||
match c {
|
Cell::Value { value } => return Some(value),
|
||||||
Cell::Free { .. } => return None,
|
});
|
||||||
Cell::Value { value } => return Some(value)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn iter_mut(&mut self) -> impl Iterator<Item=&mut T>{
|
pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut T> {
|
||||||
return self.buffer.iter_mut().filter_map(|c| {
|
return self.buffer.iter_mut().filter_map(|c| match c {
|
||||||
match c {
|
Cell::Free { .. } => return None,
|
||||||
Cell::Free { .. } => return None,
|
Cell::Value { value } => return Some(value),
|
||||||
Cell::Value { value } => return Some(value)
|
});
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn iter_indexed(&self) -> impl Iterator<Item=(usize, &T)>{
|
pub fn iter_indexed(&self) -> impl Iterator<Item = (usize, &T)> {
|
||||||
return self.buffer.iter().enumerate().filter_map(|(i, c)| {
|
return self.buffer.iter().enumerate().filter_map(|(i, c)| match c {
|
||||||
match c {
|
Cell::Free { .. } => return None,
|
||||||
Cell::Free { .. } => return None,
|
Cell::Value { value } => return Some((i, value)),
|
||||||
Cell::Value { value } => return Some((i, value))
|
});
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn iter_indexed_mut(&mut self) -> impl Iterator<Item=(usize, &mut T)>{
|
pub fn iter_indexed_mut(&mut self) -> impl Iterator<Item = (usize, &mut T)> {
|
||||||
return self.buffer.iter_mut().enumerate().filter_map(|(i, c)| {
|
return self
|
||||||
match c {
|
.buffer
|
||||||
|
.iter_mut()
|
||||||
|
.enumerate()
|
||||||
|
.filter_map(|(i, c)| match c {
|
||||||
Cell::Free { .. } => return None,
|
Cell::Free { .. } => return None,
|
||||||
Cell::Value { value } => return Some((i, value))
|
Cell::Value { value } => return Some((i, value)),
|
||||||
}
|
});
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn capacity(&self) -> usize {
|
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,
|
length,
|
||||||
extra
|
extra
|
||||||
};
|
};
|
||||||
return self.data.add(data);
|
return self.data.add(|_, _| data);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn remove(&mut self, edge_index: usize) {
|
pub fn remove(&mut self, edge_index: usize) {
|
||||||
|
|||||||
@ -1,7 +1,9 @@
|
|||||||
mod _preserve_index_vec;
|
mod _preserve_index_vec;
|
||||||
|
mod complete_graph;
|
||||||
pub mod edges;
|
pub mod edges;
|
||||||
pub mod vertices;
|
pub mod vertices;
|
||||||
|
|
||||||
use _preserve_index_vec::_PreserveIndexVec;
|
use _preserve_index_vec::_PreserveIndexVec;
|
||||||
|
pub use complete_graph::CompleteGraph;
|
||||||
pub use edges::{Edge, EdgesVec};
|
pub use edges::{Edge, EdgesVec};
|
||||||
pub use vertices::VerticesVec;
|
pub use vertices::VerticesVec;
|
||||||
|
|||||||
@ -16,8 +16,16 @@ impl VerticesVec {
|
|||||||
pub fn len(&self) -> usize {
|
pub fn len(&self) -> usize {
|
||||||
return self.data.len();
|
return self.data.len();
|
||||||
}
|
}
|
||||||
pub fn add(&mut self, edges: HashSet<usize>) -> usize {
|
pub fn add(
|
||||||
return self.data.add(edges);
|
&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) {
|
pub fn remove(&mut self, edge_index: usize) {
|
||||||
@ -35,7 +43,7 @@ impl VerticesVec {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn capacity(&self) -> usize {
|
pub fn capacity(&self) -> usize {
|
||||||
return self.data.capacity()
|
return self.data.capacity();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user