N Rectangles inside the Square (Minizinc) - minizinc

I try to place N rectangular blocks with different sizes into a grid, by formulating it as a CSP problem.
The blocks should not overlap with each other, they can touch on the edges, and there can be
empty places.
with requirement place 4 rectangular blocks of size 2x2 into a 8x8 grid.
I also need to generalize for varying the number of blocks, the sizes of the blocks, and the size of the grid.
I dont understand how I use this terms in codes.
include "globals.mzn";
int: nParts;
set of int: PARTS = 1..nParts;
int: nShapes;
set of int: SHAPES = 1..nShapes;
int: plateLength;
int: plateWidth;
set of int: LEN = 0..plateLength;
set of int: WID = 0..plateWidth;
int: k = 2;
set of int: DIM = 1..k;
array[SHAPES,DIM] of int: rect_size;
array[SHAPES,DIM] of 0..0: rect_offset;
array[PARTS] of set of SHAPES: shape;
array[PARTS,DIM] of var int: xy;
array[PARTS] of var SHAPES: kind;
constraint geost(k, rect_size, rect_offset, shape, xy, kind);
constraint forall(i in PARTS)(kind[i] in shape[i]);
constraint forall(i in PARTS)(xy[i,1] in LEN);
constraint forall(i in PARTS)(xy[i,1] + rect_size[kind[i], 1] in LEN);
constraint forall(i in PARTS)(xy[i,2] in WID);
constraint forall(i in PARTS)(xy[i,2] + rect_size[kind[i], 2] in WID);

First of all you should use diffn global constraint that is specially suited for this kind of problems. I think it has stronger propagation than geost. Second, if you use geost use a solver that support it natively (JaCoP, Choco or Sicstus).
Check also benchmark perfect_square form this year minizinc chgallenge.

Related

Big performance differences between solvers

