NUCS 3.0.0__tar.gz → 4.2.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (152) hide show
  1. {nucs-3.0.0 → nucs-4.2.0/NUCS.egg-info}/PKG-INFO +1 -1
  2. {nucs-3.0.0 → nucs-4.2.0}/NUCS.egg-info/SOURCES.txt +33 -1
  3. {nucs-3.0.0/NUCS.egg-info → nucs-4.2.0}/PKG-INFO +1 -1
  4. {nucs-3.0.0 → nucs-4.2.0}/docs/source/conf.py +2 -2
  5. {nucs-3.0.0 → nucs-4.2.0}/nucs/constants.py +37 -9
  6. {nucs-3.0.0 → nucs-4.2.0}/nucs/examples/alpha/__main__.py +1 -1
  7. {nucs-3.0.0 → nucs-4.2.0}/nucs/examples/alpha/alpha_problem.py +1 -1
  8. {nucs-3.0.0 → nucs-4.2.0}/nucs/examples/bibd/__main__.py +5 -3
  9. {nucs-3.0.0 → nucs-4.2.0}/nucs/examples/donald/__main__.py +1 -1
  10. {nucs-3.0.0 → nucs-4.2.0}/nucs/examples/donald/donald_problem.py +1 -3
  11. {nucs-3.0.0 → nucs-4.2.0}/nucs/examples/golomb/__main__.py +20 -4
  12. {nucs-3.0.0 → nucs-4.2.0}/nucs/examples/golomb/golomb_problem.py +27 -28
  13. {nucs-3.0.0 → nucs-4.2.0}/nucs/examples/knapsack/__main__.py +4 -3
  14. {nucs-3.0.0 → nucs-4.2.0}/nucs/examples/magic_sequence/__main__.py +5 -3
  15. {nucs-3.0.0 → nucs-4.2.0}/nucs/examples/magic_sequence/magic_sequence_problem.py +1 -3
  16. {nucs-3.0.0 → nucs-4.2.0}/nucs/examples/magic_square/__main__.py +2 -2
  17. {nucs-3.0.0 → nucs-4.2.0}/nucs/examples/quasigroup/__main__.py +2 -2
  18. {nucs-3.0.0 → nucs-4.2.0}/nucs/examples/queens/__main__.py +3 -3
  19. {nucs-3.0.0 → nucs-4.2.0}/nucs/examples/schur_lemma/__main__.py +2 -2
  20. {nucs-3.0.0 → nucs-4.2.0}/nucs/examples/sports_tournament_scheduling/__main__.py +2 -2
  21. {nucs-3.0.0 → nucs-4.2.0}/nucs/examples/sudoku/sudoku_problem.py +2 -16
  22. nucs-4.2.0/nucs/examples/tsp/__main__.py +64 -0
  23. nucs-4.2.0/nucs/examples/tsp/mcp_dom_heuristic.py +59 -0
  24. nucs-4.2.0/nucs/examples/tsp/mrp_var_heuristic.py +60 -0
  25. nucs-4.2.0/nucs/examples/tsp/total_cost_propagator.py +79 -0
  26. nucs-4.2.0/nucs/examples/tsp/tsp_instances.py +72 -0
  27. nucs-4.2.0/nucs/examples/tsp/tsp_problem.py +47 -0
  28. nucs-4.2.0/nucs/heuristics/first_not_instantiated_var_heuristic.py +35 -0
  29. nucs-4.2.0/nucs/heuristics/greatest_domain_var_heuristic.py +40 -0
  30. nucs-4.2.0/nucs/heuristics/heuristics.py +60 -0
  31. nucs-4.2.0/nucs/heuristics/max_regret_var_heuristic.py +53 -0
  32. nucs-4.2.0/nucs/heuristics/max_value_dom_heuristic.py +58 -0
  33. nucs-4.2.0/nucs/heuristics/mid_value_dom_heuristic.py +47 -0
  34. nucs-4.2.0/nucs/heuristics/min_cost_dom_heuristic.py +52 -0
  35. nucs-4.2.0/nucs/heuristics/min_value_dom_heuristic.py +58 -0
  36. nucs-4.2.0/nucs/heuristics/smallest_domain_var_heuristic.py +42 -0
  37. nucs-4.2.0/nucs/heuristics/split_high_dom_heuristic.py +58 -0
  38. nucs-4.2.0/nucs/heuristics/split_low_dom_heuristic.py +58 -0
  39. nucs-4.2.0/nucs/heuristics/value_dom_heuristic.py +78 -0
  40. {nucs-3.0.0 → nucs-4.2.0}/nucs/numpy_helper.py +2 -2
  41. nucs-4.2.0/nucs/problems/circuit_problem.py +33 -0
  42. {nucs-3.0.0 → nucs-4.2.0}/nucs/problems/problem.py +36 -26
  43. {nucs-3.0.0 → nucs-4.2.0}/nucs/propagators/affine_eq_propagator.py +20 -31
  44. {nucs-3.0.0 → nucs-4.2.0}/nucs/propagators/affine_geq_propagator.py +32 -17
  45. {nucs-3.0.0 → nucs-4.2.0}/nucs/propagators/affine_leq_propagator.py +31 -16
  46. {nucs-3.0.0 → nucs-4.2.0}/nucs/propagators/alldifferent_propagator.py +2 -2
  47. {nucs-3.0.0 → nucs-4.2.0}/nucs/propagators/and_propagator.py +3 -3
  48. {nucs-3.0.0 → nucs-4.2.0}/nucs/propagators/count_eq_propagator.py +2 -2
  49. {nucs-3.0.0 → nucs-4.2.0}/nucs/propagators/dummy_propagator.py +2 -2
  50. nucs-4.2.0/nucs/propagators/element_iv_propagator.py +82 -0
  51. {nucs-3.0.0 → nucs-4.2.0}/nucs/propagators/element_lic_propagator.py +17 -32
  52. {nucs-3.0.0 → nucs-4.2.0}/nucs/propagators/element_liv_propagator.py +16 -17
  53. {nucs-3.0.0 → nucs-4.2.0}/nucs/propagators/exactly_eq_propagator.py +2 -2
  54. {nucs-3.0.0 → nucs-4.2.0}/nucs/propagators/exactly_true_propagator.py +2 -2
  55. {nucs-3.0.0 → nucs-4.2.0}/nucs/propagators/gcc_propagator.py +2 -2
  56. {nucs-3.0.0 → nucs-4.2.0}/nucs/propagators/lexicographic_leq_propagator.py +2 -2
  57. {nucs-3.0.0 → nucs-4.2.0}/nucs/propagators/max_eq_propagator.py +2 -2
  58. {nucs-3.0.0 → nucs-4.2.0}/nucs/propagators/max_leq_propagator.py +11 -5
  59. {nucs-3.0.0 → nucs-4.2.0}/nucs/propagators/min_eq_propagator.py +2 -2
  60. {nucs-3.0.0 → nucs-4.2.0}/nucs/propagators/min_geq_propagator.py +11 -5
  61. nucs-4.2.0/nucs/propagators/no_sub_cycle_propagator.py +78 -0
  62. {nucs-3.0.0 → nucs-4.2.0}/nucs/propagators/propagators.py +21 -8
  63. {nucs-3.0.0 → nucs-4.2.0}/nucs/propagators/relation_propagator.py +2 -2
  64. nucs-4.2.0/nucs/propagators/scc_propagator.py +75 -0
  65. {nucs-3.0.0 → nucs-4.2.0}/nucs/solvers/backtrack_solver.py +159 -106
  66. {nucs-3.0.0 → nucs-4.2.0}/nucs/solvers/bound_consistency_algorithm.py +38 -29
  67. nucs-4.2.0/nucs/solvers/choice_points.py +133 -0
  68. {nucs-3.0.0 → nucs-4.2.0}/nucs/solvers/multiprocessing_solver.py +10 -7
  69. {nucs-3.0.0 → nucs-4.2.0}/nucs/solvers/shaving_consistency_algorithm.py +36 -25
  70. {nucs-3.0.0 → nucs-4.2.0}/nucs/solvers/solver.py +3 -49
  71. {nucs-3.0.0 → nucs-4.2.0}/pyproject.toml +1 -1
  72. {nucs-3.0.0 → nucs-4.2.0}/tests/examples/test_alpha.py +1 -1
  73. {nucs-3.0.0 → nucs-4.2.0}/tests/examples/test_bibd.py +3 -3
  74. {nucs-3.0.0 → nucs-4.2.0}/tests/examples/test_donald.py +1 -1
  75. {nucs-3.0.0 → nucs-4.2.0}/tests/examples/test_golomb.py +2 -7
  76. {nucs-3.0.0 → nucs-4.2.0}/tests/examples/test_knapsack.py +1 -1
  77. {nucs-3.0.0 → nucs-4.2.0}/tests/examples/test_magic_sequence.py +6 -2
  78. {nucs-3.0.0 → nucs-4.2.0}/tests/examples/test_magic_square.py +1 -1
  79. {nucs-3.0.0 → nucs-4.2.0}/tests/examples/test_quasigroup.py +1 -1
  80. {nucs-3.0.0 → nucs-4.2.0}/tests/examples/test_queens.py +1 -1
  81. {nucs-3.0.0 → nucs-4.2.0}/tests/examples/test_sports_tournament_scheduling.py +1 -1
  82. nucs-4.2.0/tests/examples/test_tsp.py +47 -0
  83. nucs-4.2.0/tests/heuristics/test_max_value_dom_heuristic.py +24 -0
  84. nucs-4.2.0/tests/heuristics/test_mid_value_dom_heuristic.py +24 -0
  85. nucs-4.2.0/tests/heuristics/test_min_value_dom_heuristic.py +24 -0
  86. nucs-4.2.0/tests/problems/__init__.py +0 -0
  87. nucs-4.2.0/tests/problems/test_circuit_problem.py +36 -0
  88. nucs-4.2.0/tests/propagators/__init__.py +0 -0
  89. {nucs-3.0.0 → nucs-4.2.0}/tests/propagators/test_affine_eq.py +1 -1
  90. {nucs-3.0.0 → nucs-4.2.0}/tests/propagators/test_affine_geq.py +1 -1
  91. {nucs-3.0.0 → nucs-4.2.0}/tests/propagators/test_affine_leq.py +1 -1
  92. nucs-4.2.0/tests/propagators/test_element_iv.py +36 -0
  93. {nucs-3.0.0 → nucs-4.2.0}/tests/propagators/test_element_liv.py +5 -0
  94. nucs-4.2.0/tests/propagators/test_no_sub_cycle.py +27 -0
  95. nucs-4.2.0/tests/propagators/test_scc.py +32 -0
  96. nucs-4.2.0/tests/solvers/__init__.py +0 -0
  97. {nucs-3.0.0 → nucs-4.2.0}/tests/solvers/test_backtrack_solver.py +43 -3
  98. {nucs-3.0.0 → nucs-4.2.0}/tests/solvers/test_multiprocessing_solver.py +28 -23
  99. nucs-3.0.0/nucs/solvers/choice_points.py +0 -88
  100. nucs-3.0.0/nucs/solvers/heuristics.py +0 -193
  101. {nucs-3.0.0 → nucs-4.2.0}/LICENSE.md +0 -0
  102. {nucs-3.0.0 → nucs-4.2.0}/NUCS.egg-info/dependency_links.txt +0 -0
  103. {nucs-3.0.0 → nucs-4.2.0}/NUCS.egg-info/requires.txt +0 -0
  104. {nucs-3.0.0 → nucs-4.2.0}/NUCS.egg-info/top_level.txt +0 -0
  105. {nucs-3.0.0 → nucs-4.2.0}/README.md +0 -0
  106. {nucs-3.0.0 → nucs-4.2.0}/nucs/__init__.py +0 -0
  107. {nucs-3.0.0 → nucs-4.2.0}/nucs/examples/__init__.py +0 -0
  108. {nucs-3.0.0 → nucs-4.2.0}/nucs/examples/alpha/__init__.py +0 -0
  109. {nucs-3.0.0 → nucs-4.2.0}/nucs/examples/bibd/__init__.py +0 -0
  110. {nucs-3.0.0 → nucs-4.2.0}/nucs/examples/bibd/bibd_problem.py +0 -0
  111. {nucs-3.0.0 → nucs-4.2.0}/nucs/examples/donald/__init__.py +0 -0
  112. {nucs-3.0.0 → nucs-4.2.0}/nucs/examples/golomb/__init__.py +0 -0
  113. {nucs-3.0.0 → nucs-4.2.0}/nucs/examples/knapsack/__init__.py +0 -0
  114. {nucs-3.0.0 → nucs-4.2.0}/nucs/examples/knapsack/knapsack_problem.py +0 -0
  115. {nucs-3.0.0 → nucs-4.2.0}/nucs/examples/magic_sequence/__init__.py +0 -0
  116. {nucs-3.0.0 → nucs-4.2.0}/nucs/examples/magic_square/__init__.py +0 -0
  117. {nucs-3.0.0 → nucs-4.2.0}/nucs/examples/magic_square/magic_square_problem.py +0 -0
  118. {nucs-3.0.0 → nucs-4.2.0}/nucs/examples/quasigroup/__init__.py +0 -0
  119. {nucs-3.0.0 → nucs-4.2.0}/nucs/examples/quasigroup/quasigroup_problem.py +0 -0
  120. {nucs-3.0.0 → nucs-4.2.0}/nucs/examples/queens/__init__.py +0 -0
  121. {nucs-3.0.0 → nucs-4.2.0}/nucs/examples/queens/queens_problem.py +0 -0
  122. {nucs-3.0.0 → nucs-4.2.0}/nucs/examples/schur_lemma/__init__.py +0 -0
  123. {nucs-3.0.0 → nucs-4.2.0}/nucs/examples/schur_lemma/schur_lemma_problem.py +0 -0
  124. {nucs-3.0.0 → nucs-4.2.0}/nucs/examples/sports_tournament_scheduling/__init__.py +0 -0
  125. {nucs-3.0.0 → nucs-4.2.0}/nucs/examples/sports_tournament_scheduling/sports_tournament_scheduling_problem.py +0 -0
  126. {nucs-3.0.0 → nucs-4.2.0}/nucs/examples/sudoku/__init__.py +0 -0
  127. {nucs-3.0.0/nucs/problems → nucs-4.2.0/nucs/examples/tsp}/__init__.py +0 -0
  128. {nucs-3.0.0/nucs/propagators → nucs-4.2.0/nucs/heuristics}/__init__.py +0 -0
  129. {nucs-3.0.0 → nucs-4.2.0}/nucs/numba_helper.py +0 -0
  130. {nucs-3.0.0/nucs/solvers → nucs-4.2.0/nucs/problems}/__init__.py +0 -0
  131. {nucs-3.0.0 → nucs-4.2.0}/nucs/problems/latin_square_problem.py +0 -0
  132. {nucs-3.0.0/tests → nucs-4.2.0/nucs/propagators}/__init__.py +0 -0
  133. {nucs-3.0.0/tests/problems → nucs-4.2.0/nucs/solvers}/__init__.py +0 -0
  134. {nucs-3.0.0 → nucs-4.2.0}/nucs/solvers/consistency_algorithms.py +0 -0
  135. {nucs-3.0.0 → nucs-4.2.0}/setup.cfg +0 -0
  136. {nucs-3.0.0/tests/propagators → nucs-4.2.0/tests}/__init__.py +0 -0
  137. {nucs-3.0.0 → nucs-4.2.0}/tests/examples/test_latin_square.py +0 -0
  138. {nucs-3.0.0 → nucs-4.2.0}/tests/examples/test_schur_lemma.py +0 -0
  139. {nucs-3.0.0 → nucs-4.2.0}/tests/examples/test_sudokus.py +0 -0
  140. {nucs-3.0.0/tests/solvers → nucs-4.2.0/tests/heuristics}/__init__.py +0 -0
  141. {nucs-3.0.0 → nucs-4.2.0}/tests/problems/test_problem.py +0 -0
  142. {nucs-3.0.0 → nucs-4.2.0}/tests/propagators/test_alldifferent.py +0 -0
  143. {nucs-3.0.0 → nucs-4.2.0}/tests/propagators/test_count_eq.py +0 -0
  144. {nucs-3.0.0 → nucs-4.2.0}/tests/propagators/test_element_lic.py +0 -0
  145. {nucs-3.0.0 → nucs-4.2.0}/tests/propagators/test_exactly_eq.py +0 -0
  146. {nucs-3.0.0 → nucs-4.2.0}/tests/propagators/test_gcc.py +0 -0
  147. {nucs-3.0.0 → nucs-4.2.0}/tests/propagators/test_lexicographic_leq.py +0 -0
  148. {nucs-3.0.0 → nucs-4.2.0}/tests/propagators/test_max_eq.py +0 -0
  149. {nucs-3.0.0 → nucs-4.2.0}/tests/propagators/test_max_leq.py +0 -0
  150. {nucs-3.0.0 → nucs-4.2.0}/tests/propagators/test_min_eq.py +0 -0
  151. {nucs-3.0.0 → nucs-4.2.0}/tests/propagators/test_min_geq.py +0 -0
  152. {nucs-3.0.0 → nucs-4.2.0}/tests/propagators/test_relation.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: NUCS
