adjacency_matrix/static_half/
mod.rs1use crate::AdjacencyEdge;
2use graph_types::{GraphError, GraphResult, UndirectedEdge};
3use num_traits::{One, Zero};
4use std::{
5 cmp::Ordering,
6 fmt::{Debug, Display},
7 ops::AddAssign,
8};
9mod display;
10
11#[derive(Clone, Debug)]
12pub struct StaticUndirected {
13 edges: Vec<usize>,
15}
16
17impl StaticUndirected {
18 pub fn new(nodes: usize) -> Self {
19 Self { edges: vec![0; (nodes + 1) * nodes / 2] }
20 }
21 pub fn nodes(&self) -> usize {
22 (((self.edges.len() * 8 + 1) as f64).sqrt() / 2.0).floor() as usize
24 }
25 pub fn edges(&self) -> usize {
26 self.edges.len()
27 }
28 pub fn max_degree(&self) -> usize {
29 self.edges.iter().max().copied().unwrap_or(0)
30 }
31 pub fn min_degree(&self) -> usize {
32 self.edges.iter().min().copied().unwrap_or(0)
33 }
34 pub fn get_edge<T>(&self, undirected: T) -> GraphResult<usize>
35 where
36 T: Into<UndirectedEdge>,
37 {
38 let edge = undirected.into();
39 let index = edge_index(&edge);
40 match self.edges.get(index) {
41 Some(s) => Ok(*s),
42 None => Err(GraphError::edge_out_of_range(index, self.edges.len())),
43 }
44 }
45 pub fn mut_edge<T>(&mut self, undirected: T) -> GraphResult<&mut usize>
46 where
47 T: Into<UndirectedEdge>,
48 {
49 let edge = undirected.into();
50 let index = edge_index(&edge);
51 let count = self.edges.len();
52 match self.edges.get_mut(index) {
53 Some(s) => Ok(s),
54 None => Err(GraphError::edge_out_of_range(index, count)),
55 }
56 }
57 pub fn set_edge<T>(&mut self, undirected: T, mut connection: usize) -> GraphResult<usize>
58 where
59 T: Into<UndirectedEdge>,
60 {
61 let new = &mut connection;
62 let old = self.mut_edge(undirected)?;
63 std::mem::swap(new, old);
64 Ok(*new)
65 }
66
67 pub fn connect<T>(&mut self, edge: T) -> GraphResult<usize>
68 where
69 T: Into<UndirectedEdge>,
70 {
71 let edge = self.mut_edge(edge)?;
72 *edge = edge.saturating_add(1);
73 Ok(*edge)
74 }
75 pub fn disconnect<T>(&mut self, edge: T) -> GraphResult<usize>
76 where
77 T: Into<UndirectedEdge>,
78 {
79 let edge = self.mut_edge(edge)?;
80 *edge = edge.saturating_sub(1);
81 Ok(*edge)
82 }
83}
84
85fn edge_index(edge: &UndirectedEdge) -> usize {
86 let min_index = edge.min_index();
87 let max_index = edge.max_index();
88 max_index * (max_index + 1) / 2 + min_index
89}