Skip to content

Commit 286632e

Browse files
committed
Started implementing dijkstra
1 parent 22bf751 commit 286632e

File tree

8 files changed

+307
-175
lines changed

8 files changed

+307
-175
lines changed

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "rust_graph_visualiser"
3-
version = "1.0.0"
3+
version = "1.0.1"
44
edition = "2021"
55

66
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

src/graph.rs

Lines changed: 119 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use std::cmp::Ordering;
2+
13
use crate::utils::is_point_in_circle;
24

35
// TODO: consider using a Vec<u8> to store the points
@@ -43,10 +45,10 @@ impl Default for DijkstraGraph
4345

4446
impl DijkstraGraph
4547
{
46-
pub fn new() -> DijkstraGraph
48+
pub(crate) fn new() -> DijkstraGraph
4749
{ return DijkstraGraph { ..DijkstraGraph::default() }; }
4850

49-
pub fn clear(&mut self)
51+
pub(crate) fn clear(&mut self)
5052
{
5153
self.points = self.points.iter()
5254
.map(|_| None)
@@ -58,46 +60,32 @@ impl DijkstraGraph
5860
self.end = None;
5961
}
6062

61-
pub fn clear_path(&mut self)
63+
pub(crate) fn clear_path(&mut self)
6264
{
63-
self.points = self.points.iter()
64-
.map(|point_option|
65-
{
66-
if point_option.is_some()
67-
{
68-
let mut point = point_option.clone().unwrap();
69-
point.parent = None;
70-
return Some(point);
71-
}
72-
else
73-
{
74-
return None;
75-
}
76-
})
77-
.collect::<Vec<_>>()
78-
.try_into()
79-
.unwrap();
80-
81-
self.start = None;
82-
self.end = None;
65+
for option in self.points.iter_mut()
66+
{
67+
let Some(point) = option.as_mut() else { continue; };
68+
point.parent = None;
69+
point.visited = false;
70+
}
8371
}
8472

8573
/// Returns the amount of nodes in the graph
86-
pub fn size(&self) -> usize
74+
pub(crate) fn size(&self) -> usize
8775
{
8876
let mut size = 0;
8977
self.points.iter().for_each(|node| { if node.is_some() { size += 1; } });
9078
return size;
9179
}
9280

93-
pub fn add_point(&mut self, id: usize, x: f32, y: f32)
81+
pub(crate) fn add_point(&mut self, id: usize, x: f32, y: f32)
9482
{
9583
if id > 100 { return; }
9684
if self.points[id].is_none() { self.points[id] = Some(DijkstraNode::new(x, y)); }
9785
}
9886

9987
/// Inserts a node at the first missing instance of the array
100-
pub fn append_point(&mut self, x: f32, y: f32)
88+
pub(crate) fn append_point(&mut self, x: f32, y: f32)
10189
{
10290
for (index, node_option) in self.points.iter().enumerate()
10391
{
@@ -109,14 +97,14 @@ impl DijkstraGraph
10997
}
11098
}
11199

112-
pub fn remove_point(&mut self, id: usize)
100+
pub(crate) fn remove_point(&mut self, id: usize)
113101
{
114102
if id > 100 { return; }
115103
self.points[id] = None;
116104
}
117105

118106
/// Adds a line; if it already exists, the length gets updated
119-
pub fn add_line(&mut self, from: usize, to: usize, distance: u16)
107+
pub(crate) fn add_line(&mut self, from: usize, to: usize, distance: u16)
120108
{
121109
if from > 100 || to > 100 { return; }
122110

@@ -135,58 +123,123 @@ impl DijkstraGraph
135123
point.edges.push(Edge { destination: to, distance });
136124
}
137125

138-
pub fn remove_line(&mut self, from: usize, to: usize)
126+
pub(crate) fn remove_line(&mut self, from: usize, to: usize)
139127
{
140128
if from > 100 || to > 100 { return; }
141129

142130
let Some(from_point) = self.points[from].as_mut() else { return; };
143131
from_point.edges.remove(to);
144132
}
145133

146-
pub fn get(&self, id: usize) -> &Option<DijkstraNode>
134+
pub(crate) fn get(&self, id: usize) -> &Option<DijkstraNode>
147135
{ return &self.points[id]; }
148136

149-
pub fn get_mut(&mut self, id: usize) -> &mut Option<DijkstraNode>
137+
pub(crate) fn get_mut(&mut self, id: usize) -> &mut Option<DijkstraNode>
150138
{ return &mut self.points[id]; }
151139

152-
pub fn start(&self) -> Option<usize>
140+
pub(crate) fn start(&self) -> Option<usize>
153141
{ return self.start; }
154142

155-
pub fn set_start(&mut self, start: usize)
143+
pub(crate) fn set_start(&mut self, start: usize)
156144
{
157145
if start > 100 { return; }
158146
self.start = Some(start);
159147
}
160148

161-
pub fn clear_start(&mut self)
149+
pub(crate) fn clear_start(&mut self)
162150
{ self.start = None; }
163151

164-
pub fn end(&self) -> Option<usize>
152+
pub(crate) fn end(&self) -> Option<usize>
165153
{ return self.end; }
166154

167-
pub fn set_end(&mut self, end: usize)
155+
pub(crate) fn set_end(&mut self, end: usize)
168156
{
169157
if end > 100 { return; }
170158
self.end = Some(end);
171159
}
172160

173-
pub fn clear_end(&mut self)
161+
pub(crate) fn clear_end(&mut self)
174162
{ self.end = None; }
175163

176164
/// Returns true if the shortest path has been found
177-
pub fn find_shortest_path(&mut self) -> bool
165+
pub(crate) fn find_shortest_path(&mut self)
178166
{
179-
if self.start.is_none() || self.end.is_none() { return false; }
167+
if self.start.is_none() || self.end.is_none() || (self.start.is_none() && self.end.is_none()) { return; }
168+
if self.points[self.start.unwrap()].is_none() { self.start = None; return; }
169+
if self.points[self.end.unwrap()].is_none() { self.end = None; return; }
170+
171+
self.clear_path();
172+
173+
self.points[self.start.unwrap()].as_mut().unwrap().distance = Some(0);
174+
self.points[self.start.unwrap()].as_mut().unwrap().parent = Some(self.start.unwrap());
175+
176+
let mut unvisited_points = vec![];
177+
unvisited_points.push(self.start.unwrap());
178+
let mut current_id;
179+
let mut path_length: u16; // TODO: this
180180

181-
todo!();
182181
// --- DIJKSTRA'S SHORTEST PATH ALGORITHM ---
182+
while !unvisited_points.is_empty()
183+
{
184+
/*
185+
unvisited_points.sort_by(|a, b|
186+
{
187+
// It is basically impossible, that unvisited_points contains ids that aren't in the graph
188+
let distance_a = self.points[*a].as_ref().unwrap().distance;
189+
let distance_b = self.points[*b].as_ref().unwrap().distance;
190+
191+
// Distance = None serves as the infinite value
192+
match (distance_a, distance_b)
193+
{
194+
(None, None) => return Ordering::Equal,
195+
(Some(_), None) => return Ordering::Less,
196+
(None, Some(_)) => return Ordering::Greater,
197+
(Some(dist_a), Some(dist_b)) => return dist_a.cmp(&dist_b),
198+
};
199+
});
200+
*/
201+
202+
/*
203+
// Removing all points that have been marked as visited
204+
unvisited_points.retain(|id| !self.points[*id].as_ref().unwrap().visited);
205+
if unvisited_points.is_empty() { break; }
206+
*/
207+
208+
current_id = *unvisited_points.first().unwrap();
209+
unvisited_points.remove(0);
210+
211+
if self.points[current_id].is_none() { continue; }
212+
213+
let current_point = self.points[current_id].as_mut().unwrap();
214+
current_point.visited = true;
215+
let current_point_distance = current_point.distance.clone().unwrap();
216+
let edges = current_point.edges.clone();
217+
218+
// drop(current_point);
219+
220+
for edge in edges
221+
{
222+
let Some(neighbour) = self.points[edge.destination].as_mut() else { return; };
223+
224+
if !neighbour.visited
225+
{ unvisited_points.push(edge.destination); }
226+
227+
let possibly_lower_goal = current_point_distance + edge.distance;
228+
229+
if neighbour.distance.is_none() || neighbour.distance.unwrap() > possibly_lower_goal
230+
{
231+
neighbour.distance = Some(possibly_lower_goal);
232+
neighbour.parent = Some(current_id);
233+
}
234+
}
235+
}
183236
}
184237

185-
pub fn get_path(&self) -> Option<Vec<usize>>
238+
pub(crate) fn get_path(&self) -> Option<Vec<usize>>
186239
{
187-
if self.start.is_none() || self.end.is_none() { return None; }
240+
if self.start.is_none() || self.end.is_none() || (self.start.is_none() && self.end.is_none()) { return None; }
188241

189-
let mut current_node = self.start.unwrap();
242+
let mut current_node = self.end.unwrap();
190243
let mut path = vec![current_node];
191244

192245
for _ in 0..self.points.len()
@@ -198,16 +251,18 @@ impl DijkstraGraph
198251

199252
path.push(current_node);
200253

201-
if current_node == self.end.unwrap() { break; }
254+
if current_node == self.start.unwrap() { break; }
202255
}
203256

257+
path.reverse();
258+
204259
return Some(path);
205260
}
206261