3
- Version: 3.0.0
3
+ Version: 4.2.0
4
4
  Summary: A Numpy and Numba based Python library for solving Constraint Satisfaction Problems over finite domains
5
5
  Author-email: Yan Georget <yan.georget@gmail.com>
6
6
  Project-URL: Homepage, https://github.com/yangeorget/nucs
@@ -47,7 +47,28 @@ nucs/examples/sports_tournament_scheduling/__main__.py
47
47
  nucs/examples/sports_tournament_scheduling/sports_tournament_scheduling_problem.py
48
48
  nucs/examples/sudoku/__init__.py
49
49
  nucs/examples/sudoku/sudoku_problem.py
50
+ nucs/examples/tsp/__init__.py
51
+ nucs/examples/tsp/__main__.py
52
+ nucs/examples/tsp/mcp_dom_heuristic.py
53
+ nucs/examples/tsp/mrp_var_heuristic.py
54
+ nucs/examples/tsp/total_cost_propagator.py
55
+ nucs/examples/tsp/tsp_instances.py
56
+ nucs/examples/tsp/tsp_problem.py
57
+ nucs/heuristics/__init__.py
58
+ nucs/heuristics/first_not_instantiated_var_heuristic.py
59
+ nucs/heuristics/greatest_domain_var_heuristic.py
60
+ nucs/heuristics/heuristics.py
61
+ nucs/heuristics/max_regret_var_heuristic.py
62
+ nucs/heuristics/max_value_dom_heuristic.py
63
+ nucs/heuristics/mid_value_dom_heuristic.py
64
+ nucs/heuristics/min_cost_dom_heuristic.py
65
+ nucs/heuristics/min_value_dom_heuristic.py
66
+ nucs/heuristics/smallest_domain_var_heuristic.py
67
+ nucs/heuristics/split_high_dom_heuristic.py
68
+ nucs/heuristics/split_low_dom_heuristic.py
69
+ nucs/heuristics/value_dom_heuristic.py
50
70
  nucs/problems/__init__.py
