implemented dfs
it's way faster now
This commit is contained in:
parent
11f90b5cc8
commit
8962baadf9
142
src/graph.rs
142
src/graph.rs
@ -1,18 +1,20 @@
|
||||
use self::matrix::clone;
|
||||
use matrix::{clone, dfs_bridges, mult};
|
||||
|
||||
use self::matrix::dfs_articulations;
|
||||
|
||||
pub mod matrix;
|
||||
|
||||
pub fn calculate_distanz_matrix(adjazenz_matrix: &Vec<Vec<u8>>) -> Vec<Vec<u8>> {
|
||||
let mut distanz_matrix: Vec<Vec<u8>> = vec![vec![]; adjazenz_matrix.len()];
|
||||
pub fn calculate_distanz_matrix(adjazenz_matrix: &Vec<Vec<usize>>) -> Vec<Vec<usize>> {
|
||||
let mut distanz_matrix: Vec<Vec<usize>> = vec![vec![]; adjazenz_matrix.len()];
|
||||
let mut potenz_matrix = clone(adjazenz_matrix);
|
||||
|
||||
for k in 1..(adjazenz_matrix.len() + 1) {
|
||||
potenz_matrix = matrix::mult(&potenz_matrix, adjazenz_matrix);
|
||||
for k in 1..=adjazenz_matrix.len() {
|
||||
potenz_matrix = mult(&potenz_matrix, adjazenz_matrix);
|
||||
for i in 0..adjazenz_matrix.len() {
|
||||
for j in 0..adjazenz_matrix.len() {
|
||||
if k != 1 {
|
||||
if potenz_matrix[i][j] != 0 && distanz_matrix[i][j] == u8::MAX {
|
||||
distanz_matrix[i][j] = u8::try_from(k).unwrap();
|
||||
if potenz_matrix[i][j] != 0 && distanz_matrix[i][j] == usize::MAX {
|
||||
distanz_matrix[i][j] = k;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
@ -21,7 +23,7 @@ pub fn calculate_distanz_matrix(adjazenz_matrix: &Vec<Vec<u8>>) -> Vec<Vec<u8>>
|
||||
} else if adjazenz_matrix[i][j] == 1 {
|
||||
distanz_matrix[i].push(1);
|
||||
} else {
|
||||
distanz_matrix[i].push(u8::MAX);
|
||||
distanz_matrix[i].push(usize::MAX);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -29,12 +31,12 @@ pub fn calculate_distanz_matrix(adjazenz_matrix: &Vec<Vec<u8>>) -> Vec<Vec<u8>>
|
||||
distanz_matrix
|
||||
}
|
||||
|
||||
pub fn calculate_weg_matrix(adjazenz_matrix: &Vec<Vec<u8>>) -> Vec<Vec<u8>> {
|
||||
let mut weg_matrix: Vec<Vec<u8>> = vec![vec![]; adjazenz_matrix.len()];
|
||||
pub fn calculate_weg_matrix(adjazenz_matrix: &Vec<Vec<usize>>) -> Vec<Vec<usize>> {
|
||||
let mut weg_matrix: Vec<Vec<usize>> = vec![vec![]; adjazenz_matrix.len()];
|
||||
let mut potenz_matrix = clone(adjazenz_matrix);
|
||||
|
||||
for k in 1..(adjazenz_matrix.len() + 1) {
|
||||
potenz_matrix = matrix::mult(&potenz_matrix, adjazenz_matrix);
|
||||
for k in 1..=adjazenz_matrix.len() {
|
||||
potenz_matrix = mult(&potenz_matrix, adjazenz_matrix);
|
||||
for i in 0..adjazenz_matrix.len() {
|
||||
for j in 0..adjazenz_matrix.len() {
|
||||
if k != 1 {
|
||||
@ -54,15 +56,15 @@ pub fn calculate_weg_matrix(adjazenz_matrix: &Vec<Vec<u8>>) -> Vec<Vec<u8>> {
|
||||
weg_matrix
|
||||
}
|
||||
|
||||
pub fn calculate_exzentrizitaeten(distanz_matrix: Vec<Vec<u8>>) -> Vec<u8> {
|
||||
let mut exzentrizitaeten: Vec<u8> = vec![];
|
||||
let mut exzentrizitaet: u8;
|
||||
pub fn calculate_exzentrizitaeten(distanz_matrix: Vec<Vec<usize>>) -> Vec<usize> {
|
||||
let mut exzentrizitaeten = vec![];
|
||||
let mut exzentrizitaet: usize;
|
||||
|
||||
for vector in distanz_matrix {
|
||||
exzentrizitaet = 0;
|
||||
|
||||
for value in vector {
|
||||
if value == u8::MAX {
|
||||
if value == usize::MAX {
|
||||
continue;
|
||||
}
|
||||
exzentrizitaet = exzentrizitaet.max(value);
|
||||
@ -72,23 +74,23 @@ pub fn calculate_exzentrizitaeten(distanz_matrix: Vec<Vec<u8>>) -> Vec<u8> {
|
||||
exzentrizitaeten
|
||||
}
|
||||
|
||||
pub fn calculate_properties(exzentrizitaeten: &[u8]) -> (u8, u8, Vec<u8>, bool) {
|
||||
let mut radius = u8::MAX;
|
||||
let mut diameter: u8 = 0;
|
||||
let mut centre: Vec<u8> = vec![];
|
||||
let mut connected: bool = true;
|
||||
pub fn calculate_properties(exzentrizitaeten: &[usize]) -> (usize, usize, Vec<usize>, bool) {
|
||||
let mut radius = usize::MAX;
|
||||
let mut diameter = 0;
|
||||
let mut centre = vec![];
|
||||
let mut connected = true;
|
||||
|
||||
for (index, value) in exzentrizitaeten.iter().enumerate() {
|
||||
if value > &diameter {
|
||||
diameter = *value;
|
||||
}
|
||||
if value == &radius {
|
||||
centre.push(u8::try_from(index + 1).unwrap());
|
||||
centre.push(index + 1);
|
||||
}
|
||||
if value < &radius {
|
||||
radius = *value;
|
||||
centre.clear();
|
||||
centre.push(u8::try_from(index + 1).unwrap());
|
||||
centre.push(index + 1);
|
||||
}
|
||||
if value == &0 {
|
||||
connected = false;
|
||||
@ -97,15 +99,15 @@ pub fn calculate_properties(exzentrizitaeten: &[u8]) -> (u8, u8, Vec<u8>, bool)
|
||||
(radius, diameter, centre, connected)
|
||||
}
|
||||
|
||||
pub fn find_components(weg_matrix: Vec<Vec<u8>>) -> Vec<Vec<u8>> {
|
||||
let mut components: Vec<Vec<u8>> = vec![];
|
||||
let mut component: Vec<u8>;
|
||||
pub fn find_components(weg_matrix: Vec<Vec<usize>>) -> Vec<Vec<usize>> {
|
||||
let mut components: Vec<Vec<usize>> = vec![];
|
||||
let mut component: Vec<usize>;
|
||||
|
||||
for array in weg_matrix {
|
||||
component = vec![];
|
||||
for (index, value) in array.iter().enumerate() {
|
||||
if value == &1 {
|
||||
component.push(u8::try_from(index + 1).unwrap());
|
||||
component.push(index + 1);
|
||||
}
|
||||
}
|
||||
if !components.contains(&component) {
|
||||
@ -115,46 +117,56 @@ pub fn find_components(weg_matrix: Vec<Vec<u8>>) -> Vec<Vec<u8>> {
|
||||
components
|
||||
}
|
||||
|
||||
pub fn find_articulations_and_bridges(
|
||||
adjazenz_matrix: &mut Vec<Vec<u8>>,
|
||||
components: &Vec<Vec<u8>>,
|
||||
) -> (Vec<u8>, Vec<Vec<u8>>) {
|
||||
let mut bridges: Vec<Vec<u8>> = vec![];
|
||||
let mut articulations: Vec<u8> = vec![];
|
||||
let mut temp_matrix = adjazenz_matrix.clone();
|
||||
pub fn find_bridges(adjazenz_matrix: &Vec<Vec<usize>>) -> Vec<Vec<usize>> {
|
||||
let size = adjazenz_matrix.len();
|
||||
let mut bridges: Vec<Vec<usize>> = vec![];
|
||||
let mut visited = vec![false; size];
|
||||
let mut discovery_time = vec![0; size];
|
||||
let mut low_time = vec![0; size];
|
||||
let time = 0;
|
||||
|
||||
for n in 0..temp_matrix.len() {
|
||||
for i in 0..temp_matrix.len() {
|
||||
for j in 0..temp_matrix.len() {
|
||||
temp_matrix[i][n] = 0;
|
||||
temp_matrix[n][j] = 0;
|
||||
|
||||
if n != 0 {
|
||||
continue;
|
||||
}
|
||||
let bridge = vec![
|
||||
u8::try_from(usize::min(i + 1, j + 1)).unwrap(),
|
||||
u8::try_from(usize::max(i + 1, j + 1)).unwrap(),
|
||||
];
|
||||
let prev_value = adjazenz_matrix[i][j];
|
||||
adjazenz_matrix[i][j] = 0;
|
||||
adjazenz_matrix[j][i] = 0;
|
||||
|
||||
if find_components(calculate_weg_matrix(adjazenz_matrix)).len() > components.len()
|
||||
&& !bridges.contains(&bridge)
|
||||
{
|
||||
bridges.push(bridge);
|
||||
}
|
||||
adjazenz_matrix[i][j] = prev_value;
|
||||
adjazenz_matrix[j][i] = prev_value;
|
||||
}
|
||||
for i in 0..size {
|
||||
if !visited[i] {
|
||||
dfs_bridges(
|
||||
&mut bridges,
|
||||
adjazenz_matrix,
|
||||
&mut visited,
|
||||
&mut discovery_time,
|
||||
&mut low_time,
|
||||
time,
|
||||
i,
|
||||
usize::MAX,
|
||||
);
|
||||
}
|
||||
|
||||
if find_components(calculate_weg_matrix(&temp_matrix)).len() > (components.len() + 1) {
|
||||
articulations.push(u8::try_from(n + 1).unwrap());
|
||||
}
|
||||
temp_matrix = adjazenz_matrix.clone();
|
||||
}
|
||||
|
||||
(articulations, bridges)
|
||||
bridges
|
||||
}
|
||||
|
||||
pub fn find_articulations(adjazenz_matrix: &Vec<Vec<usize>>) -> Vec<usize> {
|
||||
let size = adjazenz_matrix.len();
|
||||
let mut ariculations = vec![];
|
||||
let mut is_articulation = vec![false; size];
|
||||
let mut visited = vec![false; size];
|
||||
let mut discovery_time = vec![0; size];
|
||||
let mut low_time = vec![0; size];
|
||||
let time = 0;
|
||||
|
||||
for i in 0..size {
|
||||
if !visited[i] {
|
||||
dfs_articulations(
|
||||
&mut ariculations,
|
||||
&mut is_articulation,
|
||||
adjazenz_matrix,
|
||||
&mut visited,
|
||||
&mut discovery_time,
|
||||
&mut low_time,
|
||||
time,
|
||||
i,
|
||||
usize::MAX,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
ariculations
|
||||
}
|
||||
|
@ -1,33 +1,26 @@
|
||||
use csv::ReaderBuilder;
|
||||
pub fn fill_with_random(size: usize) -> Vec<Vec<usize>> {
|
||||
let mut matrix = vec![vec![0; size]; size];
|
||||
let mut random_value: usize;
|
||||
|
||||
pub fn fill_with_random(size: usize) -> Vec<Vec<u8>> {
|
||||
assert!(
|
||||
(size < u8::MAX.into() && size > 0),
|
||||
"fill_with_random: size must not be bigger than 255 or smaller than 1, size was: {size}"
|
||||
);
|
||||
|
||||
let mut matrix: Vec<Vec<u8>> = vec![];
|
||||
for i in 0..size {
|
||||
matrix.push(vec![]);
|
||||
for j in 0..size {
|
||||
if i == j {
|
||||
matrix[i].push(0);
|
||||
continue;
|
||||
}
|
||||
matrix[i].push(fastrand::u8(0..2));
|
||||
random_value = fastrand::usize(0..=1);
|
||||
matrix[i][j] = random_value;
|
||||
matrix[j][i] = random_value;
|
||||
matrix[i][i] = 0;
|
||||
}
|
||||
}
|
||||
matrix
|
||||
}
|
||||
|
||||
pub fn mult(matrix1: &Vec<Vec<usize>>, matrix2: &Vec<Vec<u8>>) -> Vec<Vec<usize>> {
|
||||
let mut product: Vec<Vec<usize>> = vec![vec![]; matrix2.len()];
|
||||
pub fn mult(matrix1: &Vec<Vec<usize>>, matrix2: &Vec<Vec<usize>>) -> Vec<Vec<usize>> {
|
||||
let mut product = vec![vec![]; matrix2.len()];
|
||||
let mut vector: Vec<usize>;
|
||||
|
||||
for (index, k) in (0..matrix1.len()).enumerate() {
|
||||
vector = vec![];
|
||||
for array in matrix2 {
|
||||
vector.push(array[index].into());
|
||||
vector.push(array[index]);
|
||||
}
|
||||
for array in matrix1 {
|
||||
product[k].push(array.iter().zip(vector.iter()).map(|(x, y)| x * y).sum());
|
||||
@ -36,20 +29,115 @@ pub fn mult(matrix1: &Vec<Vec<usize>>, matrix2: &Vec<Vec<u8>>) -> Vec<Vec<usize>
|
||||
product
|
||||
}
|
||||
|
||||
pub fn clone(matrix: &Vec<Vec<u8>>) -> Vec<Vec<usize>> {
|
||||
pub fn dfs_bridges(
|
||||
bridges: &mut Vec<Vec<usize>>,
|
||||
adjazenz_matrix: &Vec<Vec<usize>>,
|
||||
visited: &mut Vec<bool>,
|
||||
discovery_time: &mut Vec<usize>,
|
||||
low_time: &mut Vec<usize>,
|
||||
time: usize,
|
||||
vertex: usize,
|
||||
parent: usize,
|
||||
) {
|
||||
let time = time + 1;
|
||||
visited[vertex] = true;
|
||||
discovery_time[vertex] = time;
|
||||
low_time[vertex] = time;
|
||||
|
||||
for neighbor in 0..adjazenz_matrix.len() {
|
||||
if adjazenz_matrix[vertex][neighbor] != 1 || visited[neighbor] {
|
||||
continue;
|
||||
}
|
||||
if neighbor != parent {
|
||||
low_time[vertex] = usize::min(low_time[vertex], discovery_time[neighbor]);
|
||||
}
|
||||
|
||||
dfs_bridges(
|
||||
bridges,
|
||||
adjazenz_matrix,
|
||||
visited,
|
||||
discovery_time,
|
||||
low_time,
|
||||
time,
|
||||
neighbor,
|
||||
vertex,
|
||||
);
|
||||
|
||||
low_time[vertex] = usize::min(low_time[vertex], low_time[neighbor]);
|
||||
|
||||
if discovery_time[vertex] < low_time[neighbor] {
|
||||
bridges.push(vec![vertex + 1, neighbor + 1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn dfs_articulations(
|
||||
articulations: &mut Vec<usize>,
|
||||
is_articulation: &mut Vec<bool>,
|
||||
adjazenz_matrix: &Vec<Vec<usize>>,
|
||||
visited: &mut Vec<bool>,
|
||||
discovery_time: &mut Vec<usize>,
|
||||
low_time: &mut Vec<usize>,
|
||||
time: usize,
|
||||
vertex: usize,
|
||||
parent: usize,
|
||||
) {
|
||||
let time = time + 1;
|
||||
visited[vertex] = true;
|
||||
discovery_time[vertex] = time;
|
||||
low_time[vertex] = time;
|
||||
let mut child_count: usize = 0;
|
||||
let mut articulation = false;
|
||||
|
||||
for neighbor in 0..adjazenz_matrix.len() {
|
||||
if visited[neighbor] || neighbor == parent || parent == usize::MAX {
|
||||
continue;
|
||||
}
|
||||
|
||||
child_count += 1;
|
||||
dfs_articulations(
|
||||
articulations,
|
||||
is_articulation,
|
||||
adjazenz_matrix,
|
||||
visited,
|
||||
discovery_time,
|
||||
low_time,
|
||||
time,
|
||||
vertex,
|
||||
parent,
|
||||
);
|
||||
|
||||
low_time[vertex] = usize::min(low_time[vertex], low_time[neighbor]);
|
||||
|
||||
if discovery_time[vertex] <= low_time[neighbor] {
|
||||
articulation = true;
|
||||
}
|
||||
}
|
||||
|
||||
if parent != usize::MAX && child_count > 1 {
|
||||
articulation = true;
|
||||
}
|
||||
|
||||
if articulation {
|
||||
is_articulation[vertex] = true;
|
||||
articulations.push(vertex + 1);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn clone(matrix: &Vec<Vec<usize>>) -> Vec<Vec<usize>> {
|
||||
let mut new_matrix: Vec<Vec<usize>> = vec![];
|
||||
|
||||
for i in 0..matrix.len() {
|
||||
new_matrix.push(vec![]);
|
||||
for j in 0..matrix.len() {
|
||||
new_matrix[i].push(matrix[i][j].into());
|
||||
new_matrix[i].push(matrix[i][j]);
|
||||
}
|
||||
}
|
||||
|
||||
new_matrix
|
||||
}
|
||||
|
||||
pub fn show(matrix: &Vec<Vec<u8>>) {
|
||||
pub fn show(matrix: &Vec<Vec<usize>>) {
|
||||
for vector in matrix {
|
||||
for value in vector {
|
||||
print!("{value} ");
|
||||
@ -58,10 +146,10 @@ pub fn show(matrix: &Vec<Vec<u8>>) {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn read_csv(file_name: &str) -> Vec<Vec<u8>> {
|
||||
let mut matrix: Vec<Vec<u8>> = vec![];
|
||||
pub fn read_csv(file_name: &str) -> Vec<Vec<usize>> {
|
||||
let mut matrix: Vec<Vec<usize>> = vec![];
|
||||
let dir: String = "/home/rene/projects/Java/graphprogram/csv/".into();
|
||||
let mut csv = ReaderBuilder::new()
|
||||
let mut csv = csv::ReaderBuilder::new()
|
||||
.has_headers(false)
|
||||
.delimiter(b';')
|
||||
.from_path(dir + file_name)
|
||||
|
@ -6,7 +6,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn graph() {
|
||||
let mut adjazenz_matrix = read_csv("art-brck.csv");
|
||||
let adjazenz_matrix = read_csv("art-brck.csv");
|
||||
let distanz_matrix = calculate_distanz_matrix(&adjazenz_matrix);
|
||||
let weg_matrix = calculate_weg_matrix(&adjazenz_matrix);
|
||||
|
||||
@ -44,7 +44,8 @@ mod tests {
|
||||
let exzentrizitaeten = calculate_exzentrizitaeten(distanz_matrix);
|
||||
let properties = calculate_properties(&exzentrizitaeten);
|
||||
let components = find_components(weg_matrix);
|
||||
let result = find_articulations_and_bridges(&mut adjazenz_matrix, &components);
|
||||
let bridges = find_bridges(&adjazenz_matrix);
|
||||
let articulations = find_articulations(&adjazenz_matrix);
|
||||
|
||||
assert_eq!(exzentrizitaeten, vec![2, 2, 2, 1, 2]);
|
||||
assert_eq!(properties.0, 1);
|
||||
@ -52,8 +53,8 @@ mod tests {
|
||||
assert_eq!(properties.2, vec![4]);
|
||||
assert_eq!(properties.3, true);
|
||||
assert_eq!(components, vec![vec![1, 2, 3, 4, 5]]);
|
||||
assert_eq!(result.1, vec![vec![4, 5]]);
|
||||
assert_eq!(result.0, vec![4]);
|
||||
assert_eq!(bridges, vec![vec![4, 5]]);
|
||||
assert_eq!(articulations, vec![4]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
13
src/main.rs
13
src/main.rs
@ -7,13 +7,13 @@ use crate::graph::{
|
||||
pub mod graph;
|
||||
|
||||
pub fn main() {
|
||||
//let file_name = "50n.csv";
|
||||
//let mut adjazenz_matrix = read_csv(file_name);
|
||||
let mut adjazenz_matrix = fill_with_random(1); // with 48 verteces, it runs in about 10.2 seconds (run on the 2023-06-03 at 12:36)
|
||||
let file_name = "24n.csv";
|
||||
let adjazenz_matrix = read_csv(file_name);
|
||||
//let adjazenz_matrix = fill_with_random(320); // with 320 verteces, it runs in about 10 seconds on an Intel i5-10300H @4.3 GHz (2023-06-05 15:48)
|
||||
let distanz_matrix = calculate_distanz_matrix(&adjazenz_matrix);
|
||||
let weg_matrix = calculate_weg_matrix(&adjazenz_matrix);
|
||||
|
||||
println!("adjazen matrix:");
|
||||
println!("adjazenz matrix:");
|
||||
show(&adjazenz_matrix);
|
||||
println!("\ndistanz matrix:");
|
||||
show(&distanz_matrix);
|
||||
@ -37,7 +37,6 @@ pub fn main() {
|
||||
let components = find_components(weg_matrix);
|
||||
println!("components: {components:?}");
|
||||
|
||||
let result = find_articulations_and_bridges(&mut adjazenz_matrix, &components);
|
||||
println!("bridges: {:?}", result.1);
|
||||
println!("articulations: {:?}", result.0);
|
||||
println!("bridges: {:?}", find_bridges(&adjazenz_matrix));
|
||||
println!("articulations: {:?}", find_articulations(&adjazenz_matrix));
|
||||
}
|
||||
|
Reference in New Issue
Block a user