graph_algo_ptas/algorithm/dynamic_programming/
max_independent_set.rs1use super::{
2 solve::{DpTable, DpTableEntry},
3 utils::{bit_vec_powerset, immutable_bit_vec_update, init_bit_vec, to_bit_vec},
4};
5use arboretum_td::graph::{BaseGraph, HashMapGraph};
6use fxhash::FxHashSet;
7use itertools::Itertools;
8
9pub fn handle_leaf_node(graph: &HashMapGraph, id: usize, tables: &mut [DpTable], vertex: usize) {
10 tables[id].insert(init_bit_vec(graph.order()), DpTableEntry::new_leaf(0, None));
11 tables[id].insert(
12 immutable_bit_vec_update(&init_bit_vec(graph.order()), vertex),
13 DpTableEntry::new_leaf(1, Some(vertex)),
14 );
15}
16
17pub fn handle_join_node(
18 graph: &HashMapGraph,
19 id: usize,
20 left_child_id: usize,
21 right_child_id: usize,
22 tables: &mut [DpTable],
23 vertex_set: &FxHashSet<usize>,
24) {
25 for subset_vec in vertex_set.iter().powerset() {
26 let subset = to_bit_vec(subset_vec.iter().copied(), graph.order());
27 let left_val = tables[left_child_id].get(&subset).unwrap().val;
28 let right_val = tables[right_child_id].get(&subset).unwrap().val;
29 let new_val = if left_val == i32::min_value() || right_val == i32::min_value() {
30 i32::min_value()
31 } else {
32 left_val + right_val - subset_vec.len() as i32
33 };
34
35 tables[id].insert(
36 subset.clone(),
37 DpTableEntry::new_join(new_val, left_child_id, right_child_id, subset),
38 );
39 }
40}
41
42pub fn handle_forget_node(
43 graph: &HashMapGraph,
44 id: usize,
45 child_id: usize,
46 tables: &mut [DpTable],
47 vertex_set: &FxHashSet<usize>,
48 forgotten_vertex: usize,
49) {
50 for subset in bit_vec_powerset(vertex_set, graph.order()) {
51 let val = tables[child_id].get(&subset).unwrap().val;
52 let subset_with_v = immutable_bit_vec_update(&subset, forgotten_vertex);
53 let val_with_v = tables[child_id].get(&subset_with_v).unwrap().val;
54 let (new_val, subset_used) = if val > val_with_v {
55 (val, subset.clone())
56 } else {
57 (val_with_v, subset_with_v)
58 };
59 tables[id].insert(
60 subset,
61 DpTableEntry::new_forget(new_val, child_id, subset_used),
62 );
63 }
64}
65
66pub fn handle_introduce_node(
67 graph: &HashMapGraph,
68 id: usize,
69 child_id: usize,
70 tables: &mut [DpTable],
71 _: &FxHashSet<usize>,
72 child_vertex_set: &FxHashSet<usize>,
73 introduced_vertex: usize,
74) {
75 for subset_vec in child_vertex_set.iter().powerset() {
76 let subset = to_bit_vec(subset_vec.iter().copied(), graph.order());
77 let val = tables[child_id].get(&subset).unwrap().val;
78 tables[id].insert(
79 subset.clone(),
80 DpTableEntry::new_intro(val, child_id, subset.clone(), None),
81 );
82
83 let has_edge = subset_vec
84 .iter()
85 .any(|w| graph.has_edge(introduced_vertex, **w));
86
87 let (new_val, node_used) = if has_edge {
88 (i32::min_value(), None)
89 } else {
90 (
91 if val == i32::min_value() {
92 i32::min_value()
93 } else {
94 val + 1
95 },
96 Some(introduced_vertex),
97 )
98 };
99 let subset_with_v = immutable_bit_vec_update(&subset, introduced_vertex);
100 tables[id].insert(
101 subset_with_v,
102 DpTableEntry::new_intro(new_val, child_id, subset, node_used),
103 );
104 }
105}