Archived
1
0

Add code to perform pareto search

This commit is contained in:
Jip J. Dekker 2021-12-22 11:52:20 +11:00
parent 4bc44838a4
commit ad9e85aa2d
No known key found for this signature in database
GPG Key ID: 517DF4A00618C9C3
5 changed files with 206 additions and 2 deletions

View File

@ -30,6 +30,7 @@ array[Patient] of var bool: first_detected = [
| pt in Patient
];
% --- Constraint ---
% The DLMO should be detected on the second round (if not detected on the first round)
@ -42,12 +43,16 @@ constraint forall (pt in Patient) (
);
% --- Objective ---
solve minimize
% solve minimize
% Pareto Front objectives
var int: total_tests ::output =
% Number of tests on first round
(length(Patient) * first_num_samples)
% Number of test on second round
+ (count(pt in Patient) (not first_detected[pt]) * second_num_samples);
var int: total_not_detected ::output = length(Patient) - count(first_detected);
% --- Output ---
output ["First Round:\n"]
@ -57,7 +62,7 @@ output ["First Round:\n"]
++ ["\n\nSecond Round:\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\nTotal number of tests = \(total_tests);"]
++ ["\n\n\nfirst_sample = \(first_sample);\n"]

54
pareto.py Normal file
View File

@ -0,0 +1,54 @@
import minizinc
def pareto_front(instance, objectives):
front = []
result = None
with instance.branch() as instance:
failed = False
while not failed:
result = instance.solve()
# print(result)
# print("----------------------------------------")
if result == None or result.status == minizinc.Status.UNSATISFIABLE:
failed = True
else:
to_remove = []
for i in range(len(front)):
if all([result[o] <= front[i][o] for o in objectives]):
to_remove.append(i)
# print(to_remove[::-1])
for r in to_remove[::-1]:
front.pop(r)
instance.add_string(
"constraint "
+ " \/ ".join([f"{o} < {result[o]}" for o in objectives])
+ ";\n"
)
front.append(result)
return front
if __name__ == "__main__":
inst = minizinc.Instance(
minizinc.Solver.lookup("chuffed"), minizinc.Model("dlmo.mzn")
)
inst.add_file("full.dzn")
front = pareto_front(inst, ["total_tests", "total_not_detected"])
for sol in front:
print(
",".join(
[
str(sol["total_tests"]),
str(sol["total_not_detected"]),
str(sol["first_sample"]),
str(sol["first_num_samples"]),
str(sol["second_num_samples"]),
]
)
)
print("----------------------------------------------------")
for sol in front:
print(sol)

109
pareto_front.txt Normal file
View File

@ -0,0 +1,109 @@
792,82,-3,3,3
845,39,-4,4,3
958,24,-4,5,2
979,23,-5,5,3
1108,8,-5,6,2
1274,0,-5,7,8
----------------------------------------------------
First Round:
-5 -4 -3 -2 -1 0 1 2
|----|----|====|====|----|----|----|
First try (%): 54.94505494505495
Second Round:
-5 -4 -3 -2 -1 0 1 2
|====|====|----|----|====|====|----|
Total number of tests = 792;
first_sample = -3;
first_num_samples = 3;
second_num_samples = 3;
First Round:
-5 -4 -3 -2 -1 0 1 2
|----|====|====|====|----|----|----|
First try (%): 78.57142857142857
Second Round:
-5 -4 -3 -2 -1 0 1 2
|====|----|----|----|====|====|----|
Total number of tests = 845;
first_sample = -4;
first_num_samples = 4;
second_num_samples = 3;
First Round:
-5 -4 -3 -2 -1 0 1 2
|----|====|====|====|====|----|----|
First try (%): 86.81318681318682
Second Round:
-5 -4 -3 -2 -1 0 1 2
|====|----|----|----|----|====|----|
Total number of tests = 958;
first_sample = -4;
first_num_samples = 5;
second_num_samples = 2;
First Round:
-5 -4 -3 -2 -1 0 1 2
|====|====|====|====|----|----|----|
First try (%): 87.36263736263736
Second Round:
-5 -4 -3 -2 -1 0 1 2
|----|----|----|----|====|====|----|
Total number of tests = 979;
first_sample = -5;
first_num_samples = 5;
second_num_samples = 3;
First Round:
-5 -4 -3 -2 -1 0 1 2
|====|====|====|====|====|----|----|
First try (%): 95.60439560439561
Second Round:
-5 -4 -3 -2 -1 0 1 2
|----|----|----|----|----|====|----|
Total number of tests = 1108;
first_sample = -5;
first_num_samples = 6;
second_num_samples = 2;
First Round:
-5 -4 -3 -2 -1 0 1 2
|====|====|====|====|====|====|----|
First try (%): 100.0
Second Round:
-5 -4 -3 -2 -1 0 1 2
|----|----|----|----|----|----|====|
Total number of tests = 1274;
first_sample = -5;
first_num_samples = 7;
second_num_samples = 8;

21
poetry.lock generated Normal file
View File

@ -0,0 +1,21 @@
[[package]]
name = "minizinc"
version = "0.5.0"
description = "Access MiniZinc directly from Python"
category = "main"
optional = false
python-versions = ">=3.6"
[package.extras]
dzn = ["lark-parser (>=0.7.5)"]
[metadata]
lock-version = "1.1"
python-versions = "^3.8"
content-hash = "49ec9364d3548273c0b3fdc5f79b951566db8dd93f01d69b758811a0f578da22"
[metadata.files]
minizinc = [
{file = "minizinc-0.5.0-py3-none-any.whl", hash = "sha256:678f6cc5894290960aef63df143033912541050c17912bf1fd5d28d814eb3d74"},
{file = "minizinc-0.5.0.tar.gz", hash = "sha256:d60580d9c71cb8a8d819f117803f1ab922907367f3d09aaf9e2e0c668ccc38ac"},
]

15
pyproject.toml Normal file
View File

@ -0,0 +1,15 @@
[tool.poetry]
name = "dlmo-model"
version = "0.1.0"
description = ""
authors = ["Jip J. Dekker <jip@dekker.one>"]
[tool.poetry.dependencies]
python = "^3.8"
minizinc = "^0.5.0"
[tool.poetry.dev-dependencies]
[build-system]
requires = ["poetry-core>=1.0.0"]
build-backend = "poetry.core.masonry.api"