problemreductions/rules/
bmf_bicliquecover.rs1use crate::models::algebraic::BMF;
18use crate::models::graph::BicliqueCover;
19use crate::reduction;
20use crate::rules::traits::{ReduceTo, ReductionResult};
21use crate::topology::BipartiteGraph;
22
23pub(crate) fn config_bc_to_bmf(bc: &[usize], m: usize, n: usize, k: usize) -> Vec<usize> {
29 let mut bmf = vec![0usize; m * k + k * n];
30 for i in 0..m {
31 for l in 0..k {
32 bmf[i * k + l] = bc[i * k + l];
33 }
34 }
35 for l in 0..k {
36 for j in 0..n {
37 bmf[m * k + l * n + j] = bc[(m + j) * k + l];
38 }
39 }
40 bmf
41}
42
43pub(crate) fn config_bmf_to_bc(bmf: &[usize], m: usize, n: usize, k: usize) -> Vec<usize> {
46 let mut bc = vec![0usize; (m + n) * k];
47 for i in 0..m {
48 for l in 0..k {
49 bc[i * k + l] = bmf[i * k + l];
50 }
51 }
52 for l in 0..k {
53 for j in 0..n {
54 bc[(m + j) * k + l] = bmf[m * k + l * n + j];
55 }
56 }
57 bc
58}
59
60#[derive(Debug, Clone)]
62pub struct ReductionBMFToBicliqueCover {
63 target: BicliqueCover,
64 m: usize,
65 n: usize,
66 k: usize,
67}
68
69impl ReductionResult for ReductionBMFToBicliqueCover {
70 type Source = BMF;
71 type Target = BicliqueCover;
72
73 fn target_problem(&self) -> &BicliqueCover {
74 &self.target
75 }
76
77 fn extract_solution(&self, target_solution: &[usize]) -> Vec<usize> {
79 config_bc_to_bmf(target_solution, self.m, self.n, self.k)
80 }
81}
82
83#[reduction(
84 overhead = {
85 num_vertices = "rows + cols",
86 num_edges = "rows * cols",
87 rank = "rank",
88 }
89)]
90impl ReduceTo<BicliqueCover> for BMF {
91 type Result = ReductionBMFToBicliqueCover;
92
93 fn reduce_to(&self) -> Self::Result {
94 let m = self.rows();
95 let n = self.cols();
96 let k = self.rank();
97 let mut edges = Vec::new();
98 for (i, row) in self.matrix().iter().enumerate() {
99 for (j, &val) in row.iter().enumerate() {
100 if val {
101 edges.push((i, j));
102 }
103 }
104 }
105 let target = BicliqueCover::new(BipartiteGraph::new(m, n, edges), k);
106 ReductionBMFToBicliqueCover { target, m, n, k }
107 }
108}
109
110#[cfg(feature = "example-db")]
111pub(crate) fn canonical_rule_example_specs() -> Vec<crate::example_db::specs::RuleExampleSpec> {
112 use crate::export::SolutionPair;
113
114 vec![crate::example_db::specs::RuleExampleSpec {
115 id: "bmf_to_bicliquecover",
116 build: || {
117 let source = BMF::new(vec![vec![true, true], vec![true, true]], 1);
119 crate::example_db::specs::rule_example_with_witness::<_, BicliqueCover>(
120 source,
121 SolutionPair {
122 source_config: vec![1, 1, 1, 1],
124 target_config: vec![1, 1, 1, 1],
126 },
127 )
128 },
129 }]
130}
131
132#[cfg(test)]
133#[path = "../unit_tests/rules/bmf_bicliquecover.rs"]
134mod tests;