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.
- {nucs-3.0.0 → nucs-4.2.0/NUCS.egg-info}/PKG-INFO +1 -1
- {nucs-3.0.0 → nucs-4.2.0}/NUCS.egg-info/SOURCES.txt +33 -1
- {nucs-3.0.0/NUCS.egg-info → nucs-4.2.0}/PKG-INFO +1 -1
- {nucs-3.0.0 → nucs-4.2.0}/docs/source/conf.py +2 -2
- {nucs-3.0.0 → nucs-4.2.0}/nucs/constants.py +37 -9
- {nucs-3.0.0 → nucs-4.2.0}/nucs/examples/alpha/__main__.py +1 -1
- {nucs-3.0.0 → nucs-4.2.0}/nucs/examples/alpha/alpha_problem.py +1 -1
- {nucs-3.0.0 → nucs-4.2.0}/nucs/examples/bibd/__main__.py +5 -3
- {nucs-3.0.0 → nucs-4.2.0}/nucs/examples/donald/__main__.py +1 -1
- {nucs-3.0.0 → nucs-4.2.0}/nucs/examples/donald/donald_problem.py +1 -3
- {nucs-3.0.0 → nucs-4.2.0}/nucs/examples/golomb/__main__.py +20 -4
- {nucs-3.0.0 → nucs-4.2.0}/nucs/examples/golomb/golomb_problem.py +27 -28
- {nucs-3.0.0 → nucs-4.2.0}/nucs/examples/knapsack/__main__.py +4 -3
- {nucs-3.0.0 → nucs-4.2.0}/nucs/examples/magic_sequence/__main__.py +5 -3
- {nucs-3.0.0 → nucs-4.2.0}/nucs/examples/magic_sequence/magic_sequence_problem.py +1 -3
- {nucs-3.0.0 → nucs-4.2.0}/nucs/examples/magic_square/__main__.py +2 -2
- {nucs-3.0.0 → nucs-4.2.0}/nucs/examples/quasigroup/__main__.py +2 -2
- {nucs-3.0.0 → nucs-4.2.0}/nucs/examples/queens/__main__.py +3 -3
- {nucs-3.0.0 → nucs-4.2.0}/nucs/examples/schur_lemma/__main__.py +2 -2
- {nucs-3.0.0 → nucs-4.2.0}/nucs/examples/sports_tournament_scheduling/__main__.py +2 -2
- {nucs-3.0.0 → nucs-4.2.0}/nucs/examples/sudoku/sudoku_problem.py +2 -16
- nucs-4.2.0/nucs/examples/tsp/__main__.py +64 -0
- nucs-4.2.0/nucs/examples/tsp/mcp_dom_heuristic.py +59 -0
- nucs-4.2.0/nucs/examples/tsp/mrp_var_heuristic.py +60 -0
- nucs-4.2.0/nucs/examples/tsp/total_cost_propagator.py +79 -0
- nucs-4.2.0/nucs/examples/tsp/tsp_instances.py +72 -0
- nucs-4.2.0/nucs/examples/tsp/tsp_problem.py +47 -0
- nucs-4.2.0/nucs/heuristics/first_not_instantiated_var_heuristic.py +35 -0
- nucs-4.2.0/nucs/heuristics/greatest_domain_var_heuristic.py +40 -0
- nucs-4.2.0/nucs/heuristics/heuristics.py +60 -0
- nucs-4.2.0/nucs/heuristics/max_regret_var_heuristic.py +53 -0
- nucs-4.2.0/nucs/heuristics/max_value_dom_heuristic.py +58 -0
- nucs-4.2.0/nucs/heuristics/mid_value_dom_heuristic.py +47 -0
- nucs-4.2.0/nucs/heuristics/min_cost_dom_heuristic.py +52 -0
- nucs-4.2.0/nucs/heuristics/min_value_dom_heuristic.py +58 -0
- nucs-4.2.0/nucs/heuristics/smallest_domain_var_heuristic.py +42 -0
- nucs-4.2.0/nucs/heuristics/split_high_dom_heuristic.py +58 -0
- nucs-4.2.0/nucs/heuristics/split_low_dom_heuristic.py +58 -0
- nucs-4.2.0/nucs/heuristics/value_dom_heuristic.py +78 -0
- {nucs-3.0.0 → nucs-4.2.0}/nucs/numpy_helper.py +2 -2
- nucs-4.2.0/nucs/problems/circuit_problem.py +33 -0
- {nucs-3.0.0 → nucs-4.2.0}/nucs/problems/problem.py +36 -26
- {nucs-3.0.0 → nucs-4.2.0}/nucs/propagators/affine_eq_propagator.py +20 -31
- {nucs-3.0.0 → nucs-4.2.0}/nucs/propagators/affine_geq_propagator.py +32 -17
- {nucs-3.0.0 → nucs-4.2.0}/nucs/propagators/affine_leq_propagator.py +31 -16
- {nucs-3.0.0 → nucs-4.2.0}/nucs/propagators/alldifferent_propagator.py +2 -2
- {nucs-3.0.0 → nucs-4.2.0}/nucs/propagators/and_propagator.py +3 -3
- {nucs-3.0.0 → nucs-4.2.0}/nucs/propagators/count_eq_propagator.py +2 -2
- {nucs-3.0.0 → nucs-4.2.0}/nucs/propagators/dummy_propagator.py +2 -2
- nucs-4.2.0/nucs/propagators/element_iv_propagator.py +82 -0
- {nucs-3.0.0 → nucs-4.2.0}/nucs/propagators/element_lic_propagator.py +17 -32
- {nucs-3.0.0 → nucs-4.2.0}/nucs/propagators/element_liv_propagator.py +16 -17
- {nucs-3.0.0 → nucs-4.2.0}/nucs/propagators/exactly_eq_propagator.py +2 -2
- {nucs-3.0.0 → nucs-4.2.0}/nucs/propagators/exactly_true_propagator.py +2 -2
- {nucs-3.0.0 → nucs-4.2.0}/nucs/propagators/gcc_propagator.py +2 -2
- {nucs-3.0.0 → nucs-4.2.0}/nucs/propagators/lexicographic_leq_propagator.py +2 -2
- {nucs-3.0.0 → nucs-4.2.0}/nucs/propagators/max_eq_propagator.py +2 -2
- {nucs-3.0.0 → nucs-4.2.0}/nucs/propagators/max_leq_propagator.py +11 -5
- {nucs-3.0.0 → nucs-4.2.0}/nucs/propagators/min_eq_propagator.py +2 -2
- {nucs-3.0.0 → nucs-4.2.0}/nucs/propagators/min_geq_propagator.py +11 -5
- nucs-4.2.0/nucs/propagators/no_sub_cycle_propagator.py +78 -0
- {nucs-3.0.0 → nucs-4.2.0}/nucs/propagators/propagators.py +21 -8
- {nucs-3.0.0 → nucs-4.2.0}/nucs/propagators/relation_propagator.py +2 -2
- nucs-4.2.0/nucs/propagators/scc_propagator.py +75 -0
- {nucs-3.0.0 → nucs-4.2.0}/nucs/solvers/backtrack_solver.py +159 -106
- {nucs-3.0.0 → nucs-4.2.0}/nucs/solvers/bound_consistency_algorithm.py +38 -29
- nucs-4.2.0/nucs/solvers/choice_points.py +133 -0
- {nucs-3.0.0 → nucs-4.2.0}/nucs/solvers/multiprocessing_solver.py +10 -7
- {nucs-3.0.0 → nucs-4.2.0}/nucs/solvers/shaving_consistency_algorithm.py +36 -25
- {nucs-3.0.0 → nucs-4.2.0}/nucs/solvers/solver.py +3 -49
- {nucs-3.0.0 → nucs-4.2.0}/pyproject.toml +1 -1
- {nucs-3.0.0 → nucs-4.2.0}/tests/examples/test_alpha.py +1 -1
- {nucs-3.0.0 → nucs-4.2.0}/tests/examples/test_bibd.py +3 -3
- {nucs-3.0.0 → nucs-4.2.0}/tests/examples/test_donald.py +1 -1
- {nucs-3.0.0 → nucs-4.2.0}/tests/examples/test_golomb.py +2 -7
- {nucs-3.0.0 → nucs-4.2.0}/tests/examples/test_knapsack.py +1 -1
- {nucs-3.0.0 → nucs-4.2.0}/tests/examples/test_magic_sequence.py +6 -2
- {nucs-3.0.0 → nucs-4.2.0}/tests/examples/test_magic_square.py +1 -1
- {nucs-3.0.0 → nucs-4.2.0}/tests/examples/test_quasigroup.py +1 -1
- {nucs-3.0.0 → nucs-4.2.0}/tests/examples/test_queens.py +1 -1
- {nucs-3.0.0 → nucs-4.2.0}/tests/examples/test_sports_tournament_scheduling.py +1 -1
- nucs-4.2.0/tests/examples/test_tsp.py +47 -0
- nucs-4.2.0/tests/heuristics/test_max_value_dom_heuristic.py +24 -0
- nucs-4.2.0/tests/heuristics/test_mid_value_dom_heuristic.py +24 -0
- nucs-4.2.0/tests/heuristics/test_min_value_dom_heuristic.py +24 -0
- nucs-4.2.0/tests/problems/__init__.py +0 -0
- nucs-4.2.0/tests/problems/test_circuit_problem.py +36 -0
- nucs-4.2.0/tests/propagators/__init__.py +0 -0
- {nucs-3.0.0 → nucs-4.2.0}/tests/propagators/test_affine_eq.py +1 -1
- {nucs-3.0.0 → nucs-4.2.0}/tests/propagators/test_affine_geq.py +1 -1
- {nucs-3.0.0 → nucs-4.2.0}/tests/propagators/test_affine_leq.py +1 -1
- nucs-4.2.0/tests/propagators/test_element_iv.py +36 -0
- {nucs-3.0.0 → nucs-4.2.0}/tests/propagators/test_element_liv.py +5 -0
- nucs-4.2.0/tests/propagators/test_no_sub_cycle.py +27 -0
- nucs-4.2.0/tests/propagators/test_scc.py +32 -0
- nucs-4.2.0/tests/solvers/__init__.py +0 -0
- {nucs-3.0.0 → nucs-4.2.0}/tests/solvers/test_backtrack_solver.py +43 -3
- {nucs-3.0.0 → nucs-4.2.0}/tests/solvers/test_multiprocessing_solver.py +28 -23
- nucs-3.0.0/nucs/solvers/choice_points.py +0 -88
- nucs-3.0.0/nucs/solvers/heuristics.py +0 -193
- {nucs-3.0.0 → nucs-4.2.0}/LICENSE.md +0 -0
- {nucs-3.0.0 → nucs-4.2.0}/NUCS.egg-info/dependency_links.txt +0 -0
- {nucs-3.0.0 → nucs-4.2.0}/NUCS.egg-info/requires.txt +0 -0
- {nucs-3.0.0 → nucs-4.2.0}/NUCS.egg-info/top_level.txt +0 -0
- {nucs-3.0.0 → nucs-4.2.0}/README.md +0 -0
- {nucs-3.0.0 → nucs-4.2.0}/nucs/__init__.py +0 -0
- {nucs-3.0.0 → nucs-4.2.0}/nucs/examples/__init__.py +0 -0
- {nucs-3.0.0 → nucs-4.2.0}/nucs/examples/alpha/__init__.py +0 -0
- {nucs-3.0.0 → nucs-4.2.0}/nucs/examples/bibd/__init__.py +0 -0
- {nucs-3.0.0 → nucs-4.2.0}/nucs/examples/bibd/bibd_problem.py +0 -0
- {nucs-3.0.0 → nucs-4.2.0}/nucs/examples/donald/__init__.py +0 -0
- {nucs-3.0.0 → nucs-4.2.0}/nucs/examples/golomb/__init__.py +0 -0
- {nucs-3.0.0 → nucs-4.2.0}/nucs/examples/knapsack/__init__.py +0 -0
- {nucs-3.0.0 → nucs-4.2.0}/nucs/examples/knapsack/knapsack_problem.py +0 -0
- {nucs-3.0.0 → nucs-4.2.0}/nucs/examples/magic_sequence/__init__.py +0 -0
- {nucs-3.0.0 → nucs-4.2.0}/nucs/examples/magic_square/__init__.py +0 -0
- {nucs-3.0.0 → nucs-4.2.0}/nucs/examples/magic_square/magic_square_problem.py +0 -0
- {nucs-3.0.0 → nucs-4.2.0}/nucs/examples/quasigroup/__init__.py +0 -0
- {nucs-3.0.0 → nucs-4.2.0}/nucs/examples/quasigroup/quasigroup_problem.py +0 -0
- {nucs-3.0.0 → nucs-4.2.0}/nucs/examples/queens/__init__.py +0 -0
- {nucs-3.0.0 → nucs-4.2.0}/nucs/examples/queens/queens_problem.py +0 -0
- {nucs-3.0.0 → nucs-4.2.0}/nucs/examples/schur_lemma/__init__.py +0 -0
- {nucs-3.0.0 → nucs-4.2.0}/nucs/examples/schur_lemma/schur_lemma_problem.py +0 -0
- {nucs-3.0.0 → nucs-4.2.0}/nucs/examples/sports_tournament_scheduling/__init__.py +0 -0
- {nucs-3.0.0 → nucs-4.2.0}/nucs/examples/sports_tournament_scheduling/sports_tournament_scheduling_problem.py +0 -0
- {nucs-3.0.0 → nucs-4.2.0}/nucs/examples/sudoku/__init__.py +0 -0
- {nucs-3.0.0/nucs/problems → nucs-4.2.0/nucs/examples/tsp}/__init__.py +0 -0
- {nucs-3.0.0/nucs/propagators → nucs-4.2.0/nucs/heuristics}/__init__.py +0 -0
- {nucs-3.0.0 → nucs-4.2.0}/nucs/numba_helper.py +0 -0
- {nucs-3.0.0/nucs/solvers → nucs-4.2.0/nucs/problems}/__init__.py +0 -0
- {nucs-3.0.0 → nucs-4.2.0}/nucs/problems/latin_square_problem.py +0 -0
- {nucs-3.0.0/tests → nucs-4.2.0/nucs/propagators}/__init__.py +0 -0
- {nucs-3.0.0/tests/problems → nucs-4.2.0/nucs/solvers}/__init__.py +0 -0
- {nucs-3.0.0 → nucs-4.2.0}/nucs/solvers/consistency_algorithms.py +0 -0
- {nucs-3.0.0 → nucs-4.2.0}/setup.cfg +0 -0
- {nucs-3.0.0/tests/propagators → nucs-4.2.0/tests}/__init__.py +0 -0
- {nucs-3.0.0 → nucs-4.2.0}/tests/examples/test_latin_square.py +0 -0
- {nucs-3.0.0 → nucs-4.2.0}/tests/examples/test_schur_lemma.py +0 -0
- {nucs-3.0.0 → nucs-4.2.0}/tests/examples/test_sudokus.py +0 -0
- {nucs-3.0.0/tests/solvers → nucs-4.2.0/tests/heuristics}/__init__.py +0 -0
- {nucs-3.0.0 → nucs-4.2.0}/tests/problems/test_problem.py +0 -0
- {nucs-3.0.0 → nucs-4.2.0}/tests/propagators/test_alldifferent.py +0 -0
- {nucs-3.0.0 → nucs-4.2.0}/tests/propagators/test_count_eq.py +0 -0
- {nucs-3.0.0 → nucs-4.2.0}/tests/propagators/test_element_lic.py +0 -0
- {nucs-3.0.0 → nucs-4.2.0}/tests/propagators/test_exactly_eq.py +0 -0
- {nucs-3.0.0 → nucs-4.2.0}/tests/propagators/test_gcc.py +0 -0
- {nucs-3.0.0 → nucs-4.2.0}/tests/propagators/test_lexicographic_leq.py +0 -0
- {nucs-3.0.0 → nucs-4.2.0}/tests/propagators/test_max_eq.py +0 -0
- {nucs-3.0.0 → nucs-4.2.0}/tests/propagators/test_max_leq.py +0 -0
- {nucs-3.0.0 → nucs-4.2.0}/tests/propagators/test_min_eq.py +0 -0
- {nucs-3.0.0 → nucs-4.2.0}/tests/propagators/test_min_geq.py +0 -0
- {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
|
+
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
|
+
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
|
|
@@ -14,12 +14,28 @@ import os
|
|
|
14
14
|
|
|
15
15
|
from numba import bool, int32, int64, types, uint8, uint16 # type: ignore
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
|
|
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
|
-
|
|
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[:], #
|
|
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
|
|
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.
|
|
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(
|
|
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 =
|
|
33
|
-
|
|
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:
|
|
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:
|
|
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
|
-
|
|
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.
|
|
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(
|
|
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[
|
|
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[
|
|
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
|
-
|
|
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
|
-
|
|
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("
|
|
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
|
-
|
|
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
|
)
|