1
0
This repository has been archived on 2025-03-06. You can view files and clone it, but cannot push or open issues or pull requests.

78 lines
2.4 KiB
MiniZinc

%-----------------------------------------------------------------------------%
% Radiation problem, MiniZinc 2.0.4 version
%
%-----------------------------------------------------------------------------%
%-----------------------------------------------------------------------------%
% Parameters
%-----------------------------------------------------------------------------%
int: m; % Rows
int: n; % Columns
set of int: Rows = 1..m;
set of int: Columns = 1..n;
% Intensity matrix
array[Rows, Columns] of int: Intensity;
set of int: BTimes = 1..Bt_max;
int: Bt_max = max(i in Rows, j in Columns) (Intensity[i,j]);
int: Ints_sum = sum(i in Rows, j in Columns) (Intensity[i,j]);
%-----------------------------------------------------------------------------%
% Variables
%-----------------------------------------------------------------------------%
% Total beam-on time
var 0..Ints_sum: Beamtime;
% Number of shape matrices
var 0..m*n: K;
% N[b] is the number of shape matrices with associated beam-on time b
array[BTimes] of var 0..m*n: N;
% Q[i,j,b] is the number of shape matrices with associated beam-on time
% b that expose cell (i,j)
array[Rows, Columns, BTimes] of var 0..m*n: Q;
%-----------------------------------------------------------------------------%
% Constraints
%-----------------------------------------------------------------------------%
% For FD/LP hybrid solving, all these should go the LP solver
% (with a suitable linearisation of the 'max' expressions).
constraint
Beamtime = sum(b in BTimes) (b * N[b])
/\
K = sum(b in BTimes) (N[b])
/\
forall(i in Rows, j in Columns)
( Intensity[i,j] = sum([b * Q[i,j,b] | b in BTimes]) )
/\
forall(i in Rows, b in BTimes)
( upper_bound_on_increments(N[b], [Q[i,j,b] | j in Columns]) );
predicate upper_bound_on_increments(var int: N_b, array[int] of var int: L) =
N_b >= L[1] + sum([ max(L[j] - L[j-1], 0) | j in 2..n ]);
%
% Good linear version:
% let { array[min(index_set(L))..max(index_set(L))] of var int: S } in
% N_b >= L[1] + sum([ S[j] | j in 2..n ]) /\
% forall([ S[j] >= L[j] - L[j-1] /\ S[j] >= 0 | j in 2..n ]);
%-----------------------------------------------------------------------------%
output [
"Beamtime = \(Beamtime);\n",
"K = \(K);\n",
"N = \(N);\n",
"Q = array3d(\(Rows), \(Columns), \(BTimes), \(Q));\n"
];
%-----------------------------------------------------------------------------%