#![allow(dead_code)]
use itertools::Itertools;
pub fn index_to_edge(index: usize, n: usize) -> (usize, usize) {
let mut sum = 0;
let mut i = 0;
while sum + (n - i - 1) <= index {
sum += n - i - 1;
i += 1;
}
let j = index - sum + i + 1;
(i, j)
}
pub fn is_connected(v: &[bool], n: usize, u: usize, w: usize) -> bool {
if u == w {
return false; }
let (min_node, max_node) = if u < w { (u, w) } else { (w, u) };
let offset = (2 * n - min_node - 1) * min_node / 2;
let index = offset + (max_node - min_node - 1);
if index < v.len() {
v[index]
} else {
false
}
}
pub fn is_clique(v: &[bool], n: usize, nodes: &[usize]) -> bool {
for i in 0..nodes.len() {
for j in i + 1..nodes.len() {
if !is_connected(v, n, nodes[i], nodes[j]) {
return false;
}
}
}
true
}
pub fn find_clique(v: &[bool], n: usize, k: usize) -> Option<Vec<usize>> {
if k == 1 {
return Some(vec![0]);
}
if k == n {
if is_clique(v, n, &(0..n).collect::<Vec<_>>()) {
return Some((0..n).collect());
} else {
return None;
}
}
(0..n).combinations(k).find(|nodes| is_clique(v, n, nodes))
}
pub fn clique(v: &[bool], n: usize, k: usize) -> bool {
(k..n + 1).any(|i| find_clique(v, n, i).is_some())
}
pub fn generate_random_graph(n: usize, density: f64) -> Vec<bool> {
use rand::random;
let edges_count = n * (n - 1) / 2;
let mut edges = Vec::with_capacity(edges_count);
for _ in 0..edges_count {
edges.push(random::<f64>() < density);
}
edges
}
pub fn print_graph(v: &[bool], n: usize) {
println!("Matriz de adyacencia:");
for i in 0..n {
for j in 0..n {
if i == j {
print!("0 ");
} else {
let connected = is_connected(v, n, i, j);
print!("{} ", if connected { "1" } else { "0" });
}
}
println!();
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_index_to_edge() {
assert_eq!(index_to_edge(0, 4), (0, 1)); assert_eq!(index_to_edge(1, 4), (0, 2)); assert_eq!(index_to_edge(2, 4), (0, 3)); assert_eq!(index_to_edge(3, 4), (1, 2)); assert_eq!(index_to_edge(4, 4), (1, 3)); assert_eq!(index_to_edge(5, 4), (2, 3)); }
#[test]
fn test_is_connected() {
let n = 4;
let v = vec![true, false, true, true, false, true];
assert!(is_connected(&v, n, 0, 1)); assert!(!is_connected(&v, n, 0, 2)); assert!(is_connected(&v, n, 0, 3)); assert!(is_connected(&v, n, 1, 2)); assert!(!is_connected(&v, n, 1, 3)); assert!(is_connected(&v, n, 2, 3)); }
#[test]
fn test_is_clique() {
let n = 4;
let v = vec![true, false, true, true, false, true];
assert!(!is_clique(&v, n, &[0, 1, 2]));
assert!(!is_clique(&v, n, &[0, 1, 3]));
assert!(!is_clique(&v, n, &[0, 3, 2]));
assert!(!is_clique(&v, n, &[1, 2, 3]));
assert!(is_clique(&v, n, &[0, 1]));
assert!(is_clique(&v, n, &[1, 2]));
}
}