Skip to content

Commit

Permalink
MiniZinc: added kidney_exchange_model.mzn self_referential_sentence.mzn
Browse files Browse the repository at this point in the history
  • Loading branch information
hakank committed Jul 13, 2014
1 parent 201ae8b commit 52c34f2
Show file tree
Hide file tree
Showing 3 changed files with 162 additions and 1 deletion.
4 changes: 3 additions & 1 deletion minizinc/index.html
Expand Up @@ -631,6 +631,7 @@ <h3>Puzzles, small, and large</h3>
<li> <a href="secret_santa.mzn">secret_santa.mzn</a>: Secret Santa problem
<li> <a href="secret_santa2.mzn">secret_santa2.mzn</a>: Another Secret Santa problem
<li> <a href="self_referential_quiz.mzn">self_referential_quiz.mzn</a>: Self-referential quiz
<li> <a href="self_referential_sentence.mzn">self_referential_sentence.mzn</a>: Self-referential sentence
<li> <a href="send_more_money.mzn">send_more_money.mzn</a>: Alphametic puzzle: SEND + MORE = MONEY
<li> <a href="send_more_money2.mzn">send_more_money2.mzn</a>: Alphametic puzzle: SEND + MORE = MONEY, alternative model
<li> <a href="send_more_money_any_base.mzn">send_more_money_any_base.mzn</a>: Alphametic puzzle: SEND + MORE = MONEY, in any base
Expand Down Expand Up @@ -1038,7 +1039,8 @@ <h3>Combinatorial problems</h3>
<li> <a href="k_consecutive_integers.mzn">k_consecutive_integers.mzn</a>: k consecutive integers (Stack Overflow: <a href=" http://stackoverflow.com/questions/18550915/k-consecutive-integers-constraint">k consecutive integers constraint</a>)
<li> <a href="kidney_exchange.mzn">kidney_exchange.mzn</a>: Simple kidney exchange model (inspired by Pascal Van Hentenryck's introduction to the Coursera Course "Discrete Optimization")
<a name="kidney_exchange">
<li> <a href="kidney_exchange2.mzn">kidney_exchange2.mzn</a>: Kidney exchange model (for .dzn files)<br>
<li> <a href="kidney_exchange2.mzn">kidney_exchange2.mzn</a>: Kidney exchange model<br>
Faster version: <a href="kidney_exchange_model.mzn">kidney_exchange_model.mzn</a>:<br>
Data files:
<ul>
<li> <a href="kidney_exchange_pascal.dzn">kidney_exchange_pascal.dzn</a>
Expand Down
109 changes: 109 additions & 0 deletions minizinc/kidney_exchange_model.mzn
@@ -0,0 +1,109 @@
%
% Kidney exchange in MiniZinc.
%
% A simple model of kidney exchange, inspired by Pascal Van Hentenryck's
% introduction of the Coursera Course Discrete Optimization.
%
% The objective is to maximize the number of kidney exchanges given
% the compatible
%
% Note that we are looking for cycles, which means that a person receiving
% a kidney must be able to give a kidney.
%

%
% This MiniZinc model was created by Hakan Kjellerstrand, hakank@gmail.com
% See also my MiniZinc page: http://www.hakank.org/minizinc/
%

include "globals.mzn";

int: num_people;
array[1..num_people] of set of int: compatible;

% people that has no no potential donors (and can't get a kidney)
set of 1..num_people: non_compatible = { p | p in 1..num_people where card(compatible[p]) = 0 };

% The domains for each person
array[1..num_people] of set of int:
compatible_pruned = [
if card(compatible[p]) = 0 then {p} else (compatible[p] diff non_compatible) union {p} endif
| p in 1..num_people ];

%
% decision variables
%

% which kidney does person p get (or p if he/she gets no kidney)
array[1..num_people] of var 1..num_people: x;

var 0..num_people: z = sum([bool2int(x[i] != i) | i in 1..num_people]);

% solve satisfy;
% solve maximize z;
solve :: int_search(
x,
first_fail,
indomain_median,
complete)
maximize z;

% Just allow the compatible people (+ p) in the domains
% and remove uncompatible people.
constraint
forall(p in 1..num_people) (
x[p] in compatible_pruned[p]
)
/\
alldifferent(x)

% experimental: first test if all are donors (-> circuit)
%
% works in MiniZinc v2.0, at least for some solvers.
/\ (circuit(x) \/ true)
;

output [
"z: " ++ show(z) ++ "\n" ++
"x: " ++ show(x) ++ "\n"
]
++
[
"person: donor\n"
]
++
[
if fix(x[i] = i) then
show_int(3, i) ++ ": -\n"
else
show_int(3, i) ++ ": " ++ show_int(3, x[i]) ++ "\n"
endif
| i in 1..num_people
]
++
[
show(x) ++ "\n"
++ "z: " ++ show(z) ++ "\n"
];


%
% data
%

% The compatibility matrix
% (from Pascal's introduction lecture)
% who can give a kidney to person p
% This is a directed graph
% num_people = 8;
% compatible =
% [
% {2,3}, % 1
% {1,6}, % 2
% {1,4,7}, % 3
% {2}, % 4
% {2}, % 5
% {5}, % 6
% {8}, % 7
% {3}, % 8
% ];
50 changes: 50 additions & 0 deletions minizinc/self_referential_sentence.mzn
@@ -0,0 +1,50 @@
%
% Self referential sentence in MiniZinc.
%
% E.g. from
% http://puzzling.stackexchange.com/questions/1901/write-a-true-self-reflective-statement-about-the-digits-from-0-to-9-or-prove-it
%
% "This statement contains 1 0's, 7 1's, 3 2's, 2 3's, 1 4's, 1 5's, 1 6's, 2 7's, 1 8's, and 1 9's."
%
% Note: It happens that the number of occurrences of the digits are between 1..9
% so we don't have to worry about converting 10 to 1,0 etc.

%
% This MiniZinc model was created by Hakan Kjellerstrand, hakank@gmail.com
% See also my MiniZinc page: http://www.hakank.org/minizinc/
%

include "globals.mzn";

int: b = 9; % base
int: n = 2*(b+1);

% decision variables
array[1..n] of var 0..b: x;


solve satisfy;
% solve :: int_search(x, first_fail, indomain_min, complete) satisfy;

constraint
% The digits 0..b are placed in positions x[i*2+1].
% Ensure that it is x[i*2+2] occurrences of the digit i
forall(i in 0..b) (
x[i*2+1] = i
/\
count(x,i,x[i*2+2])
)
;

output
[
"x: ", show(x), "\n",
"This statement contains "
]
++
[
show(x[i*2+2]) ++ " " ++ show(x[i*2+1]) ++ "'s, " ++
if i == b-1 then "and " else "" endif
| i in 0..b
];

0 comments on commit 52c34f2

Please sign in to comment.