71
+ nucs/problems/circuit_problem.py
51
72
  nucs/problems/latin_square_problem.py
52
73
  nucs/problems/problem.py
53
74
  nucs/propagators/__init__.py
@@ -58,6 +79,7 @@ nucs/propagators/alldifferent_propagator.py
58
79
  nucs/propagators/and_propagator.py
59
80
  nucs/propagators/count_eq_propagator.py
60
81
  nucs/propagators/dummy_propagator.py
82
+ nucs/propagators/element_iv_propagator.py
61
83
  nucs/propagators/element_lic_propagator.py
62
84
  nucs/propagators/element_liv_propagator.py
63
85
  nucs/propagators/exactly_eq_propagator.py
@@ -68,14 +90,15 @@ nucs/propagators/max_eq_propagator.py
68
90
  nucs/propagators/max_leq_propagator.py
69
91
  nucs/propagators/min_eq_propagator.py
70
92
  nucs/propagators/min_geq_propagator.py
93
+ nucs/propagators/no_sub_cycle_propagator.py
71
94
  nucs/propagators/propagators.py
72
95
  nucs/propagators/relation_propagator.py
96
+ nucs/propagators/scc_propagator.py
73
97
  nucs/solvers/__init__.py
74
98
  nucs/solvers/backtrack_solver.py
75
99
  nucs/solvers/bound_consistency_algorithm.py
76
100
  nucs/solvers/choice_points.py
77
101
  nucs/solvers/consistency_algorithms.py
78
- nucs/solvers/heuristics.py
79
102
  nucs/solvers/multiprocessing_solver.py
80
103
  nucs/solvers/shaving_consistency_algorithm.py
81
104
  nucs/solvers/solver.py
@@ -93,7 +116,13 @@ tests/examples/test_queens.py
93
116
  tests/examples/test_schur_lemma.py
94
117
  tests/examples/test_sports_tournament_scheduling.py
95
118
  tests/examples/test_sudokus.py
