Skip to content

Commit

Permalink
Further documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
RaoulLuque committed Jun 27, 2024
1 parent 03e6e28 commit 925a9aa
Show file tree
Hide file tree
Showing 7 changed files with 53 additions and 27 deletions.
7 changes: 7 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,5 @@ repository = "https://github.com/RaoulLuque/treewidth-heuristic-clique-graph"
petgraph = "0.6.4"
itertools = "0.13"
rand = "0.8.5"
rustc-hash = { version ="2.0.0", git = "https://github.com/rust-lang/rustc-hash"}
rustc-hash = { version ="2.0.0", git = "https://github.com/rust-lang/rustc-hash"}
log = "0.4.21"
8 changes: 4 additions & 4 deletions src/compute_treewidth_upper_bound.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,14 @@ pub enum SpanningTreeConstructionMethod {
/// a tree decomposition.
///
/// See [TreewidthComputationMethod] for the different options of spanning tree construction.
///
///
/// Also see [edge weight functions][crate::clique_graph_edge_weight_functions] for the different
/// weight options for the edges in the clique graph.
///
/// It is possible to not use the clique graph but the clique graph with a bound on the
/// It is possible to not use the clique graph but the clique graph with a bound on the
/// size of the cliques instead. The resulting graph is the intersection graph of the set of all
/// cliques that are maximal or have a size of clique_bound
///
///
/// Can also check the tree decomposition for correctness after computation which will up to double
/// the running time. If so, will panic if the tree decomposition if incorrect returning the vertices
/// and path that is faulty.
Expand Down Expand Up @@ -79,7 +79,7 @@ pub fn compute_treewidth_upper_bound<
// .sorted()
.collect()
} else {
find_maximum_cliques::<Vec<_>, _, S>(graph)
find_maximal_cliques::<Vec<_>, _, S>(graph)
// .sorted()
.collect()
};
Expand Down
20 changes: 18 additions & 2 deletions src/fill_bags_while_generating_mst.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,15 @@ use std::{
hash::BuildHasher,
};

use log::trace;
use petgraph::{graph::NodeIndex, Graph, Undirected};

/// The function computes a [tree decomposition][https://en.wikipedia.org/wiki/Tree_decomposition]
/// with the vertices having bags (HashSets) as labels
/// given a clique graph. For this a minimum spanning tree of the clique graph is constructed using
/// prim's algorithm and the edge labels in the clique graph as edge weights. Whenever a new vertex
/// is added to the spanning tree, the bags of the current spanning tree are filled up/updated
/// according to the [tree decomposition criteria][https://en.wikipedia.org/wiki/Tree_decomposition#Definition].
pub fn fill_bags_while_generating_mst<N, E, O: Ord, S: Default + BuildHasher + Clone>(
clique_graph: &Graph<HashSet<NodeIndex, S>, O, Undirected>,
edge_weight_heuristic: fn(&HashSet<NodeIndex, S>, &HashSet<NodeIndex, S>) -> O,
Expand Down Expand Up @@ -44,7 +51,7 @@ pub fn fill_bags_while_generating_mst<N, E, O: Ord, S: Default + BuildHasher + C
while !clique_graph_remaining_vertices.is_empty() {
// DEBUG
if clique_graph_remaining_vertices.len() % 30 == 0 {
println!(
trace!(
"{} vertices remaining",
clique_graph_remaining_vertices.len()
);
Expand Down Expand Up @@ -179,6 +186,11 @@ fn fill_bags<O, S: BuildHasher>(
}
}

/// Computes a tree decomposition similar to [fill_bags_while_generating_mst] except that whenever
/// a vertex is added to the current spanning tree and the bags of the current spanning tree are
/// filled up/updated, edges to other vertices in the entire clique graph are updated (in order to
/// preserve the property that two vertices/bags in the clique graph are adjacent iff they have a
/// non-empty intersection).
pub fn fill_bags_while_generating_mst_update_edges<
N,
E,
Expand Down Expand Up @@ -315,7 +327,7 @@ fn fill_bags_from_result_graph_updating_edges<S: BuildHasher + Clone, O>(
}
}

/// Adapted from fill_bags
/// Adapted from [fill_bags]
fn fill_bags_updating_edges<O, S: BuildHasher>(
start_vertex: NodeIndex,
end_vertex: NodeIndex,
Expand Down Expand Up @@ -493,6 +505,10 @@ pub fn fill_bags_while_generating_mst_using_tree<N, E, O: Ord, S: Default + Buil
result_graph
}

/// Computes a tree decomposition similar to [fill_bags_while_generating_mst] except that instead of
/// using edge weights in prim's algorithm, the weight of an edge (u,v) (v is not yet in the
/// spanning tree) is the size of the biggest bag in the spanning tree if v was added to the
/// spanning tree and the bags were filled up/updated accordingly.
pub fn fill_bags_while_generating_mst_least_bag_size<
N,
E,
Expand Down
15 changes: 8 additions & 7 deletions src/find_maximum_cliques.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@ use std::hash::BuildHasher;
use std::iter::from_fn;
use std::{collections::HashSet, hash::Hash};

/// Returns an iterator that produces all maximum cliques in the given graph in arbitrary order.
/// Returns an iterator that produces all [maximal cliques][https://en.wikipedia.org/wiki/Clique_(graph_theory)#Definitions]
/// in the given graph in arbitrary order.
///
/// This algorithm is adapted from <https://networkx.org/documentation/stable/reference/algorithms/generated/networkx.algorithms.clique.find_cliques.html>.
pub fn find_maximum_cliques<TargetColl, G, S: Default + BuildHasher + Clone>(
/// This algorithm is adapted from [networkX find_cliques algorithm][https://networkx.org/documentation/stable/reference/algorithms/generated/networkx.algorithms.clique.find_cliques.html].
pub fn find_maximal_cliques<TargetColl, G, S: Default + BuildHasher + Clone>(
graph: G,
) -> impl Iterator<Item = TargetColl>
where
Expand Down Expand Up @@ -110,8 +111,8 @@ where
})
}

/// Returns an iterator that produces all maximum cliques with maximum size k or cliques that are
/// part of maximum cliques that are themselves bigger in size than k in arbitrary order.
/// Returns an iterator that produces (once each) all cliques that are [maximal][https://en.wikipedia.org/wiki/Clique_(graph_theory)#Definitions]
/// (and of size less than k) or of size k (and not necessarily maximal) in arbitrary order.
///
/// Uses the [find_maximum_cliques] method.
pub fn find_maximum_cliques_bounded<TargetColl, G, S: Default + Clone + BuildHasher>(
Expand All @@ -126,7 +127,7 @@ where
TargetColl: FromIterator<G::NodeId>,
<G as GraphBase>::NodeId: 'static,
{
let mut maximum_cliques = find_maximum_cliques::<HashSet<_, S>, G, S>(graph);
let mut maximum_cliques = find_maximal_cliques::<HashSet<_, S>, G, S>(graph);
let mut combinations = HashSet::<_, S>::default().into_iter().combinations(k);
let mut seen_combinations = HashSet::<_, S>::default();
from_fn(move || loop {
Expand Down Expand Up @@ -160,7 +161,7 @@ mod tests {
let test_graph = crate::tests::setup_test_graph(i);

let mut cliques: Vec<Vec<_>> =
find_maximum_cliques::<Vec<_>, _, RandomState>(&test_graph.graph).collect();
find_maximal_cliques::<Vec<_>, _, RandomState>(&test_graph.graph).collect();

for i in 0..cliques.len() {
cliques[i].sort();
Expand Down
25 changes: 13 additions & 12 deletions src/generate_partial_k_tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,18 @@ use rand::{seq::IteratorRandom, Rng};

use crate::maximum_minimum_degree_plus;

/// Generates a [k-tree](https://en.wikipedia.org/wiki/K-tree) and then randomly removes p percent of the edges
/// to get a [partial k-tree](https://en.wikipedia.org/wiki/Partial_k-tree). To guarantee a treewidth of k,
/// this procedure is repeated until the treewidth of the graph is at least k according to the minimum
/// maximum degree heuristic.
/// Generates a [k-tree](https://en.wikipedia.org/wiki/K-tree) and then randomly removes p percent
/// of the edges to get a [partial k-tree](https://en.wikipedia.org/wiki/Partial_k-tree). To
/// guarantee a treewidth of k, this procedure is repeated until the treewidth of the graph is at
/// least k according to the minimum maximum degree heuristic.
///
/// **Caution!**: Due to the randomness involved, this function could in theory take indefinitely to generate
/// a partial k-tree with the wished treewidth.
/// **Caution!**: Due to the randomness involved, this function could in theory take
/// indefinitely to generate a partial k-tree with the desired treewidth.
///
/// If p > 100 all edges will be removed. The Rng is passed in to increase performance when calling the function multiple times in a row.
/// If p > 100 all edges will be removed. The Rng is passed in to increase performance when
/// calling the function multiple times in a row.
///
/// Returns None if k > n
/// Returns None if k > n.
pub fn generate_partial_k_tree_with_guaranteed_treewidth(
k: usize,
n: usize,
Expand All @@ -37,10 +38,10 @@ pub fn generate_partial_k_tree_with_guaranteed_treewidth(
/// If p > 100 all edges will be removed. The Rng is passed in to increase performance when calling
/// the function multiple times in a row.
///
/// Returns None if k > n
/// Returns None if k > n.
///
/// The number of edges in a k_tree are k * (k - 1) / 2 + k * (n - k). So the number of removed edges in a
/// partial_k_tree will be (k * (k - 1) / 2 + k * (n - k)) * p / 100 rounded down
/// The number of edges in a k_tree are k * (k - 1) / 2 + k * (n - k). So the number of removed
/// edges in a partial_k_tree will be (k * (k - 1) / 2 + k * (n - k)) * p / 100 rounded down.
pub fn generate_partial_k_tree(
k: usize,
n: usize,
Expand All @@ -67,7 +68,7 @@ pub fn generate_partial_k_tree(
}

/// Generates a [k-tree](https://en.wikipedia.org/wiki/K-tree) with n vertices and k in the definition.
/// Returns None if k > n
/// Returns None if k > n.
pub fn generate_k_tree(k: usize, n: usize) -> Option<Graph<i32, i32, Undirected>> {
if k > n {
None
Expand Down
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ pub(crate) use fill_bags_while_generating_mst::{
fill_bags_while_generating_mst_update_edges, fill_bags_while_generating_mst_using_tree,
};
pub(crate) use find_connected_components::find_connected_components;
pub(crate) use find_maximum_cliques::{find_maximum_cliques, find_maximum_cliques_bounded};
pub(crate) use find_maximum_cliques::{find_maximal_cliques, find_maximum_cliques_bounded};
pub(crate) use find_width_of_tree_decomposition::find_width_of_tree_decomposition;
pub use generate_partial_k_tree::{
generate_k_tree, generate_partial_k_tree, generate_partial_k_tree_with_guaranteed_treewidth,
Expand Down

0 comments on commit 925a9aa

Please sign in to comment.