I have a working model with its associated dzn files. I have tried different solvers (Gurobi, ORTools & Chuffed). All solvers can find a solution (for now, I'm only using solve satisfy;.
However, if I increase the problem size, Gurobi & ORTools cannot find a solution in a reasonable amount of time (> 25 min) whereas Chuffed find a solution within 1 to 2 min.
For ORTools I have these stats, but cannot find a solution within 25 min.
Flattening ...
CompilePass: Flatten with /Applications/MiniZincIDE.app/Contents/Resources/share/minizinc//' library ...
MIP domains ... done (298.16 s)
Optimizing ... done (314.31 s)
Converting to old FlatZinc ... done (352.18 s)
done (352.18 s)
done (352.38 s), max stack depth 32
I am using default settings for solvers. What would you recommend ? What could explain such big differences between Chuffed & Gurobi/ORTools ?
Thanks for your hints.
PS: here is the model
include "globals.mzn";
%-----------------------------------------------------------------------------%
% MODEL PARAMETERS
% Tasks
int: n_tasks; % The number of tasks
set of int: Tasks = 1..n_tasks; % The set of all tasks
array[Tasks] of int : duration ; % The task durations
array[Tasks] of set of int: predecessor; % The task successors
array [Tasks, 1..2] of int: early_late_start; % early late start bouding information
% Resources
int: n_resources;
set of int: Resources = 1..n_resources;
array[Tasks] of set of int: resource_needed; % The resource requirements
array[Tasks] of set of int: resource_forbidden; % The resource requirements
array[Tasks] of int: number_resource_needed; % The resource requirements
% Maximum duration
int: t_max;
%-----------------------------------------------------------------------------%
%~~~~~~~~~~~~~~~~~
% MODEL VARIABLES.
%~~~~~~~~~~~~~~~~~
array [Tasks] of var 1..t_max: start; % The start times
array[Tasks, Resources] of var 0..1: resource_allocation; %Selection of resources per task.
%-----------------------------------------------------------------------------%
%-----------------------------------------------------------------------------%
%~~~~~~~~~~~~~~~~~
% CONSTRAINTS
%~~~~~~~~~~~~~~~~~
%~~~~~~~~~~~~~~~~~
% Resource Allocation Constraints
%~~~~~~~~~~~~~~~~~
% Mandatory & Forbidden constraint allocation
constraint forall(t in Tasks, r in resource_needed[t])(resource_allocation[t,r]=1);
constraint forall(t in Tasks, r in resource_forbidden[t])(resource_allocation[t,r]=0);
% Number of Resources per Task constraint
constraint forall(t in Tasks) (
sum(r in Resources) (resource_allocation[t, r]) = number_resource_needed[t]
);
% Constraint allocated to only one task at a time
constraint forall(r in Resources)(
cumulative(start, duration, [resource_allocation[t, r] | t in Tasks], 1)
);
%constraint cumulative(start, duration, [ sum(r in Resources)(resource_allocation[t,r]) | t in Tasks ],
% 1 );
%~~~~~~~~~~~~~~~~~
% Task Scheduling
%~~~~~~~~~~~~~~~~~
% Early Start / Late Start
constraint forall(i in Tasks)(
early_late_start[i, 1]<= start[i] /\ start[i] <= early_late_start[i, 2]
);
% Precedence constraint
constraint
forall(i in Tasks, j in predecessor[i])(
start[j]+duration[j]<= start[i]
);
% Max Time constraint
constraint forall(i in Tasks)(
start[i] + duration[i] <= t_max
);
solve satisfy;

Referring to decision variable arrays in MiniZinc functions

I'd like to find the permutation steps that lead from the initial state to a required state. The decision variable array Steps is intended to record the permutation steps, encoded as integers. My approach is to constrain the values of Steps so that "replaying" the permutations identified by them on the initial state yields the
arranged state, represented by State. In order to select from various permutations, I'd have to refer to the items of Steps in a conditional expression, which results in a type error.
int : nrItems;
int : nrMaxSteps;
nrItems = 3;
nrMaxSteps = 10;
array [1..nrItems] of int : State;
State = [2,1,3];
array [1..nrMaxSteps] of var 0..4 : Steps;
% 0 - empty step for solutions shorter than nrMaxSteps
%**********************************************
% permute the initial state
function array [1..nrItems] of int: permute() =
% apply permutations on the initial state
% depending on the values of Steps
if(Steps[1] == 1) ... select permutation1
%**********************************************
predicate arranged() =
let { array [1..nrItems] of int : permuted = permute(); }
in permuted[1] == State[1] /\ permuted[2] == State[2] /\ permuted[3] == State[3];
constraint
arranged();
solve satisfy;
What would be the right approach here?

Support for pow() with decision variables in MiniZinc

I am trying to build a model with a decision variable that takes the range 0..10 with the constraint
that it must be divisible by 4.The output must be the one that minimizes the value (x-7)^2. Investigating I see that Gecode already supports it.
I have tried to build the model as follows but I get an error using the built-in pow()
% Decision variable
var 0..10: x;
% Constraints
constraint (x mod 4) == 0;
% Call to the resolver
int: obj = pow(x-7, 2);
solve minimize obj;
% Solution
output["x = ", show(x), "\nobj = ", show(obj)];
I get the following error:
MiniZinc: type error: initialisation value for `obj' has invalid type-inst: expected `int', actual `var int'
I think it occurs because is considering the variable as a decision variable instead of just an integer parameter.
#hankank's solution is correct. Using var int: obj = pow(x-7, 2);
Variables (e.g., var int) in MiniZinc are decision variables and other names (which you might call variables in Python) are referred to as parameters (e.g., par int or int). These are two distinct types for a good reason: any calculation with only parameter is guaranteed to be able to be executed during MiniZinc compilation, while any calculation that uses a variable will generally have to be decided by a solver.
Note, that using pow actually might also bring problems for linear solver (i.e., MIP solvers). In this case the calculation can still be made linear because the transformation is using a constant, but the expression pow(x,y) where both arguments are variables could not be decided by a linear solver.
To move the pow() call from solution time to compilation time, you could use a pre-calculated array:
% Decision variable
var 0..10: x;
set of int: DomainX = 0..10;
array[DomainX] of int: xa = array1d(DomainX, [pow(i-7, 2) | i in DomainX]);
% Constraints
constraint (x mod 4) == 0;
% Call to the resolver
var int: obj = xa[x];
solve minimize obj;
% Solution
output["x = ", show(x), "\nobj = ", show(obj)];
As commented by hakank, variable obj must be of type var int, as it depends on a decision variable.

Mixed-Integer Nearest Optimal Solution in Matlab

Is it possible to find the nearest solution to optimal for a mixed-integer problem? For example I would want the simplified problem below:
f = [1;1;1];
intcon = 1:3;
Aeq = [0.99,0.97,0.15];
beq = 0.16;
lb = zeros(3,1);
ub = [1;1;1];
x = intlinprog(f,intcon,[],[],Aeq,beq,lb,ub)
to return x=[0;0;1] as this is the nearest integer solution to the objective value of 0.16. Instead currently it returns
Intlinprog stopped because no point satisfies the constraints.
Does not necessarily have to run intlinprog. Would ideally need to also work if beq is low, for example 0.14.
You can introduce some slack variables to allow some constraint violation when needed as follows:
largeValue = 100; % choose some large value to penalise the constraint violation
f_ = [f; largeValue; largeValue]; % penalise both slack variables
Aeq_ = [Aeq, 1, -1]; % add a positive and negative slack variable to the constraint
beq_ = beq;
lb_ = [lb; 0; 0]; % limit the constraint to a positive number
ub_ = [ub; inf; inf];
x_ = intlinprog(f_,intcon,[],[],Aeq_,beq_,lb_,ub_); % solve the adapted problem
x = x_(1:3) % extract the solution of the original problem
Remarks
I added two (positive) slack variables, one for a positive constraint violation and another one for a negative constraint violation.
You should penalise the slack variables with a large value, otherwise it is beneficial to violate your constraints more than strictly necessary. A more general approach would be to determine a good penalisation value based on the values in f and Aeq, for example
largeValue = 2*max(abs(f))/min(abs(Aeq(Aeq ~= 0)))

Is there any way to add perturbation to a variable in Matlab?

I have a 101x82 size matrix called A. I am trying to minimize an objective function obj_fun, whose value is computed indirectly using A.
Now in order to minimize this objective function obj_fun, I need to perturb the values of A. I want to check if obj_fun is going down in values or not. If not, then I need to do perturb/change values of A to a certain percentage such that it minimizes obj_fun. Keep on perturbing/changing values of A until we get minimum obj_fun. My average value of A before any perturbation is ~ 1.1529e+003.
Does any one have suggestion how can I do this? Also, I care a bit about speed i.e. the method/algorithm should not be too slow. Thanks.
You can add random Gaussian noise to A:
A = 0; % seed value for A with something more interesting than 0
best = obj_fun(A);
for iter = 1:max_iter % max_iter should be the maximum number of iterations
newA = A + normrnd(0, 1, size(A));
newObj = obj_fun(A);
if( newObj < best )
best = newObj;
A = newA;
end
end