/*** !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" ];