207-
pub fn points(&self) -> &[Option<DijkstraNode>; 100]
262+
pub(crate) fn points(&self) -> &[Option<DijkstraNode>; 100]
208263
{ return &self.points; }
209264

210-
pub fn lines(&self) -> Vec<(usize, &DijkstraNode, u16, usize, &DijkstraNode)>
265+
pub(crate) fn lines(&self) -> Vec<(usize, &DijkstraNode, u16, usize, &DijkstraNode)>
211266
{
212267
let mut lines = vec![];
213268

@@ -229,7 +284,7 @@ impl DijkstraGraph
229284
return lines;
230285
}
231286

232-
pub fn find_hovered_point(&mut self, mouse_x: f32, mouse_y: f32, radius: f32) -> Option<usize>
287+
pub(crate) fn find_hovered_point(&mut self, mouse_x: f32, mouse_y: f32, radius: f32) -> Option<usize>
233288
{
234289
let mut point_id = None;
235290

@@ -248,31 +303,14 @@ impl DijkstraGraph
248303
}
249304

250305
// !dbg
251-
pub fn print_path(&self)
306+
pub(crate) fn print_graph_data(&self)
252307
{
253-
let Some(path) = self.get_path() else { return; };
254-
println!("{:?}", path);
255-
}
256-
257-
// !dbg
258-
pub fn print_graph_data(&self)
259-
{
260-
println!("Points:");
261-
self.points.iter().enumerate().for_each(|(index, node_option)|
262-
{
263-
if node_option.is_some()
264-
{ print!("{} ", index); }
265-
});
266-
267-
println!("Lines:");
268-
self.points.iter().enumerate().for_each(|(index, node_option)|
269-
{
270-
if let Some(node) = node_option
308+
println!("Graph data:");
309+
self.lines().iter()
310+
.for_each(|(from_id, _, distance, to_id, _)|
271311
{
272-
node.edges.iter().for_each(|edge|
273-
{ print!("{}->{} ", index, edge.destination); });
274-
}
275-
});
312+
println!(" {}--{}-->{}", from_id, distance, to_id);
313+
});
276314

