Archived
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.
dlmo-model/dlmo.mzn

66 lines
3.0 KiB
MiniZinc

% --- Data quantities ---
enum Patient; % Patients for which samples have been taken
set of int: Horizon = -5..2; % (Relative) sampling times
% --- Data input ---
float: DLMO_threshold = 13.043;
array[Patient, Horizon] of float: sample;
% --- Derived data ---
% For each patient: after which sample could we stop and have found dlmo? (occasion must then include `critical_test[PT]` and its successor to catch it).
array[Patient] of var Horizon: critical_sample = [ min([i | i in -5..1 where sample[pt, i] <= DLMO_threshold /\ sample[pt, i+1] >= DLMO_threshold]) | pt in Patient];
% --- Decisions ---
% First occasion:
var Horizon: first_sample; % When to start sampling on the first occasion
var 1..length(Horizon)-1: first_num_samples; % How many samples to take on the first occasion
% Second occasion:
var 1..length(Horizon)-1: second_num_samples; % How many samples to take on the second occasion
% (Assumption: If the levels were to high in all samples during the first occasion, then we sample `second_num_samples` ending with the `first_sample`.
% If the levels were to low in all samples during the first occasion, then we sample `second_num_samples` from `first_sample + first_num_samples`.)
% --- Decision Consequences ---
% For each patient: will their DLMO be detected on the first occasion?
array[Patient] of var bool: first_detected = [
critical_sample[pt] >= first_sample /\ critical_sample[pt] + 1 <= first_sample + (first_num_samples - 1)
| pt in Patient
];
% --- Constraint ---
% The DLMO should be detected on the second occasion (if not detected on the first occasion)
constraint forall (pt in Patient) (
first_detected[pt]
% Before first occasion
\/ (critical_sample[pt] >= first_sample - (second_num_samples - 1) /\ critical_sample[pt] + 1 <= first_sample)
% After first occasion
\/ (critical_sample[pt] >= first_sample + (first_num_samples - 1) /\ critical_sample[pt] + 1 <= first_sample + (first_num_samples - 1) + (second_num_samples - 1))
);
% --- Objective ---
solve minimize
% Number of tests on first occasion
(length(Patient) * first_num_samples)
% Number of test on second occasion
+ (count(pt in Patient) (not first_detected[pt]) * second_num_samples);
% --- Output ---
output ["First Occasion:\n"]
++ [format(2, i) ++ " " | i in Horizon] ++ ["\n |"]
++ [if i in fix(first_sample)..fix(first_sample + (first_num_samples-1) - 1) then "====|" else "----|" endif | i in -5..1]
++ ["\n\nFirst try (%): \(count(first_detected) / length(Patient) * 100)\n"]
++ ["\n\nSecond Occasion:\n"]
++ [format(2, i) ++ " " | i in Horizon] ++ ["\n |"]
++ [if i in fix(first_sample-(second_num_samples-1))..fix(first_sample-1) \/ i in fix(first_sample + (first_num_samples - 1))..fix(first_sample + (first_num_samples - 1) + (second_num_samples - 1) - 1) then "====|" else "----|" endif | i in -5..1]
++ ["\n\nTotal number of tests = \(_objective);"]
++ ["\n\n\nfirst_sample = \(first_sample);\n"]
++ ["first_num_samples = \(first_num_samples);\n"]
++ ["second_num_samples = \(second_num_samples);"];