119
+ tests/examples/test_tsp.py
120
+ tests/heuristics/__init__.py
121
+ tests/heuristics/test_max_value_dom_heuristic.py
122
+ tests/heuristics/test_mid_value_dom_heuristic.py
123
+ tests/heuristics/test_min_value_dom_heuristic.py
96
124
  tests/problems/__init__.py
125
+ tests/problems/test_circuit_problem.py
97
126
  tests/problems/test_problem.py
98
127
  tests/propagators/__init__.py
99
128
  tests/propagators/test_affine_eq.py
@@ -101,6 +130,7 @@ tests/propagators/test_affine_geq.py
101
130
  tests/propagators/test_affine_leq.py
102
131
  tests/propagators/test_alldifferent.py
103
132
  tests/propagators/test_count_eq.py
133
+ tests/propagators/test_element_iv.py
104
134
  tests/propagators/test_element_lic.py
105
135
  tests/propagators/test_element_liv.py
106
136
  tests/propagators/test_exactly_eq.py
@@ -110,7 +140,9 @@ tests/propagators/test_max_eq.py
110
140
  tests/propagators/test_max_leq.py
111
141
  tests/propagators/test_min_eq.py
112
142
  tests/propagators/test_min_geq.py
143
+ tests/propagators/test_no_sub_cycle.py
113
144
  tests/propagators/test_relation.py
145
+ tests/propagators/test_scc.py
114
146
  tests/solvers/__init__.py
115
147
  tests/solvers/test_backtrack_solver.py
116
148
  tests/solvers/test_multiprocessing_solver.py
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: NUCS
3
- Version: 3.0.0
3
+ Version: 4.2.0
4
4
  Summary: A Numpy and Numba based Python library for solving Constraint Satisfaction Problems over finite domains
5
5
  Author-email: Yan Georget <yan.georget@gmail.com>
6
6
  Project-URL: Homepage, https://github.com/yangeorget/nucs
@@ -6,8 +6,8 @@ project = 'NUCS'
6
6
  copyright = '2024, Yan Georget'
7
7
  author = 'Yan Georget'
8
8
 
9
- release = '3.0.0'
10
- version = '3.0.0'
9
+ release = '4.2.0'
10
+ version = '4.2.0'
11
11
 
12
12
  # -- General configuration
13
13
 
@@ -14,12 +14,28 @@ import os
14
14
 
15
15
  from numba import bool, int32, int64, types, uint8, uint16 # type: ignore
16
16
 
17
- START = 0 # index corresponding the start of a values range
18
- END = 1 # index corresponding the end of a values range
17
+ OPT_RESET = "RESET"
18
+ OPT_PRUNE = "PRUNE"
19
+ OPT_MODES = [OPT_RESET, OPT_PRUNE]
20
+
21
+ RG_START = 0 # index corresponding the start of a values range
22
+ RG_END = 1 # index corresponding the end of a values range
19
23
 
20
24
  MIN = 0 # min value of a domain
21
25
  MAX = 1 # max value of a domain
22
26
 
27
+ DOM_UPDATE_IDX = 0
28
+ DOM_UPDATE_EVENTS = 1
29
+
30
+ EVENT_MASK_MIN = 1 << 0
31
+ EVENT_MASK_MAX = 1 << 1
32
+ EVENT_MASK_GROUND = 1 << 2
33
+ EVENT_MASK_MIN_MAX = EVENT_MASK_MIN | EVENT_MASK_MAX
34
+ EVENT_MASK_MIN_GROUND = EVENT_MASK_MIN | EVENT_MASK_GROUND
35
+ EVENT_MASK_MAX_GROUND = EVENT_MASK_MAX | EVENT_MASK_GROUND
36
+ EVENT_MASK_MIN_MAX_GROUND = EVENT_MASK_MIN | EVENT_MASK_MAX | EVENT_MASK_GROUND
37
+
38
+
23
39
  PROP_INCONSISTENCY = 0 # returned by a propagator when inconsistent
24
40
  PROP_CONSISTENCY = 1 # returned by a propagator when consistent
25
41
  PROP_ENTAILMENT = 2 # returned by a propagator when entailed
@@ -29,10 +45,6 @@ PROBLEM_UNBOUND = 1 # returned when the filtering of a problem has been complet
29
45
  PROBLEM_BOUND = 2 # returned when a problem is solved
30
46
 
31
47
  SIGNATURE_COMPUTE_DOMAINS = int64(int32[:, :], int32[:]) # domains, parameters
