detect cycles and use usize for most numbers

This commit is contained in:
cy 2025-01-17 16:00:58 -05:00
parent d9dfeb00ec
commit 68c610cf5e

View file

@ -8,7 +8,7 @@ struct Edgenode {
#[allow(unused)] #[allow(unused)]
weight: i32, // Edge weight, if any weight: i32, // Edge weight, if any
y: i32, // Adjacency info y: usize, // Adjacency info
next: Option<Rc<Edgenode>>, // next edge in list next: Option<Rc<Edgenode>>, // next edge in list
} }
@ -16,7 +16,7 @@ pub struct Graph {
edges: Vec<Option<Rc<Edgenode>>>, // adjacency info edges: Vec<Option<Rc<Edgenode>>>, // adjacency info
degree: Vec<i32>, // outdegree of each vertex degree: Vec<i32>, // outdegree of each vertex
nvertices: usize, // number of vertices in graph nvertices: usize, // number of vertices in graph
nedges: i32, // number of edges in graph nedges: usize, // number of edges in graph
directed: bool, // is the graph directed? directed: bool, // is the graph directed?
} }
@ -26,8 +26,10 @@ struct SearchState {
// A vertex is `processed` after we have traversed all outgoing // A vertex is `processed` after we have traversed all outgoing
// edges from it. // edges from it.
processed: Vec<bool>, processed: Vec<bool>,
// Discovery relation // Discovery relation. Needs to be signed cause we initialize it to -1
parent: Vec<i32>, parent: Vec<i32>,
// Time tracking for DFS
time: usize,
} }
impl Graph { impl Graph {
@ -41,7 +43,7 @@ impl Graph {
} }
} }
fn insert_edge(&mut self, x: usize, y: i32, directed: bool) { fn insert_edge(&mut self, x: usize, y: usize, directed: bool) {
let p = Rc::new(Edgenode { let p = Rc::new(Edgenode {
y, y,
weight: 0, weight: 0,
@ -52,7 +54,7 @@ impl Graph {
if directed { if directed {
self.nedges += 1; self.nedges += 1;
} else { } else {
self.insert_edge(y.try_into().unwrap(), x.try_into().unwrap(), true); self.insert_edge(y, x, true);
} }
} }
@ -83,9 +85,9 @@ impl Graph {
// After that, parse edges as (x, y) // After that, parse edges as (x, y)
for _ in 0..num_edges { for _ in 0..num_edges {
let x: i32 = data_parsed.pop().unwrap().parse().unwrap(); let x: usize = data_parsed.pop().unwrap().parse().unwrap();
let y: i32 = data_parsed.pop().unwrap().parse().unwrap(); let y: usize = data_parsed.pop().unwrap().parse().unwrap();
self.insert_edge(x.try_into().unwrap(), y, directed); self.insert_edge(x, y, directed);
} }
} }
@ -99,7 +101,7 @@ impl Graph {
state.processed[v] = true; state.processed[v] = true;
let mut p_opt = &self.edges[v]; let mut p_opt = &self.edges[v];
while let Some(p) = p_opt { while let Some(p) = p_opt {
let y: usize = p.y.try_into().unwrap(); let y: usize = p.y;
if !state.processed[y] || self.directed { if !state.processed[y] || self.directed {
println!("process edge ({:?},{:?})", v, y); println!("process edge ({:?},{:?})", v, y);
} }
@ -122,7 +124,7 @@ impl Graph {
while let Some(v) = q.pop() { while let Some(v) = q.pop() {
let mut p_opt = &self.edges[v]; let mut p_opt = &self.edges[v];
while let Some(p) = p_opt { while let Some(p) = p_opt {
let y: usize = p.y.try_into().unwrap(); let y: usize = p.y;
if !state.discovered[y] { if !state.discovered[y] {
state.discovered[y] = true; state.discovered[y] = true;
state.parent[y] = v.try_into().unwrap(); state.parent[y] = v.try_into().unwrap();
@ -131,6 +133,9 @@ impl Graph {
} else if !state.processed[y] || self.directed { } else if !state.processed[y] || self.directed {
println!("process edge ({:?},{:?})", v, y); println!("process edge ({:?},{:?})", v, y);
} }
if state.parent[y] != v.try_into().unwrap() {
println!("cycle from {:?} to {:?}", v, y);
}
p_opt = &p.next; p_opt = &p.next;
} }
state.processed[v] = true; state.processed[v] = true;
@ -144,6 +149,7 @@ impl SearchState {
discovered: vec![false; MAXV], discovered: vec![false; MAXV],
processed: vec![false; MAXV], processed: vec![false; MAXV],
parent: vec![-1; MAXV], parent: vec![-1; MAXV],
time: 0,
} }
} }
} }