I have a table of Projects with 4 features (name, value, cost, people). I want to describe a model in Minizinc that selects the projects that maximize the total value but with a total budget of 255 and I can choose almost 9 projects between 20.
I write a data file: data.dzn
% name value cost people
data = [
| PRJ0, 6000, 35, 5
| PRJ1, 4000, 34, 3
| PRJ2, 1000, 26, 4
...
| PRJ20, 1200, 18, 2
|];
PRJ = {PRJ0,...,PRJ20};
FEATURE = {name, value, budget, personnel};
max_budget = 225;
max_prj=9;
So my constraints are:
choose_project <= 9 /\ budget<=255 s.t solve maximize tot_value;
How can I select a non-arbitrary number (1 to 9) of decision variables among projects raw in the table? Until now this is my code: invest.mzn
include "data.dzn";
int: max_budget; %255
int: max_prj; %9
enum FEATURE;
enum PRJ;
array[PRJ,FEATURE] of int: data;
constraint ...
...
solve maximize tot_value;
You can declare an array of Boolean variables, say selected_projects
, that encodes whether or not a project PRJ_k
is selected or not.
Then you can simply count how many projects in this array are being selected at the same time.
Example:
enum FEATURE = {name, value, budget, personnel};
enum PRJ = { PRJ0, PRJ1 };
array[PRJ,FEATURE] of int: data =
[| PRJ0, 6000, 35, 5
| PRJ1, 4000, 34, 3
|];
array[PRJ] of var bool: selected_projects;
var int: tot_value;
% The total number of selected projects must be in [1, 9]
constraint let {
var int: tot_selected = sum(prj in PRJ) ( selected_projects[prj] )
} in
1 <= tot_selected /\ tot_selected <= 9;
constraint tot_value = sum(prj in PRJ) ( selected_projects[prj] * data[prj, value] );
% ...
% encoding of budget and personnel constraints
% ...
solve maximize tot_value;