32
- SIGNATURE_DOM_HEURISTIC = int64(
33
- int32[:, :, :], uint16[:, :], uint8[:], int64 # shr_domains_stack # dom_update_stack # stacks_top # dom_idx
34
- )
35
- SIGNATURE_VAR_HEURISTIC = int64(int32[:, :, :], uint8[:]) # shr_domains_stack, stacks_top
36
48
  SIGNATURE_CONSISTENCY_ALG = int64(
37
49
  int64[:], # statistics
38
50
  uint8[:], # algorithms
@@ -43,14 +55,30 @@ SIGNATURE_CONSISTENCY_ALG = int64(
43
55
  uint16[:], # props_dom_indices
44
56
  int32[:, :], # props_dom_offsets
45
57
  int32[:], # props_parameters
46
- bool[:, :, :], # shr_domains_propagators
58
+ uint8[:, :], # shr_domains_propagators
47
59
  int32[:, :, :], # shr_domains_stack
48
60
  bool[:, :], # not_entailed_propagators_stack
49
61
  uint16[:, :], # dom_update_stack
50
- uint8[:], # stacks_height
62
+ uint8[:], # stacks_top
51
63
  bool[:], # triggered_propagators
52
64
  int64[:], # compute_domains_addrs
65
+ uint16[:], # decision_domains
66
+ )
67
+ SIGNATURE_DOM_HEURISTIC = int64(
68
+ int32[:, :, :], # shr_domains_stack
69
+ bool[:, :], # not_entailed_propagators_stack
70
+ uint16[:, :], # dom_update_stack
71
+ uint8[:], # stacks_top
72
+ int64, # dom_idx
73
+ int64[:, :], # dom_heuristic_params
53
74
  )
75
+ SIGNATURE_VAR_HEURISTIC = int64(
76
+ uint16[:], # decision_variables
77
+ int32[:, :, :], # shr_domains_stack
78
+ uint8[:], # stacks_top
79
+ int64[:, :], # var_heuristic_params
80
+ )
81
+
54
82
 
55
83
  TYPE_COMPUTE_DOMAINS = types.FunctionType(SIGNATURE_COMPUTE_DOMAINS)
56
84
  TYPE_DOM_HEURISTIC = types.FunctionType(SIGNATURE_DOM_HEURISTIC)
@@ -59,7 +87,7 @@ TYPE_CONSISTENCY_ALG = types.FunctionType(SIGNATURE_CONSISTENCY_ALG)
59
87
 
60
88
  NUMBA_DISABLE_JIT = os.getenv("NUMBA_DISABLE_JIT")
61
89
 
62
- LOG_FORMAT = "%(asctime)s - %(processName)s - %(levelname)s - %(name)s - %(funcName)s - %(message)s"
90
+ LOG_FORMAT = "[ %(asctime)s | %(processName)s | %(levelname)s ] %(name)s.%(funcName)s - %(message)s"
63
91
  LOG_LEVEL_DEBUG = "DEBUG"
64
92
  LOG_LEVEL_INFO = "INFO"
65
93
  LOG_LEVEL_WARNING = "WARNING"
@@ -16,8 +16,8 @@ from rich import print
16
16
 
17
17
  from nucs.constants import LOG_LEVEL_INFO, LOG_LEVELS
18
18
  from nucs.examples.alpha.alpha_problem import AlphaProblem
19
+ from nucs.heuristics.heuristics import DOM_HEURISTIC_MIN_VALUE, VAR_HEURISTIC_SMALLEST_DOMAIN
19
20
  from nucs.solvers.backtrack_solver import BacktrackSolver
20
- from nucs.solvers.heuristics import DOM_HEURISTIC_MIN_VALUE, VAR_HEURISTIC_SMALLEST_DOMAIN
21
21
 
22
22
  # Run with the following command (the second run is much faster because the code has been compiled):
23
23
  # NUMBA_CACHE_DIR=.numba/cache python -m nucs.examples.alpha
@@ -12,7 +12,7 @@
12
12
  ###############################################################################
13
13
  from typing import Dict
14
14
 
15
- from numpy._typing import NDArray
15
+ from numpy.typing import NDArray
16
16
 
17
17
  from nucs.problems.problem import Problem
18
18
  from nucs.propagators.propagators import ALG_AFFINE_EQ, ALG_ALLDIFFERENT
@@ -16,8 +16,8 @@ from rich import print
16
16
 
17
17
  from nucs.constants import LOG_LEVEL_INFO, LOG_LEVELS
18
18
  from nucs.examples.bibd.bibd_problem import BIBDProblem
19
+ from nucs.heuristics.heuristics import DOM_HEURISTIC_MAX_VALUE
19
20
  from nucs.solvers.backtrack_solver import BacktrackSolver
20
- from nucs.solvers.heuristics import DOM_HEURISTIC_MAX_VALUE
21
21
 
22
22
  # Run with the following command (the second run is much faster because the code has been compiled):
23
23
  # NUMBA_CACHE_DIR=.numba/cache python -m nucs.examples.bibd -v 8 -b 14 -r 7 -k 4 -l 3 --symmetry_breaking
@@ -28,10 +28,12 @@ if __name__ == "__main__":
28
28
  parser.add_argument("-r", type=int)
29
29
  parser.add_argument("-k", type=int)
30
30
  parser.add_argument("-l", type=int)
31
- parser.add_argument("--symmetry_breaking", action=argparse.BooleanOptionalAction, default=True)
32
31
  parser.add_argument("--log_level", choices=LOG_LEVELS, default=LOG_LEVEL_INFO)
32
+ parser.add_argument("--symmetry_breaking", action=argparse.BooleanOptionalAction, default=True)
33
33
  args = parser.parse_args()
34
34
  problem = BIBDProblem(args.v, args.b, args.r, args.k, args.l, args.symmetry_breaking)
35
- solver = BacktrackSolver(problem, dom_heuristic_idx=DOM_HEURISTIC_MAX_VALUE, log_level=args.log_level)
35
+ solver = BacktrackSolver(
36
+ problem, dom_heuristic_idx=DOM_HEURISTIC_MAX_VALUE, log_level=args.log_level, stack_max_height=128
37
+ )
36
38
  solver.solve_all()
37
39
  print(solver.get_statistics())
@@ -16,8 +16,8 @@ from rich import print
16
16
 
17
17
  from nucs.constants import LOG_LEVEL_INFO, LOG_LEVELS
18
18
  from nucs.examples.donald.donald_problem import DonaldProblem
19
+ from nucs.heuristics.heuristics import DOM_HEURISTIC_MIN_VALUE, VAR_HEURISTIC_SMALLEST_DOMAIN
19
20
  from nucs.solvers.backtrack_solver import BacktrackSolver
20
- from nucs.solvers.heuristics import DOM_HEURISTIC_MIN_VALUE, VAR_HEURISTIC_SMALLEST_DOMAIN
21
21
 
22
22
  # Run with the following command (the second run is much faster because the code has been compiled):
23
23
  # NUMBA_CACHE_DIR=.numba/cache python -m nucs.examples.donald
@@ -38,9 +38,7 @@ class DonaldProblem(Problem):
38
38
  [200, -1000, 100002, 9900, 100000, 20, 1000, 0, -99010, -1, 0],
39
39
  )
40
40
  )
41
- self.add_propagator(
42
- ([A, B, D, E, G, L, N, O, R, T], ALG_ALLDIFFERENT, []),
43
- )
41
+ self.add_propagator(([A, B, D, E, G, L, N, O, R, T], ALG_ALLDIFFERENT, []))
44
42
 
45
43
  def solution_as_dict(self, solution: NDArray) -> Dict[str, int]:
46
44
  """
@@ -14,23 +14,39 @@ import argparse
14
14
 
15
15
  from rich import print
16
16
 
17
- from nucs.constants import LOG_LEVEL_INFO, LOG_LEVELS
17
+ from nucs.constants import LOG_LEVEL_INFO, LOG_LEVELS, OPT_MODES, OPT_PRUNE
18
18
  from nucs.examples.golomb.golomb_problem import GolombProblem, golomb_consistency_algorithm
19
19
  from nucs.solvers.backtrack_solver import BacktrackSolver
20
20
  from nucs.solvers.consistency_algorithms import register_consistency_algorithm
21
+ from nucs.solvers.multiprocessing_solver import MultiprocessingSolver
21
22
 
22
23
  # Run with the following command (the second run is much faster because the code has been compiled):
23
24
  # NUMBA_CACHE_DIR=.numba/cache python -m nucs.examples.golomb -n 10 --symmetry_breaking
24
25
  if __name__ == "__main__":
25
26
  parser = argparse.ArgumentParser()
26
27
  parser.add_argument("-n", type=int, default=10)
27
- parser.add_argument("--symmetry_breaking", action=argparse.BooleanOptionalAction, default=True)
28
28
  parser.add_argument("--log_level", choices=LOG_LEVELS, default=LOG_LEVEL_INFO)
29
+ parser.add_argument("--opt_mode", choices=OPT_MODES, default=OPT_PRUNE)
30
+ parser.add_argument("--processors", type=int, default=1)
31
+ parser.add_argument("--symmetry_breaking", action=argparse.BooleanOptionalAction, default=True)
29
32
  args = parser.parse_args()
30
33
  problem = GolombProblem(args.n, args.symmetry_breaking)
31
34
  consistency_alg_golomb = register_consistency_algorithm(golomb_consistency_algorithm)
32
- solver = BacktrackSolver(problem, consistency_alg_idx=consistency_alg_golomb, log_level=args.log_level)
33
- solution = solver.minimize(problem.length_idx)
35
+ solver = (
36
+ MultiprocessingSolver(
37
+ [
38
+ BacktrackSolver(
39
+ prob, consistency_alg_idx=consistency_alg_golomb, log_level=args.log_level, stack_max_height=128
40
+ )
41
+ for prob in problem.split(args.processors, 0)
42
+ ]
43
+ )
44
+ if args.processors > 1
45
+ else BacktrackSolver(
46
+ problem, consistency_alg_idx=consistency_alg_golomb, log_level=args.log_level, stack_max_height=128
47
+ )
48
+ )
49
+ solution = solver.minimize(problem.length_idx, mode=args.opt_mode)
34
50
  print(solver.get_statistics())
35
51
  if solution is not None:
36
52
  print(solution[: (args.n - 1)])
@@ -16,17 +16,17 @@ import numpy as np
16
16
  from numba import njit # type: ignore
17
17
  from numpy.typing import NDArray
18
18
 
19
- from nucs.constants import MAX, MIN
19
+ from nucs.constants import EVENT_MASK_GROUND, EVENT_MASK_MIN, MAX, MIN
20
+ from nucs.heuristics.heuristics import first_not_instantiated_var_heuristic
20
21
  from nucs.problems.problem import Problem
21
22
  from nucs.propagators.propagators import ALG_AFFINE_EQ, ALG_AFFINE_LEQ, ALG_ALLDIFFERENT, add_propagators
22
23
  from nucs.solvers.bound_consistency_algorithm import bound_consistency_algorithm
23
- from nucs.solvers.heuristics import first_not_instantiated_var_heuristic
24
24
 
25
25
  GOLOMB_LENGTHS = np.array([0, 0, 1, 3, 6, 11, 17, 25, 34, 44, 55, 72, 85, 106, 127])
26
26
 
27
27
 
28
28
  @njit(cache=True)
29
- def sum_first(n: np.uint32) -> np.uint32:
29
+ def sum_first(n: int) -> int:
30
30
  """
31
31
  Returns the sum of the first n integers.
32
32
  :param n: an integer
@@ -36,7 +36,7 @@ def sum_first(n: np.uint32) -> np.uint32:
36
36
 
37
37
 
38
38
  @njit(cache=True)
39
- def index(mark_nb: np.uint32, i: np.uint32, j: np.uint32) -> np.uint32:
39
+ def index(mark_nb: int, i: int, j: int) -> int:
40
40
  """
41
41
  Returns the index of the distance variable between two marks.
42
42
  :param mark_nb: the total number of marks
@@ -47,22 +47,6 @@ def index(mark_nb: np.uint32, i: np.uint32, j: np.uint32) -> np.uint32:
47
47
  return i * mark_nb - sum_first(i) + j - i - 1
48
48
 
49
49
 
50
- @njit(cache=True)
51
- def init_domains(dist_nb: int, mark_nb: int) -> NDArray:
52
- """
53
- Returns the domains.
54
- :param dist_nb: the number of distances
55
- :param mark_nb: the number of marks
56
- :return: a Numpy array of domains
57
- """
58
- domains = np.empty((dist_nb, 2), dtype=np.int32)
59
- for i in range(0, mark_nb - 1):
60
- for j in range(i + 1, mark_nb):
61
- domains[index(mark_nb, i, j), MIN] = GOLOMB_LENGTHS[j - i + 1] if j - i + 1 < mark_nb else sum_first(j - i)
62
- domains[:, MAX] = sum_first(dist_nb)
63
- return domains
64
-
65
-
66
50
  class GolombProblem(Problem):
67
51
  """
68
52
  This is the famous Golomb ruler problem.
@@ -77,7 +61,15 @@ class GolombProblem(Problem):
77
61
  """
78
62
 
79
63
  def __init__(self, mark_nb: int, symmetry_breaking: bool = True) -> None:
80
- super().__init__(init_domains(sum_first(mark_nb - 1), mark_nb))
64
+ dist_nb = sum_first(mark_nb - 1)
65
+ domains = np.empty((dist_nb, 2), dtype=np.int32)
66
+ for i in range(0, mark_nb - 1):
67
+ for j in range(i + 1, mark_nb):
68
+ domains[index(mark_nb, i, j), MIN] = (
69
+ GOLOMB_LENGTHS[j - i + 1] if j - i + 1 < mark_nb else sum_first(j - i)
70
+ )
71
+ domains[:, MAX] = sum_first(dist_nb) - sum_first(dist_nb - mark_nb)
72
+ super().__init__(domains)
81
73
  self.length_idx = index(mark_nb, 0, mark_nb - 1) # we want to minimize this
82
74
  # dist_ij = mark_j - mark_i for j > i
83
75
  # mark_j = dist_0j for j > 0
@@ -90,7 +82,7 @@ class GolombProblem(Problem):
90
82
  [1, -1, -1, 0],
91
83
  )
92
84
  )
93
- self.add_propagator((list(range(self.variable_nb)), ALG_ALLDIFFERENT, []))
85
+ self.add_propagator((list(range(self.shr_domain_nb)), ALG_ALLDIFFERENT, []))
94
86
  # redundant constraints
95
87
  for i in range(mark_nb - 1):
96
88
  for j in range(i + 1, mark_nb):
@@ -130,6 +122,7 @@ def golomb_consistency_algorithm(
130
122
  stacks_top: NDArray,
131
123
  triggered_propagators: NDArray,
132
124
  compute_domains_addrs: NDArray,
125
+ decision_domains: NDArray,
133
126
  ) -> int:
134
127
  """
135
128
  Applies a custom consistency algorithm for the Golomb Ruler problem.
@@ -137,9 +130,12 @@ def golomb_consistency_algorithm(
137
130
  :param problem: the problem
138
131
  :return: the status as an int
139
132
  """
133
+ top = stacks_top[0]
140
134
  # first prune the search space
141
135
  mark_nb = (1 + int(math.sqrt(8 * len(dom_indices_arr) + 1))) // 2
142
- ni_var_idx = first_not_instantiated_var_heuristic(shr_domains_stack, stacks_top) # no domains shared between vars
136
+ ni_var_idx = first_not_instantiated_var_heuristic(
137
+ decision_domains, shr_domains_stack, stacks_top, None
138
+ ) # no domains shared between vars
143
139
  if 1 < ni_var_idx < mark_nb - 1: # otherwise useless
144
140
  used_distance = np.zeros(sum_first(mark_nb - 2) + 1, dtype=np.bool)
145
141
  # a reusable array for storing the minimal sum of different integers:
@@ -148,7 +144,7 @@ def golomb_consistency_algorithm(
148
144
  # the following will mark at most sum(n-3) numbers as used
149
145
  # hence there will be at least n-2 unused numbers greater than 0
150
146
  for var_idx in range(index(mark_nb, ni_var_idx - 2, ni_var_idx - 1) + 1):
151
- dist = shr_domains_stack[stacks_top[0], dom_indices_arr[var_idx], MIN] # no offset
147
+ dist = shr_domains_stack[top, dom_indices_arr[var_idx], MIN] # no offset
152
148
  if dist < len(used_distance):
153
149
  used_distance[dist] = True
154
150
  # let's compute the sum of non-used numbers
@@ -161,14 +157,16 @@ def golomb_consistency_algorithm(
161
157
  for i in range(ni_var_idx - 1, mark_nb - 1):
162
158
  for j in range(i + 1, mark_nb):
163
159
  dom_idx = dom_indices_arr[index(mark_nb, i, j)]
164
- shr_domains_stack[stacks_top[0], dom_idx, MIN] = minimal_sum[j - i] # no offset
160
+ shr_domains_stack[top, dom_idx, MIN] = minimal_sum[j - i] # no offset
161
+ events = EVENT_MASK_MIN
162
+ if shr_domains_stack[top, dom_idx, MIN] == shr_domains_stack[top, dom_idx, MAX]:
163
+ events |= EVENT_MASK_GROUND
165
164
  add_propagators(
166
165
  triggered_propagators,
167
- not_entailed_propagators_stack,
168
- stacks_top,
166
+ not_entailed_propagators_stack[top],
169
167
  shr_domains_propagators,
170
168
  dom_idx,
171
- MIN,
169
+ events,
172
170
  )
173
171
  return bound_consistency_algorithm(
174
172
  statistics,
@@ -187,4 +185,5 @@ def golomb_consistency_algorithm(
187
185
  stacks_top,
188
186
  triggered_propagators,
189
187
  compute_domains_addrs,
188
+ decision_domains,
190
189
  )
@@ -14,16 +14,17 @@ import argparse
14
14
 
15
15
  from rich import print
16
16
 
17
- from nucs.constants import LOG_LEVEL_INFO, LOG_LEVELS
17
+ from nucs.constants import LOG_LEVEL_INFO, LOG_LEVELS, OPT_MODES, OPT_RESET
18
18
  from nucs.examples.knapsack.knapsack_problem import KnapsackProblem
19
+ from nucs.heuristics.heuristics import DOM_HEURISTIC_MAX_VALUE, VAR_HEURISTIC_FIRST_NOT_INSTANTIATED
19
20
  from nucs.solvers.backtrack_solver import BacktrackSolver
20
- from nucs.solvers.heuristics import DOM_HEURISTIC_MAX_VALUE, VAR_HEURISTIC_FIRST_NOT_INSTANTIATED
21
21
 
22
22
  # Run with the following command (the second run is much faster because the code has been compiled):
23
23
  # NUMBA_CACHE_DIR=.numba/cache python -m nucs.examples.knapsack
24
24
  if __name__ == "__main__":
25
25
  parser = argparse.ArgumentParser()
26
26
  parser.add_argument("--log_level", choices=LOG_LEVELS, default=LOG_LEVEL_INFO)
27
+ parser.add_argument("--opt_mode", choices=OPT_MODES, default=OPT_RESET)
27
28
  args = parser.parse_args()
28
29
  problem = KnapsackProblem(
29
30
  [40, 40, 38, 38, 36, 36, 34, 34, 32, 32, 30, 30, 28, 28, 26, 26, 24, 24, 22, 22],
@@ -36,6 +37,6 @@ if __name__ == "__main__":
36
37
  dom_heuristic_idx=DOM_HEURISTIC_MAX_VALUE,
37
38
  log_level=args.log_level,
38
39
  )
39
- solution = solver.maximize(problem.weight)
40
+ solution = solver.maximize(problem.weight, mode=args.opt_mode)
40
41
  print(solver.get_statistics())
41
42
  print(solution)
@@ -16,22 +16,24 @@ from rich import print
16
16
 
17
17
  from nucs.constants import LOG_LEVEL_INFO, LOG_LEVELS
18
18
  from nucs.examples.magic_sequence.magic_sequence_problem import MagicSequenceProblem
19
+ from nucs.heuristics.heuristics import DOM_HEURISTIC_MIN_VALUE, VAR_HEURISTIC_FIRST_NOT_INSTANTIATED
19
20
  from nucs.solvers.backtrack_solver import BacktrackSolver
20
- from nucs.solvers.heuristics import DOM_HEURISTIC_MIN_VALUE, VAR_HEURISTIC_LAST_NOT_INSTANTIATED
21
21
 
22
22
  # Run with the following command (the second run is much faster because the code has been compiled):
23
23
  # NUMBA_CACHE_DIR=.numba/cache python -m nucs.examples.magic_sequence -n 100
24
24
  if __name__ == "__main__":
25
25
  parser = argparse.ArgumentParser()
26
- parser.add_argument("-n", type=int, default=100)
27
26
  parser.add_argument("--log_level", choices=LOG_LEVELS, default=LOG_LEVEL_INFO)
27
+ parser.add_argument("-n", type=int, default=100)
28
28
  args = parser.parse_args()
29
29
  problem = MagicSequenceProblem(args.n)
30
30
  solver = BacktrackSolver(
31
31
  problem,
32
- var_heuristic_idx=VAR_HEURISTIC_LAST_NOT_INSTANTIATED,
32
+ decision_domains=list(range(args.n - 1, -1, -1)),
33
+ var_heuristic_idx=VAR_HEURISTIC_FIRST_NOT_INSTANTIATED,
33
34
  dom_heuristic_idx=DOM_HEURISTIC_MIN_VALUE,
34
35
  log_level=args.log_level,
36
+ stack_max_height=128,
35
37
  )
36
38
  solver.solve_all()
37
39
  print(solver.get_statistics())
@@ -16,8 +16,7 @@ from nucs.propagators.propagators import ALG_AFFINE_EQ, ALG_COUNT_EQ
16
16
 
17
17
  class MagicSequenceProblem(Problem):
18
18
  """
19
- Find a sequence x_0, ... x_n-1
20
- such that each x_i is the number of occurences of i in the sequence.
19
+ Find a sequence x_0, ... x_n-1 such that each x_i is the number of occurrences of i in the sequence.
21
20
 
22
21
  CSPLIB problem #19 - https://www.csplib.org/Problems/prob019/
23
22
  """
@@ -27,7 +26,6 @@ class MagicSequenceProblem(Problem):
27
26
  Inits the problem.
28
27
  :param n: the size of the sequence
29
28
  """
30
- self.n = n
31
29
  super().__init__([(0, n)] * n)
32
30
  for i in range(n):
33
31
  self.add_propagator((list(range(n)) + [i], ALG_COUNT_EQ, [i]))
@@ -16,16 +16,16 @@ from rich import print
16
16
 
17
17
  from nucs.constants import LOG_LEVEL_INFO, LOG_LEVELS
18
18
  from nucs.examples.magic_square.magic_square_problem import MagicSquareProblem
19
+ from nucs.heuristics.heuristics import DOM_HEURISTIC_MAX_VALUE, VAR_HEURISTIC_SMALLEST_DOMAIN
19
20
  from nucs.solvers.backtrack_solver import BacktrackSolver
20
- from nucs.solvers.heuristics import DOM_HEURISTIC_MAX_VALUE, VAR_HEURISTIC_SMALLEST_DOMAIN
21
21
 
22
22
  # Run with the following command (the second run is much faster because the code has been compiled):
23
23
  # NUMBA_CACHE_DIR=.numba/cache python -m nucs.examples.magic_square -n 4 --symmetry_breaking
24
24
  if __name__ == "__main__":
25
25
  parser = argparse.ArgumentParser()
26
+ parser.add_argument("--log_level", choices=LOG_LEVELS, default=LOG_LEVEL_INFO)
26
27
  parser.add_argument("-n", type=int)
27
28
  parser.add_argument("--symmetry_breaking", action=argparse.BooleanOptionalAction, default=True)
28
- parser.add_argument("--log_level", choices=LOG_LEVELS, default=LOG_LEVEL_INFO)
29
29
  args = parser.parse_args()
30
30
  problem = MagicSquareProblem(args.n, args.symmetry_breaking)
31
31
  solver = BacktrackSolver(
@@ -16,16 +16,16 @@ from rich import print
16
16
 
17
17
  from nucs.constants import LOG_LEVEL_INFO, LOG_LEVELS
18
18
  from nucs.examples.quasigroup.quasigroup_problem import Quasigroup5Problem
19
+ from nucs.heuristics.heuristics import DOM_HEURISTIC_MIN_VALUE, VAR_HEURISTIC_SMALLEST_DOMAIN
19
20
  from nucs.solvers.backtrack_solver import BacktrackSolver
20
- from nucs.solvers.heuristics import DOM_HEURISTIC_MIN_VALUE, VAR_HEURISTIC_SMALLEST_DOMAIN
21
21
 
22
22
  # Run with the following command (the second run is much faster because the code has been compiled):
23
23
  # NUMBA_CACHE_DIR=.numba/cache python -m nucs.examples.quasigroup -n 10 --symmetry_breaking
24
24
  if __name__ == "__main__":
25
25
  parser = argparse.ArgumentParser()
26
+ parser.add_argument("--log_level", choices=LOG_LEVELS, default=LOG_LEVEL_INFO)
26
27
  parser.add_argument("-n", type=int, default=10)
27
28
  parser.add_argument("--symmetry_breaking", action=argparse.BooleanOptionalAction, default=True)
28
- parser.add_argument("--log_level", choices=LOG_LEVELS, default=LOG_LEVEL_INFO)
29
29
  args = parser.parse_args()
30
30
  problem = Quasigroup5Problem(args.n, args.symmetry_breaking)
31
31
  solver = BacktrackSolver(
@@ -16,20 +16,20 @@ from rich import print
16
16
 
17
17
  from nucs.constants import LOG_LEVEL_INFO, LOG_LEVELS
18
18
  from nucs.examples.queens.queens_problem import QueensProblem
19
+ from nucs.heuristics.heuristics import VAR_HEURISTIC_FIRST_NOT_INSTANTIATED, VAR_HEURISTIC_SMALLEST_DOMAIN
19
20
  from nucs.solvers.backtrack_solver import BacktrackSolver
20
21
  from nucs.solvers.consistency_algorithms import CONSISTENCY_ALG_BC, CONSISTENCY_ALG_SHAVING
21
- from nucs.solvers.heuristics import VAR_HEURISTIC_FIRST_NOT_INSTANTIATED, VAR_HEURISTIC_SMALLEST_DOMAIN
22
22
  from nucs.solvers.multiprocessing_solver import MultiprocessingSolver
23
23
 
24
24
  # Run with the following command (the second run is much faster because the code has been compiled):
25
25
  # NUMBA_CACHE_DIR=.numba/cache python -m nucs.examples.queens -n 10
26
26
  if __name__ == "__main__":
27
27
  parser = argparse.ArgumentParser()
28
- parser.add_argument("-n", type=int, default=10)
28
+ parser.add_argument("--ff", type=bool, action=argparse.BooleanOptionalAction, default=False)
29
29
  parser.add_argument("--log_level", choices=LOG_LEVELS, default=LOG_LEVEL_INFO)
30
+ parser.add_argument("-n", type=int, default=10)
30
31
  parser.add_argument("--processors", type=int, default=1)
31
32
  parser.add_argument("--shaving", type=bool, action=argparse.BooleanOptionalAction, default=False)
32
- parser.add_argument("--ff", type=bool, action=argparse.BooleanOptionalAction, default=False)
33
33
  args = parser.parse_args()
34
34
  problem = QueensProblem(args.n)
35
35
  solver = (
@@ -22,11 +22,11 @@ from nucs.solvers.backtrack_solver import BacktrackSolver
22
22
  # NUMBA_CACHE_DIR=.numba/cache python -m nucs.examples.schur_lemma -n 20 --symmetry_breaking
23
23
  if __name__ == "__main__":
24
24
  parser = argparse.ArgumentParser()
25
- parser.add_argument("-n", type=int, default=20)
26
25
  parser.add_argument("--log_level", choices=LOG_LEVELS, default=LOG_LEVEL_INFO)
26
+ parser.add_argument("-n", type=int, default=20)
27
27
  parser.add_argument("--symmetry_breaking", action=argparse.BooleanOptionalAction, default=True)
28
28
  args = parser.parse_args()
29
29
  problem = SchurLemmaProblem(args.n, args.symmetry_breaking)
30
- solver = BacktrackSolver(problem, log_level=args.log_level)
30
+ solver = BacktrackSolver(problem, log_level=args.log_level, stack_max_height=128)
31
31
  solver.solve_all()
32
32
  print(solver.get_statistics())
@@ -18,15 +18,15 @@ from nucs.constants import LOG_LEVEL_INFO, LOG_LEVELS
18
18
  from nucs.examples.sports_tournament_scheduling.sports_tournament_scheduling_problem import (
19
19
  SportsTournamentSchedulingProblem,
20
20
  )
21
+ from nucs.heuristics.heuristics import DOM_HEURISTIC_MIN_VALUE, VAR_HEURISTIC_SMALLEST_DOMAIN
21
22
  from nucs.solvers.backtrack_solver import BacktrackSolver
22
- from nucs.solvers.heuristics import DOM_HEURISTIC_MIN_VALUE, VAR_HEURISTIC_SMALLEST_DOMAIN
23
23
 
24
24
  # Run with the following command (the second run is much faster because the code has been compiled):
25
25
  # NUMBA_CACHE_DIR=.numba/cache python -m nucs.examples.sports_tournament_scheduling -n 8
26
26
  if __name__ == "__main__":
27
27
  parser = argparse.ArgumentParser()
28
- parser.add_argument("-n", type=int, default=8)
29
28
  parser.add_argument("--log_level", choices=LOG_LEVELS, default=LOG_LEVEL_INFO)
29
+ parser.add_argument("-n", type=int, default=8)
30
30
  parser.add_argument("--symmetry_breaking", action=argparse.BooleanOptionalAction, default=True)
31
31
  args = parser.parse_args()
32
32
  problem = SportsTournamentSchedulingProblem(args.n, args.symmetry_breaking)
@@ -29,21 +29,7 @@ class SudokuProblem(LatinSquareProblem):
29
29
  super().__init__(list(range(1, 10)), givens)
30
30
  for i in range(3):
31
31
  for j in range(3):
32
- offset = i * 27 + j * 3
32
+ o = i * 27 + j * 3
33
33
  self.add_propagator(
34
- (
35
- [
36
- 0 + offset,
37
- 1 + offset,
38
- 2 + offset,
39
- 9 + offset,
40
- 10 + offset,
41
- 11 + offset,
42
- 18 + offset,
43
- 19 + offset,
44
- 20 + offset,
45
- ],
46
- ALG_ALLDIFFERENT,
47
- [],
48
- )
34
+ ([0 + o, 1 + o, 2 + o, 9 + o, 10 + o, 11 + o, 18 + o, 19 + o, 20 + o], ALG_ALLDIFFERENT, [])
49
35
  )