Skip to content

Commit

Permalink
Added option to log maximum bag size over time while spanning tree co…
Browse files Browse the repository at this point in the history
…nstruction using fill whilst as tree construction method.
  • Loading branch information
RaoulLuque committed Jul 25, 2024
1 parent 0c796a8 commit 7939980
Show file tree
Hide file tree
Showing 4 changed files with 168 additions and 23 deletions.
95 changes: 95 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 @@ -12,4 +12,5 @@ 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"}
log = "0.4.21"
log = "0.4.21"
csv = "1.3.0"
26 changes: 25 additions & 1 deletion src/compute_treewidth_upper_bound.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,13 @@ use find_width_of_tree_decomposition::find_width_of_tree_decomposition;
/// MSTAndUseTreeStructure Constructs a minimum spanning tree of the clique graph and fills up the
/// bags afterwards trying to speed up filling up by using the tree structure
///
/// FillWhilstMST Fill bags while constructing a spanning tree minimizing according to the edge
/// FillWhilstMST Fills bags while constructing a spanning tree minimizing according to the edge
/// heuristic
///
/// FillWhilstMSTAndLogBagSize Does the same computation as FillWhilstMST however tracks the size of the
/// biggest bag every time a new vertex is added to the current spanning tree. The file
/// k-tree-benchmarks/benchmark_results/k_tree_maximum_bag_size_over_time.csv (where k-tree-benchmarks
/// is a subdirectory of the runtime directory) otherwise this option will panic.
///
/// FillWhilstMSTEdgeUpdate Fill bags while constructing a spanning tree minimizing according to
/// the edge heuristic. Updating adjacencies in clique graph according to bag updates
Expand All @@ -35,6 +40,7 @@ pub enum SpanningTreeConstructionMethod {
MSTAndFill,
MSTAndUseTreeStructure,
FillWhilstMST,
FillWhilstMSTAndLogBagSize,
FillWhilstMSTEdgeUpdate,
FillWhilstMSTTree,
FillWhilstMSTBagSize,
Expand Down Expand Up @@ -175,6 +181,24 @@ pub fn compute_treewidth_upper_bound<
&clique_graph,
edge_weight_function,
clique_graph_map,
false,
);

(clique_graph_tree, None, None, None, clique_graph)
}
SpanningTreeConstructionMethod::FillWhilstMSTAndLogBagSize => {
let (clique_graph, clique_graph_map) =
construct_clique_graph_with_bags(cliques, edge_weight_function);

let clique_graph_tree: Graph<
std::collections::HashSet<petgraph::prelude::NodeIndex, S>,
O,
petgraph::prelude::Undirected,
> = fill_bags_while_generating_mst::<N, E, O, S>(
&clique_graph,
edge_weight_function,
clique_graph_map,
true,
);

(clique_graph_tree, None, None, None, clique_graph)
Expand Down
67 changes: 46 additions & 21 deletions src/fill_bags_while_generating_mst.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use csv::WriterBuilder;
use log::trace;
use petgraph::{graph::NodeIndex, Graph, Undirected};
use std::fs::File;
use std::{
collections::{HashMap, HashSet},
hash::BuildHasher,
Expand All @@ -11,11 +13,22 @@ use std::{
/// 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].
///
/// **Panics**
/// The log_bag_size parameter enables logging of the increase in size of the biggest bag of the spanning
/// tree over time while the spanning tree is constructed (i.e. for each new vertex added to the spanning
/// tree, logs the current size of the biggest bag). If log_bag_size == true the file
/// k-tree-benchmarks/benchmark_results/k_tree_maximum_bag_size_over_time.csv (where k-tree-benchmarks
/// is a subdirectory of the runtime directory) has to exist otherwise this function will panic.
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,
clique_graph_map: HashMap<NodeIndex, HashSet<NodeIndex, S>, S>,
log_bag_size: bool,
) -> Graph<HashSet<NodeIndex, S>, O, Undirected> {
// For logging the size of the maximum bags. Stays empty if log_bag_size == False
let mut vector_for_logging = Vec::new();

let mut result_graph: Graph<HashSet<NodeIndex, S>, O, Undirected> = Graph::new_undirected();
// Maps the vertex indices from the clique graph to the corresponding vertex indices in the result graph
let mut node_index_map: HashMap<NodeIndex, NodeIndex, S> = Default::default();
Expand Down Expand Up @@ -45,29 +58,16 @@ pub fn fill_bags_while_generating_mst<N, E, O: Ord, S: Default + BuildHasher + C
}
node_index_map.insert(first_vertex_clique, first_vertex_res);

let mut current_treewidth = 0;
// Log current maximum bag size
if log_bag_size {
vector_for_logging.push(
crate::find_width_of_tree_decomposition::find_width_of_tree_decomposition(
&result_graph,
),
);
}

while !clique_graph_remaining_vertices.is_empty() {
// DEBUG
if clique_graph_remaining_vertices.len() % 30 == 0 {
trace!(
"{} vertices remaining",
clique_graph_remaining_vertices.len()
);
}

if current_treewidth
!= crate::find_width_of_tree_decomposition::find_width_of_tree_decomposition(
&result_graph,
)
{
current_treewidth =
crate::find_width_of_tree_decomposition::find_width_of_tree_decomposition(
&result_graph,
);
// DEBUG
// println!("Max bagsize increased to: {}", current_treewidth + 1);
}
// The cheapest_old_vertex_res is one of the vertices from the already constructed tree that the new vertex
// is being attached to
// The cheapest_new_vertex_clique is the new vertex that is being added to the tree. The NodeIndex corresponds
Expand Down Expand Up @@ -119,6 +119,31 @@ pub fn fill_bags_while_generating_mst<N, E, O: Ord, S: Default + BuildHasher + C
&clique_graph_map,
&node_index_map,
);

// Log current maximum bag size
vector_for_logging.push(
crate::find_width_of_tree_decomposition::find_width_of_tree_decomposition(
&result_graph,
),
);
}

// Log bag size if log_bag_size == true
if log_bag_size {
let file = std::fs::OpenOptions::new()
.write(true)
.append(true)
.open("k-tree-benchmarks/benchmark_results/k_tree_maximum_bag_size_over_time.csv")
.unwrap();

let mut writer = WriterBuilder::new().flexible(false).from_writer(file);
let vector_for_logging = vector_for_logging.into_iter().map(|v| v.to_string());
writer
.write_record(vector_for_logging)
.expect("Writing to logs for maximum bag size for fill while should be possible");
writer
.flush()
.expect("Flushing logs for maximum bag size for fill while should be possible");
}

result_graph
Expand Down

0 comments on commit 7939980

Please sign in to comment.