use crate::error::{GraphalgError, GraphalgResult};
#[derive(Debug, Clone)]
pub struct AdjacencyMatrix {
pub n: usize,
pub mat: Vec<bool>,
}
impl AdjacencyMatrix {
pub fn new(n: usize) -> Self {
Self {
n,
mat: vec![false; n * n],
}
}
fn check_index(&self, u: usize, v: usize) -> GraphalgResult<()> {
if u >= self.n {
return Err(GraphalgError::IndexOutOfBounds {
index: u,
len: self.n,
});
}
if v >= self.n {
return Err(GraphalgError::IndexOutOfBounds {
index: v,
len: self.n,
});
}
Ok(())
}
pub fn set(&mut self, u: usize, v: usize, value: bool) -> GraphalgResult<()> {
self.check_index(u, v)?;
self.mat[u * self.n + v] = value;
Ok(())
}
pub fn add_edge(&mut self, u: usize, v: usize) -> GraphalgResult<()> {
self.set(u, v, true)
}
pub fn add_undirected_edge(&mut self, u: usize, v: usize) -> GraphalgResult<()> {
self.set(u, v, true)?;
self.set(v, u, true)?;
Ok(())
}
pub fn has_edge(&self, u: usize, v: usize) -> GraphalgResult<bool> {
self.check_index(u, v)?;
Ok(self.mat[u * self.n + v])
}
pub fn num_edges(&self) -> usize {
self.mat.iter().filter(|x| **x).count()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn empty_matrix() {
let m = AdjacencyMatrix::new(4);
assert_eq!(m.num_edges(), 0);
}
#[test]
fn set_and_get() {
let mut m = AdjacencyMatrix::new(3);
m.add_edge(0, 1).expect("ok");
assert!(m.has_edge(0, 1).expect("ok"));
assert!(!m.has_edge(1, 0).expect("ok"));
}
#[test]
fn undirected_symmetric() {
let mut m = AdjacencyMatrix::new(3);
m.add_undirected_edge(0, 2).expect("ok");
assert!(m.has_edge(0, 2).expect("ok"));
assert!(m.has_edge(2, 0).expect("ok"));
}
}