diff options
author | 2025-05-02 15:18:43 +0300 | |
---|---|---|
committer | 2025-05-02 15:18:43 +0300 | |
commit | 24ffb51a4fa63cf062b6980d1f8af5330d75cdc4 (patch) | |
tree | eaa6a78aa1a13cc12ec1955fc6460e4cddf8df74 /src | |
parent | fix: improve full NAND/NOR solutions (diff) | |
download | logic-rust-24ffb51a4fa63cf062b6980d1f8af5330d75cdc4.tar.gz logic-rust-24ffb51a4fa63cf062b6980d1f8af5330d75cdc4.tar.bz2 logic-rust-24ffb51a4fa63cf062b6980d1f8af5330d75cdc4.tar.lz logic-rust-24ffb51a4fa63cf062b6980d1f8af5330d75cdc4.tar.xz logic-rust-24ffb51a4fa63cf062b6980d1f8af5330d75cdc4.tar.zst logic-rust-24ffb51a4fa63cf062b6980d1f8af5330d75cdc4.zip |
fix: improve minimization algorithm
Diffstat (limited to 'src')
-rw-r--r-- | src/main.rs | 44 |
1 files changed, 39 insertions, 5 deletions
diff --git a/src/main.rs b/src/main.rs index 0577814..a1ee3c1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -150,7 +150,10 @@ fn solve_prime_implicants_table(minterms: &[usize], prime_implicants: &[Cube]) - for (a, b) in implicants.iter().sorted().tuple_combinations() { let a_set = &covered_by_implicants[a]; let b_set = &covered_by_implicants[b]; - let eq = a_set == b_set; + + let a_is_subset = a_set.difference(b_set).count() == 0; + let b_is_subset = b_set.difference(a_set).count() == 0; + let eq = a_is_subset && b_is_subset; let a_cost = prime_implicants[*a].cost(); let b_cost = prime_implicants[*b].cost(); @@ -161,6 +164,12 @@ fn solve_prime_implicants_table(minterms: &[usize], prime_implicants: &[Cube]) - } else if eq { implicants_to_remove[*b] = true; removed = true; + } else if a_is_subset && a_cost >= b_cost { + implicants_to_remove[*a] = true; + removed = true; + } else if b_is_subset && b_cost >= a_cost { + implicants_to_remove[*b] = true; + removed = true; } } @@ -173,9 +182,35 @@ fn solve_prime_implicants_table(minterms: &[usize], prime_implicants: &[Cube]) - table = new_table; } else { // We can't remove implicants by cost, have to choose by ourselves. - // NOTE: this leads to non-minimal solution - // NOTE: this SHOULD NOT happen, as we are filtering equal implicant costs too - todo!() + // NOTE: this can lead to non-minimal solution!!!!!!!!! + // NOTE: this happens when there's no essential implicants + + // Calculating minterm coverage + let mut minterms_freq = vec![0; minterms.len()]; + table.iter().for_each(|&(_, j)| minterms_freq[j] += 1); + + // Searching minterm that has the least coverage + let costless_minterm = minterms_freq + .into_iter() + .enumerate() + .filter(|&(_, v)| v >= 2) + .min_by_key(|&(_, v)| v) + .map(|(i, _)| i) + .unwrap(); + + // Selecting first implicant that contains this minterm + let selected_implicant = (0..prime_implicants.len()) + .find(|&i| table.contains(&(i, costless_minterm))) + .unwrap(); + selected_implicants[selected_implicant] = true; + + // Updating table to remove this implicant from calculation + let new_table: HashSet<_> = table + .iter() + .filter(|&&(i, _)| i != selected_implicant) + .cloned() + .collect(); + table = new_table; } } @@ -190,7 +225,6 @@ fn solve_prime_implicants_table(minterms: &[usize], prime_implicants: &[Cube]) - fn minimize(n: usize, minterms: &[usize], maxterms: &[usize]) -> Vec<Cube> { let prime_implicants = minimize_prime_implicants(n, minterms, maxterms); - // print_prime_implicants_table(n, minterms, &prime_implicants); solve_prime_implicants_table(minterms, &prime_implicants) } |