git-subtree-dir: software/minizinc git-subtree-split: 4f10c82056ffcb1041d7ffef29d77a7eef92cf76
241 lines
7.5 KiB
MiniZinc
241 lines
7.5 KiB
MiniZinc
/***
|
|
!Test
|
|
check_against: []
|
|
expected:
|
|
- !Result
|
|
solution: !Solution
|
|
last_step: 5
|
|
extra_files: []
|
|
markers: []
|
|
options:
|
|
all_solutions: false
|
|
solvers:
|
|
- gecode
|
|
- cbc
|
|
- chuffed
|
|
type: solve
|
|
|
|
***/
|
|
|
|
% A factory has three kinds of machines:
|
|
% - input machines, where products enter the factory;
|
|
% - output machines, where finished products leave the factory;
|
|
% - work machines, which can hold at most one product and which may
|
|
% add some attributes to that product.
|
|
%
|
|
% A product can move from one machine to another iff there is a direct
|
|
% connection between the two machines (we model staying at a particular
|
|
% machine by making the connection graph reflexive).
|
|
%
|
|
% In this model all actions are assumed to take the same amount of time.
|
|
%
|
|
% The goal is to complete a set of products in the shortest time.
|
|
% XXX Optimisation is currently very expensive; we settle instead
|
|
% for merely finding a consistent solution.
|
|
|
|
% These values must be supplied by a data file.
|
|
%
|
|
int: n_machines; % The number of machines.
|
|
int: n_products; % The number of products.
|
|
int: n_attributes; % The number of attributes.
|
|
int: n_steps; % The number of plan steps.
|
|
|
|
set of int: machines = 1..n_machines;
|
|
set of int: products = 1..n_products;
|
|
set of int: attributes = 1..n_attributes;
|
|
set of int: steps = 1..n_steps;
|
|
|
|
% These values must be supplied by a data file:
|
|
% - input_machines - the set of machines where products can start;
|
|
% - output_machines - the set of machines where products may finish;
|
|
% - connected - the (reflexive) graph of inter-machine connections;
|
|
% - can_add_attr - table of which machines can add which attributes;
|
|
% - prod_attr_goal - table of goal attributes for each product;
|
|
% - prod_start_mach - table of starting machines for each product.
|
|
%
|
|
set of machines: input_machines;
|
|
set of machines: output_machines;
|
|
array [machines, machines] of 0..1: connected;
|
|
array [machines, attributes] of 0..1: can_add_attr;
|
|
array [products, attributes] of 0..1: prod_attr_goal;
|
|
array [products] of input_machines: prod_start_mach;
|
|
|
|
% Decision variables:
|
|
% - step_prod_attr[s, p, a] - at step s, product p has attribute a;
|
|
% - step_prod_mach[s, p] = m - at step s, product p is at machine m;
|
|
% - last_step - the step at which the goal is achieved.
|
|
%
|
|
array [steps, products, attributes] of var 0..1: step_prod_attr;
|
|
array [steps, products] of var machines: step_prod_mach;
|
|
var steps: last_step;
|
|
|
|
% Work machines are those that are neither input machines or output machines.
|
|
%
|
|
set of machines: work_machines =
|
|
machines diff (input_machines union output_machines);
|
|
|
|
% Products start at particular machines.
|
|
%
|
|
constraint
|
|
forall (p in products) (
|
|
step_prod_mach[1, p] = prod_start_mach[p]
|
|
);
|
|
|
|
% Products start with no attributes.
|
|
%
|
|
constraint
|
|
forall (p in products, a in attributes) (
|
|
step_prod_attr[1, p, a] = 0
|
|
);
|
|
|
|
% The attributes of a product at step s are a subset of its
|
|
% attributes at step s+1.
|
|
%
|
|
constraint
|
|
forall (s in steps, p in products, a in attributes where s < n_steps) (
|
|
step_prod_attr[s, p, a] <= step_prod_attr[s + 1, p, a]
|
|
);
|
|
|
|
% No two products can occupy the same work machine at the same step.
|
|
%
|
|
constraint
|
|
forall (s in steps, p, q in products, m in work_machines where p < q) (
|
|
step_prod_mach[s, p] = m -> step_prod_mach[s, q] != m
|
|
);
|
|
|
|
% At t = last_step all goals should be achieved:
|
|
% - each product should have (precisely) its goal set of attributes;
|
|
% - each product should be in an output machine.
|
|
%
|
|
constraint
|
|
forall (p in products, a in attributes) (
|
|
step_prod_attr[last_step, p, a] = prod_attr_goal[p, a]
|
|
);
|
|
|
|
constraint
|
|
forall (p in products) (
|
|
step_prod_mach[last_step, p] in output_machines
|
|
);
|
|
|
|
% Products can only move between directly connected machines.
|
|
%
|
|
constraint
|
|
forall (s in steps, p in products where s < n_steps) (
|
|
connected[step_prod_mach[s, p], step_prod_mach[s + 1, p]] = 1
|
|
);
|
|
|
|
% A product can have an attribute added while at a particular machine.
|
|
%
|
|
constraint
|
|
forall (s in steps, p in products, a in attributes where s < n_steps) (
|
|
step_prod_attr[s + 1, p, a] <=
|
|
step_prod_attr[s, p, a]
|
|
+ can_add_attr[step_prod_mach[s, p], a]
|
|
);
|
|
|
|
% XXX Trying to optimize for last_step currently takes forever, even for
|
|
% relatively simple problems.
|
|
%
|
|
% solve minimize last_step;
|
|
%
|
|
last_step = n_steps;
|
|
% solve satisfy;
|
|
|
|
% Instance data
|
|
|
|
n_machines = 5;
|
|
n_products = 2;
|
|
n_attributes = 3;
|
|
n_steps = 5;
|
|
|
|
input_machines = {1};
|
|
|
|
output_machines = {5};
|
|
|
|
% Connections:
|
|
%
|
|
% M1 --- M2 ----.
|
|
% | | |
|
|
% |----- M3 --- M5
|
|
% | | |
|
|
% '----- M4 ----'
|
|
|
|
connected =
|
|
[| 1, 1, 1, 1, 0,
|
|
| 1, 1, 1, 0, 1,
|
|
| 1, 1, 1, 1, 1,
|
|
| 1, 0, 1, 1, 1,
|
|
| 0, 1, 1, 1, 1
|
|
|];
|
|
|
|
can_add_attr =
|
|
[| 0, 0, 0
|
|
| 1, 0, 0
|
|
| 0, 1, 0
|
|
| 0, 0, 1
|
|
| 0, 0, 0
|
|
|];
|
|
|
|
prod_start_mach = [
|
|
1,
|
|
1
|
|
];
|
|
|
|
prod_attr_goal =
|
|
[| 1, 1, 0
|
|
| 1, 0, 1
|
|
|];
|
|
|
|
solve satisfy;
|
|
|
|
output [
|
|
"factory planning instance\n",
|
|
"step | product | location | a1 a2 a3\n",
|
|
"-----+---------+----------+---------\n",
|
|
" 1 | 1 | ", show(step_prod_mach[1, 1]), " | ",
|
|
show(step_prod_attr[1, 1, 1]), " ",
|
|
show(step_prod_attr[1, 1, 2]), " ",
|
|
show(step_prod_attr[1, 1, 3]), "\n",
|
|
" | 2 | ", show(step_prod_mach[1, 2]), " | ",
|
|
show(step_prod_attr[1, 2, 1]), " ",
|
|
show(step_prod_attr[1, 2, 2]), " ",
|
|
show(step_prod_attr[1, 2, 3]), "\n",
|
|
"-----+---------+----------+---------\n",
|
|
" 2 | 1 | ", show(step_prod_mach[2, 1]), " | ",
|
|
show(step_prod_attr[2, 1, 1]), " ",
|
|
show(step_prod_attr[2, 1, 2]), " ",
|
|
show(step_prod_attr[2, 1, 3]), "\n",
|
|
" | 2 | ", show(step_prod_mach[2, 2]), " | ",
|
|
show(step_prod_attr[2, 2, 1]), " ",
|
|
show(step_prod_attr[2, 2, 2]), " ",
|
|
show(step_prod_attr[2, 2, 3]), "\n",
|
|
"-----+---------+----------+---------\n",
|
|
" 3 | 1 | ", show(step_prod_mach[3, 1]), " | ",
|
|
show(step_prod_attr[3, 1, 1]), " ",
|
|
show(step_prod_attr[3, 1, 2]), " ",
|
|
show(step_prod_attr[3, 1, 3]), "\n",
|
|
" | 2 | ", show(step_prod_mach[3, 2]), " | ",
|
|
show(step_prod_attr[3, 2, 1]), " ",
|
|
show(step_prod_attr[3, 2, 2]), " ",
|
|
show(step_prod_attr[3, 2, 3]), "\n",
|
|
"-----+---------+----------+---------\n",
|
|
" 4 | 1 | ", show(step_prod_mach[4, 1]), " | ",
|
|
show(step_prod_attr[4, 1, 1]), " ",
|
|
show(step_prod_attr[4, 1, 2]), " ",
|
|
show(step_prod_attr[4, 1, 3]), "\n",
|
|
" | 2 | ", show(step_prod_mach[4, 2]), " | ",
|
|
show(step_prod_attr[4, 2, 1]), " ",
|
|
show(step_prod_attr[4, 2, 2]), " ",
|
|
show(step_prod_attr[4, 2, 3]), "\n",
|
|
"-----+---------+----------+---------\n",
|
|
" 5 | 1 | ", show(step_prod_mach[5, 1]), " | ",
|
|
show(step_prod_attr[5, 1, 1]), " ",
|
|
show(step_prod_attr[5, 1, 2]), " ",
|
|
show(step_prod_attr[5, 1, 3]), "\n",
|
|
" | 2 | ", show(step_prod_mach[5, 2]), " | ",
|
|
show(step_prod_attr[5, 2, 1]), " ",
|
|
show(step_prod_attr[5, 2, 2]), " ",
|
|
show(step_prod_attr[5, 2, 3]), "\n",
|
|
"-----+---------+----------+---------\n"
|
|
];
|