Advertisement
Guest User

Untitled

a guest
Mar 16th, 2023
28
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.87 KB | None | 0 0
  1. Минимизация СКНФ (совершенной конъюнктивной нормальной формы) обычно выполняется с помощью алгоритма Куайна-Мак-Класки (QM) или алгоритма Эспрессо. Вот реализация алгоритма Куайна-Мак-Класки на Python:
  2. from itertools import combinations
  3.  
  4. def min_terms_to_binary(min_terms, n_vars):
  5. return [bin(mt)[2:].zfill(n_vars) for mt in min_terms]
  6.  
  7. def find_pair_groups(binary_min_terms):
  8. groups = [[] for _ in range(len(binary_min_terms[0]) + 1)]
  9. for bmt in binary_min_terms:
  10. groups[bmt.count('1')].append(bmt)
  11. return groups
  12.  
  13. def is_pairable(mt1, mt2):
  14. diff = 0
  15. for b1, b2 in zip(mt1, mt2):
  16. if b1 != b2:
  17. diff += 1
  18. return diff == 1
  19.  
  20. def pair(mt1, mt2):
  21. return ''.join([b1 if b1 == b2 else '-' for b1, b2 in zip(mt1, mt2)])
  22.  
  23. def qm_step(groups):
  24. new_groups = [[] for _ in range(len(groups) - 1)]
  25. paired = {mt: False for group in groups for mt in group}
  26.  
  27. for i, group in enumerate(groups[:-1]):
  28. for mt1, mt2 in itertools.product(group, groups[i + 1]):
  29. if is_pairable(mt1, mt2):
  30. new_groups[i].append(pair(mt1, mt2))
  31. paired[mt1] = paired[mt2] = True
  32.  
  33. primes = {mt for group in groups for mt in group if not paired[mt]}
  34. new_groups = [sorted(set(group)) for group in new_groups]
  35.  
  36. return new_groups, primes
  37.  
  38. def qm(binary_min_terms):
  39. groups = find_pair_groups(binary_min_terms)
  40. primes = set()
  41.  
  42. while any(groups):
  43. new_groups, new_primes = qm_step(groups)
  44. groups = new_groups
  45. primes |= new_primes
  46.  
  47. return primes
  48.  
  49. def petrick_method(primes, min_terms):
  50. covers = [{prime for prime in primes if mt in prime} for mt in min_terms]
  51. product = [covers[0]]
  52.  
  53. for cover in covers[1:]:
  54. new_product = []
  55. for prime_set1, prime_set2 in itertools.product(product, cover):
  56. new_product.append(prime_set1 | prime_set2)
  57. product = new_product
  58.  
  59. min_cover = min(product, key=lambda x: len(x))
  60. return sorted(min_cover)
  61.  
  62. def binary_to_formula(binary_min_terms, variables):
  63. def literal(var, value):
  64. return var if value == '1' else f'~{var}'
  65.  
  66. def term(binary_min_term):
  67. return ''.join([literal(var, value) for var, value in zip(variables, binary_min_term) if value != '-'])
  68.  
  69. return ' + '.join([term(binary_min_term) for binary_min_term in binary_min_terms])
  70.  
  71. def minimize_sknf(formula, variables):
  72. min_terms = [int(mt) for mt in formula.split(' + ')]
  73. binary_min_terms = min_terms_to_binary(min_terms, len(variables))
  74. primes = qm(binary_min_terms)
  75. cover = petrick_method(primes, binary_min_terms)
  76. return binary_to_formula(cover, variables)
  77.  
  78. # Usage example:
  79. formula = '1 + 2 + 3 + 5 + 6 + 7'
  80. variables = ['x1', 'x2', 'x3']
  81. minimized_formula = minimize_sknf(formula, variables)
  82. print(minimized_formula)
  83.  
  84. Пример кода выше реализует алгоритм Куайна-Мак-Класки для минимизации СКНФ. Функция `minimize_sknf` принимает на вход формулу в виде строки и список переменных. В качестве примера использования, формула '1 + 2 + 3 + 5 + 6 + 7' будет минимизирована с использованием переменных ['x1', 'x2', 'x3'].
  85.  
  86. Обратите внимание, что алгоритм Куайна-Мак-Класки может быть неэффективным для больших и сложных формул. В таких случаях рекомендуется использовать более продвинутые алгоритмы, такие как алгоритм Эспрессо.
  87.  
  88.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement