Hi Luca.
Something is strange with this.
As the model stand, none of solvers (SAT, CP, MIP, SMT) give any solution to the optimization problem using
% ...
NumBoxes #= sum([1 : R in 1 .. MaxBoxes, sum( [Boxes[R,I] : I in 1 ..N])#=0]),
Vars = Boxes ++ {NumBoxes},
solve($[max(NumBoxes),report(printf("NumBoxes: %w\n",NumBoxes))],Vars),
However, with some adjustment of the domain of Boxes as well as commenting the disjunction constraint in the loop, then the CP solver - but only the CP solver - yields a solution. Here are the changes:
%
% Boxes :: 0 .. MaxEl, % ORIG
Boxes :: [0] ++ MinEl..MaxEl, % hakank
% check range boxes
foreach(I in 1 .. MaxBoxes)
Sum #= sum([Boxes[I,J] : J in 1 .. N]),
% (Sum #=0 #\/ (Sum #>=MinEl #/\ Sum #<=MaxEl)), % hakank: Commenting this.
end,
% ...
The CP solver gives the optimal value of NumBoxes of 66 (in 0.06s), which seems to be correct (I checked it with a more complex model).
But, no other solver give any solution.
Here's my complete version:
"""
% import sat, util. % no solution
import cp, util. % gives a solution
% import mip, util. % no solution
% import smt, util. % no solution
main =>
MaxEl =300, % max number of element in a box
MinEl=60, % min number of element in a box
Articles = [ ['A', 1000], %code article , number of elements
['B', 400],
['C', 150],
['D', 500],
['E', 500],
['F', 500],
['G', 500],
['H', 500],
['I', 100] ],
N=Articles.length,
ArticlesT=Articles.transpose(),
NumArticles=sum([ArticlesT[2,I] : I in 1.. N]),
println(num_articles=NumArticles),
MaxBoxes=ceiling(NumArticles / MinEl),
println(max_boxes=MaxBoxes),
Boxes = new_array(MaxBoxes,N),
% Boxes :: 0 .. MaxEl, % ORIG
Boxes :: [0] ++ MinEl..MaxEl, % hakank
%check all element in boxes
foreach(I in 1.. N)
ArticlesT[2,I] #= sum( [Boxes[R,I] : R in 1 .. MaxBoxes])
end,
% check range boxes
foreach(I in 1 .. MaxBoxes)
Sum #= sum([Boxes[I,J] : J in 1 .. N]),
% (Sum #=0 #\/ (Sum #>=MinEl #/\ Sum #<=MaxEl)), % hakank: Commented this
end,
%maximize empty boxes
NumBoxes #= sum([1 : R in 1 .. MaxBoxes, sum( [Boxes[R,I] : I in 1 ..N])#=0]),
Vars = Boxes,
println(solve=NumBoxes),
solve($[max(NumBoxes),report(printf("NumBoxes: %w\n",NumBoxes))],Vars),
println(sum_filled=sum([1 : R in 1 .. MaxBoxes, sum( [Boxes[R,I] : I in 1 ..N])>0])),
println(num_boxes=NumBoxes),
println(Boxes).
"""
The output is:
"""
num_articles = 4150
max_boxes = 70
solve = 66
NumBoxes: 66
sum_filled = 4
num_boxes = 66
{{0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0},{100,0,0,0,0,0,0,0,0},{300,0,0,0,0,0,0,0,0},{300,100,0,200,200,200,200,200,0},{300,300,150,300,300,300,300,300,100}}
"""
Perhaps Neng-Fa can give some light on this?
Best,
Hakan