@@ -11,7 +11,7 @@ const MOIU = MOI.Utilities
11
11
12
12
include (" options.jl" )
13
13
14
- CS = ConstraintSolver
14
+ const CS = ConstraintSolver
15
15
16
16
mutable struct Variable
17
17
idx :: Int
@@ -21,15 +21,14 @@ mutable struct Variable
21
21
last_ptr :: Int
22
22
values :: Vector{Int}
23
23
indices :: Vector{Int}
24
- offset :: Int
25
- min :: Int # the minimum value during the solving process
24
+ offset :: Int
25
+ min :: Int # the minimum value during the solving process
26
26
max :: Int # for initial see lower/upper_bound
27
27
changes :: Vector{Vector{Tuple{Symbol,Int64,Int64,Int64}}}
28
- has_upper_bound :: Bool # must be true to work
29
- has_lower_bound :: Bool # must be true to work
28
+ has_upper_bound :: Bool # must be true to work
29
+ has_lower_bound :: Bool # must be true to work
30
30
is_fixed :: Bool
31
- is_integer :: Bool # must be true to work
32
-
31
+ is_integer :: Bool # must be true to work
33
32
end
34
33
35
34
Variable (idx) = Variable (idx,0 ,0 ,0 ,0 ,[],[],0 ,0 ,0 ,Vector {Vector{Tuple{Symbol,Int64,Int64,Int64}}} (), false , false , false , false )
@@ -42,18 +41,19 @@ mutable struct CSInfo
42
41
backtrack_reverses :: Int
43
42
end
44
43
45
- abstract type Constraint
46
- end
44
+ abstract type Constraint end
47
45
48
- abstract type ObjectiveFunction
49
- end
46
+ abstract type ObjectiveFunction end
50
47
51
48
mutable struct SingleVariableObjective <: ObjectiveFunction
52
49
fct :: Function
53
50
index :: Int # index of the variable
54
51
indices :: Vector{Int}
55
52
end
56
53
54
+ # used to designate a feasibility sense
55
+ struct NoObjective <: ObjectiveFunction end
56
+
57
57
mutable struct BasicConstraint <: Constraint
58
58
idx :: Int
59
59
fct :: Function
@@ -79,7 +79,7 @@ struct AllDifferentSet <: MOI.AbstractVectorSet
79
79
dimension :: Int64
80
80
end
81
81
82
- struct NotEqualSet{T} <: MOI.AbstractScalarSet
82
+ struct NotEqualSet{T} <: MOI.AbstractScalarSet
83
83
value :: T
84
84
end
85
85
@@ -134,21 +134,19 @@ end
134
134
mutable struct ConstraintSolverModel
135
135
init_search_space :: Vector{Variable}
136
136
search_space :: Vector{Variable}
137
- subscription :: Vector{Vector{Int}}
137
+ subscription :: Vector{Vector{Int}}
138
138
constraints :: Vector{Constraint}
139
139
bt_infeasible :: Vector{Int}
140
140
c_backtrack_idx :: Int
141
141
backtrack_vec :: Vector{BacktrackObj}
142
142
sense :: MOI.OptimizationSense
143
143
objective :: ObjectiveFunction
144
144
best_sol :: Int # Objective of the best solution
145
- best_bound :: Int # Overall best bound
145
+ best_bound :: Int # Overall best bound
146
146
solutions :: Vector{Int} # saves only the id to the BacktrackObj
147
147
info :: CSInfo
148
148
input :: Dict{Symbol,Any}
149
149
logs :: Vector{TreeLogNode}
150
-
151
- ConstraintSolverModel () = new ()
152
150
end
153
151
154
152
const CoM = ConstraintSolverModel
@@ -167,27 +165,32 @@ include("equal.jl")
167
165
include (" not_equal.jl" )
168
166
169
167
"""
170
- init ()
168
+ ConstraintSolverModel ()
171
169
172
- Initialize the constraint model object
170
+ Create the constraint model object.
173
171
"""
174
- function init ()
175
- com = CoM ()
176
- com. constraints = Vector {Constraint} ()
177
- com. subscription = Vector {Vector{Int}} ()
178
- com. init_search_space = Vector {Variable} ()
179
- com. search_space = Vector {Variable} ()
180
- com. bt_infeasible = Vector {Int} ()
181
- com. c_backtrack_idx = 1
182
- com. sense = MOI. FEASIBILITY_SENSE
183
- com. backtrack_vec = Vector {BacktrackObj} ()
184
- com. solutions = Vector {Int} ()
185
- com. info = CSInfo (0 , false , 0 , 0 , 0 )
186
- com. input = Dict {Symbol, Bool} ()
187
- com. logs = Vector {TreeLogNode} ()
188
- return com
172
+ function ConstraintSolverModel ()
173
+ ConstraintSolverModel (
174
+ Vector {Variable} (), # init_search_space
175
+ Vector {Variable} (), # search_space
176
+ Vector {Vector{Int}} (), # subscription
177
+ Vector {Constraint} (), # constraints
178
+ Vector {Int} (), # bt_infeasible
179
+ 1 , # c_backtrack_idx
180
+ Vector {BacktrackObj} (), # backtrack_vec
181
+ MOI. FEASIBILITY_SENSE, #
182
+ NoObjective (), #
183
+ 0 , # best_sol,
184
+ 0 , # best_bound
185
+ Vector {Int} (), # solutions
186
+ CSInfo (0 , false , 0 , 0 , 0 ), # info
187
+ Dict {Symbol,Any} (), # input
188
+ Vector {TreeLogNode} () # logs
189
+ )
189
190
end
190
191
192
+ @deprecate init () ConstraintSolverModel ()
193
+
191
194
"""
192
195
add_var!(com::CS.CoM, from::Int, to::Int; fix=nothing)
193
196
@@ -246,7 +249,7 @@ function fixed_vs_unfixed(search_space, indices)
246
249
push! (unfixed_indices, i)
247
250
end
248
251
end
249
- return fixed_vals, unfixed_indices
252
+ return ( fixed_vals, unfixed_indices)
250
253
end
251
254
252
255
"""
@@ -438,7 +441,7 @@ function prune!(com::CS.CoM; pre_backtrack=false, all=false, only_once=false, in
438
441
else
439
442
com. info. pre_backtrack_calls += 1
440
443
end
441
-
444
+
442
445
if ! feasible
443
446
break
444
447
end
@@ -535,26 +538,26 @@ function checkout_from_to!(com::CS.CoM, from_idx::Int, to_idx::Int)
535
538
from = backtrack_vec[from_idx]
536
539
to = backtrack_vec[to_idx]
537
540
if to. parent_idx == from. idx
538
- return
541
+ return
539
542
end
540
543
reverse_pruning! (com, from. idx)
541
-
544
+
542
545
prune_steps = Vector {Int} ()
543
546
# first go to same level if new is higher in the tree
544
547
if to. depth < from. depth
545
548
depth = from. depth
546
549
parent_idx = from. parent_idx
547
550
parent = backtrack_vec[parent_idx]
548
551
while to. depth < depth
549
- reverse_pruning! (com, parent_idx)
552
+ reverse_pruning! (com, parent_idx)
550
553
parent = backtrack_vec[parent_idx]
551
554
parent_idx = parent. parent_idx
552
555
depth -= 1
553
556
end
554
557
if parent_idx == to. parent_idx
555
558
return
556
559
else
557
- from = parent
560
+ from = parent
558
561
end
559
562
elseif from. depth < to. depth
560
563
depth = to. depth
@@ -567,7 +570,7 @@ function checkout_from_to!(com::CS.CoM, from_idx::Int, to_idx::Int)
567
570
depth -= 1
568
571
end
569
572
570
-
573
+
571
574
to = parent
572
575
if backtrack_vec[prune_steps[1 ]]. parent_idx == from. parent_idx
573
576
prune! (com, prune_steps)
@@ -578,7 +581,7 @@ function checkout_from_to!(com::CS.CoM, from_idx::Int, to_idx::Int)
578
581
# same diff but different parent
579
582
# => level up until same parent
580
583
while from. parent_idx != to. parent_idx
581
- reverse_pruning! (com, from. parent_idx)
584
+ reverse_pruning! (com, from. parent_idx)
582
585
from = backtrack_vec[from. parent_idx]
583
586
584
587
pushfirst! (prune_steps, to. parent_idx)
@@ -617,10 +620,10 @@ function update_best_bound!(backtrack_obj::BacktrackObj, com::CS.CoM, constraint
617
620
com. info. backtrack_reverses += 1
618
621
return false , false
619
622
end
620
-
623
+
621
624
# check best_bound again
622
- # if best bound unchanged => continue pruning
623
- # otherwise try another path but don't close the current
625
+ # if best bound unchanged => continue pruning
626
+ # otherwise try another path but don't close the current
624
627
# -> means open new paths from here even if not pruned til the end
625
628
new_bb = get_best_bound (com)
626
629
if backtrack_obj. best_bound != new_bb
@@ -639,7 +642,7 @@ Return :Solved or :Infeasible if proven or `:NotSolved` if interrupted by `max_b
639
642
function backtrack! (com:: CS.CoM , max_bt_steps; sorting= true )
640
643
found, ind = get_weak_ind (com)
641
644
com. info. backtrack_fixes = 1
642
-
645
+
643
646
pvals = reverse! (values (com. search_space[ind]))
644
647
dummy_backtrack_obj = BacktrackObj ()
645
648
dummy_backtrack_obj. status = :Close
@@ -649,7 +652,7 @@ function backtrack!(com::CS.CoM, max_bt_steps; sorting=true)
649
652
backtrack_vec = com. backtrack_vec
650
653
push! (backtrack_vec, dummy_backtrack_obj)
651
654
652
- # the first solve (before backtrack) has idx 1
655
+ # the first solve (before backtrack) has idx 1
653
656
num_backtrack_objs = 1
654
657
step_nr = 1
655
658
for pval in pvals
@@ -679,9 +682,9 @@ function backtrack!(com::CS.CoM, max_bt_steps; sorting=true)
679
682
step_nr += 1
680
683
# get next open backtrack object
681
684
l = 1
682
-
685
+
683
686
# if there is no objective or sorting is set to false
684
- if com. sense == MOI. FEASIBILITY_SENSE || ! sorting
687
+ if com. sense == MOI. FEASIBILITY_SENSE || ! sorting
685
688
l = length (backtrack_vec)
686
689
backtrack_obj = backtrack_vec[l]
687
690
while backtrack_obj. status != :Open
@@ -741,7 +744,7 @@ function backtrack!(com::CS.CoM, max_bt_steps; sorting=true)
741
744
ind = backtrack_obj. variable_idx
742
745
743
746
com. c_backtrack_idx = backtrack_obj. idx
744
-
747
+
745
748
if ! started
746
749
com. c_backtrack_idx = 0
747
750
checkout_from_to! (com, last_backtrack_id, backtrack_obj. idx)
@@ -777,7 +780,7 @@ function backtrack!(com::CS.CoM, max_bt_steps; sorting=true)
777
780
778
781
further_pruning = true
779
782
# first update the best bound (only constraints which have an index in the objective function)
780
- if com. sense != MOI. FEASIBILITY_SENSE
783
+ if com. sense != MOI. FEASIBILITY_SENSE
781
784
feasible, further_pruning = update_best_bound! (backtrack_obj, com, constraints)
782
785
783
786
if ! feasible
@@ -789,17 +792,17 @@ function backtrack!(com::CS.CoM, max_bt_steps; sorting=true)
789
792
if further_pruning
790
793
# prune completely start with all that changed by the fix or by updating best bound
791
794
feasible = prune! (com)
792
-
795
+
793
796
if ! feasible
794
797
com. info. backtrack_reverses += 1
795
798
continue
796
799
end
797
800
end
798
-
801
+
799
802
800
803
found, ind = get_weak_ind (com)
801
804
# no index found => solution found
802
- if ! found
805
+ if ! found
803
806
new_sol = get_best_bound (com)
804
807
if length (com. solutions) == 0
805
808
com. best_sol = new_sol
@@ -809,7 +812,7 @@ function backtrack!(com::CS.CoM, max_bt_steps; sorting=true)
809
812
push! (com. solutions, backtrack_obj. idx)
810
813
if com. best_sol == com. best_bound
811
814
return :Solved
812
- else
815
+ else
813
816
# set all nodes to :Worse if they can't achieve a better solution
814
817
for bo in backtrack_vec
815
818
if bo. status == :Open && obj_factor* bo. best_bound >= com. best_sol
@@ -824,12 +827,12 @@ function backtrack!(com::CS.CoM, max_bt_steps; sorting=true)
824
827
return :NotSolved
825
828
end
826
829
827
-
830
+
828
831
829
832
if com. input[:logs ]
830
833
com. logs[backtrack_obj. idx] = log_one_node (com, length (com. search_space), backtrack_obj. idx, step_nr)
831
834
end
832
-
835
+
833
836
pvals = reverse! (values (com. search_space[ind]))
834
837
last_backtrack_obj = backtrack_vec[last_backtrack_id]
835
838
for pval in pvals
@@ -858,7 +861,7 @@ function backtrack!(com::CS.CoM, max_bt_steps; sorting=true)
858
861
end
859
862
end
860
863
if length (com. solutions) > 0
861
- # find one of the best solutions
864
+ # find one of the best solutions
862
865
sol, sol_id = findmin ([backtrack_vec[sol_id]. best_bound* obj_factor for sol_id in com. solutions])
863
866
backtrack_id = com. solutions[sol_id]
864
867
checkout_from_to! (com, last_backtrack_id, backtrack_id)
@@ -901,7 +904,7 @@ function simplify!(com)
901
904
end
902
905
if b_all_different_sum && b_sum
903
906
# for each all_different constraint
904
- # which can be formulated as a sum constraint
907
+ # which can be formulated as a sum constraint
905
908
# check which sum constraints are completely inside all different
906
909
# which are partially inside
907
910
# compute inside sum and total sum
@@ -934,7 +937,7 @@ function simplify!(com)
934
937
if ! haskey (cons_indices_dict, sub_variable_idx)
935
938
all_inside = false
936
939
push! (outside_indices, sub_variable_idx)
937
- else
940
+ else
938
941
delete! (cons_indices_dict, sub_variable_idx)
939
942
end
940
943
end
@@ -949,7 +952,7 @@ function simplify!(com)
949
952
break
950
953
end
951
954
end
952
-
955
+
953
956
# make sure that there are not too many outside indices
954
957
if add_sum_constraint && length (outside_indices) < 3
955
958
add_constraint! (com, sum (com. search_space[outside_indices]) == total_sum - all_diff_sum)
@@ -993,7 +996,7 @@ function solve!(com::CS.CoM, options::SolverOptions)
993
996
if length (com. constraints) == 0
994
997
return :Solved
995
998
end
996
-
999
+
997
1000
backtrack = options. backtrack
998
1001
max_bt_steps = options. max_bt_steps
999
1002
backtrack_sorting = options. backtrack_sorting
@@ -1015,7 +1018,7 @@ function solve!(com::CS.CoM, options::SolverOptions)
1015
1018
if ! feasible
1016
1019
return :Infeasible
1017
1020
end
1018
-
1021
+
1019
1022
if all (v-> isfixed (v), com. search_space)
1020
1023
com. best_bound = get_best_bound (com)
1021
1024
com. best_sol = com. best_bound
@@ -1028,7 +1031,7 @@ function solve!(com::CS.CoM, options::SolverOptions)
1028
1031
push! (com. logs, log_one_node (com, length (com. search_space), 1 , 1 ))
1029
1032
end
1030
1033
1031
- if ! feasible
1034
+ if ! feasible
1032
1035
return :Infeasible
1033
1036
end
1034
1037
0 commit comments