277315
match self.start
278316
{
@@ -285,10 +323,16 @@ impl DijkstraGraph
285323
Some(id) => println!("End: {}", id),
286324
None => println!("End: None"),
287325
}
326+
327+
match self.get_path()
328+
{
329+
Some(path) => println!("Path: {:?}", path),
330+
None => println!("Path: None")
331+
}
288332
}
289333

290334
/// Replaces the current graph with a small one
291-
pub fn insert_small_graph(&mut self)
335+
pub(crate) fn insert_small_graph(&mut self)
292336
{
293337
self.clear();
294338

@@ -317,7 +361,7 @@ impl DijkstraGraph
317361
}
318362

319363
/// Replaces the current graph with a medium-sized one
320-
pub fn insert_medium_graph(&mut self)
364+
pub(crate) fn insert_medium_graph(&mut self)
321365
{
322366
self.clear();
323367

@@ -353,7 +397,7 @@ impl DijkstraGraph
353397
}
354398

355399
/// Replaces the current graph with a large one
356-
pub fn insert_large_graph(&mut self)
400+
pub(crate) fn insert_large_graph(&mut self)
357401
{
358402
self.clear();
359403

@@ -415,8 +459,8 @@ impl DijkstraGraph
415459
#[derive(Clone, Debug)]
416460
pub(crate) struct DijkstraNode
417461
{
418-
pub x: f32,
419-
pub y: f32,
462+
pub(crate) x: f32,
463+
pub(crate) y: f32,
420464
parent: Option<usize>,
421465
distance: Option<u16>,
422466
visited: bool,

0 commit comments

Comments
 (0)