Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update 100potions.dzn with nicer comments #17

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 9 additions & 7 deletions CP/optimization/100potions.dzn
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
n = 100; %Water Number
w = 8; %Window Size
p = 140; %Leaves required in each Window
capacity= 380; %Total Energy we have for using holy Water
m= 4; %Mode numbers
% Data for "The Strongest YaoCao", 100 potions

n = 100; % Number of potions
w = 8; % Window size
p = 140; % Min number of "leaves on all segments in a window" (actual value must be >= p)
capacity = 380; % Max capacity of nutrients available for any branch (i.e. path) from root node to outermost node
m = 4; % Max number of segments grown at each node (i.e. max branching factor)

nutrient =
[|6,5,381,381
Expand Down Expand Up @@ -107,7 +109,7 @@ nutrient =
|4,381,381,381
|];

leave =
leaf =
[|68,36,0,0
|18,48,32,0
|83,90,18,0
Expand Down Expand Up @@ -208,4 +210,4 @@ leave =
|93,35,0,0
|6,3,51,0
|19,0,0,0
|];
|];
16 changes: 9 additions & 7 deletions CP/optimization/4potions.dzn
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
n = 4;
m = 4;
w = 2;
p = 8;
capacity= 19;
% Data for "The Strongest YaoCao", 4 potions

n = 4; % Number of potions
w = 2; % Window size
p = 8; % Min number of "leaves on all segments in a window" (actual value must be >= p)
capacity = 19; % Max capacity of nutrients available for any branch (i.e. path) from root node to outermost node
m = 4; % Max number of segments grown at each node (i.e. max branching factor)

nutrient =
[|4,2,3,7
Expand All @@ -11,9 +13,9 @@ nutrient =
|3,6,2,20
|];

leave =
leaf =
[|7,6,4,8
|5,8,0,0
|5,4,7,0
|6,9,3,0
|];
|];
159 changes: 132 additions & 27 deletions CP/optimization/yaocao.mzn
Original file line number Diff line number Diff line change
@@ -1,44 +1,149 @@
int: n; % number of potions
set of int: POTIONS = 1..n;
int: w; % window size
int: p; % num of leaves in each window
int: capacity; % capacity of nutrients
int: m; % max number of grown segments
% ===
% "The Strongest YaoCao"
% ===

% Grow (or explore) a tree.
%
% The root node has level 1.
% We need to reach level n (the number of potions) at which
% YaoCao grows. The best YaoCao is the one with the most
% leaves-on-segments over the branch (the "branch" is the path
% through the tree, consisting of "segments")
% The potions are used "in order" so "tree height" (or "tree level")
% and "potion number" are equivalent (the potion x is applied to
% each node at level x equally)
% The choice is the selection of the segment to follow from each node.
% At each node, the potion determines the "branching factor"
% (the number of outgoing segments) as well as the number of leaves
% on each segment and the nutrient requirements on each segment.
% Along a branch (path through the tree), the total nutrient
% requirements of each segment must stay below a maximum.
% Along a branch, the total number of leaves of on the segments
% belonging to any "window" (a continuous series of segments of
% the branch, with the number of segments fixed) must stay above
% a minimum.

% ---
% Given
% ---

int: n; % Number of potions
int: w; % Window size
int: p; % Min number of leaves-on-segments required in a window (actual value must be >= p)
int: capacity; % Max capacity of nutrients available for any branch/path from root node to outermost node
int: m; % Max number of segments grown at each node (max branching factor)

set of int: POTIONS = 1..n;
set of int: SEGMENTS = 1..m;

array[POTIONS,SEGMENTS] of int: nutrient; % nutrient required
array[POTIONS,SEGMENTS] of int: leave; % num of leaves to grow
% Nutrients required by segment x if the node
% was expanded with potion y
% (capacity+1 if segment does not exist)

array[POTIONS,SEGMENTS] of int: nutrient;

% Number of leaves that will to grow on
% segment x if the node was expanded with potion y
% (0 if segment does not exist)

array[POTIONS] of var SEGMENTS: choice; %Choice of segment for each potion
array[POTIONS] of var int: nutrient_list =
array[POTIONS,SEGMENTS] of int: leaf;

% ---
% Sought
% ---

% The branch (i.e. the path through the tree): which segment to select at
% every height "x" (equivalent to potion "x") of the tree

array[POTIONS] of var SEGMENTS: choice;

% The list of nutrients needed over the branch/path implied by "choice"

array[POTIONS] of var int: nutrient_list =
[nutrient[i,choice[i]] | i in POTIONS];
array[POTIONS] of var int: leave_list =
[leave[i,choice[i]] | i in POTIONS];

% The list of leaves-on-segments over the branch/path implied by "choice"

array[POTIONS] of var int: leave_list =
[leaf[i,choice[i]] | i in POTIONS];

var int: total_nutrient = sum(nutrient_list);
var int: total_leaves = sum(leave_list);

constraint assert(n>=w,"Window Size larger than # of steps");
constraint assert(w<=n,"Window size must be <= than number of potions");

% Nutrients required by the full branch/path may not exceed capacity

%Capacity
constraint total_nutrient <= capacity;
%In each window, leave numbers should be larger than p

% Number of leaves-on-segments in any window on the branch/path must be >= p

constraint forall(tail in w..n)
(sum(i in tail-w+1..tail)(leave_list[i]) >= p);

% ---
% Solving
% ---

solve :: ssearch2 maximize total_leaves;

ann: search1 = int_search(leave_list, input_order, indomain_min, complete);
ann: search2 = int_search(leave_list, input_order, indomain_max, complete);
ann: search3 = int_search(leave_list, largest, indomain_min, complete);
ann: search4 = int_search(leave_list, largest, indomain_max, complete);
ann: search5 = int_search(leave_list, smallest, indomain_min, complete);
ann: search6 = int_search(leave_list, smallest, indomain_max, complete);
% search4: finds optimum (6443 for "100 potions") in least time (seconds)
% search6: finds optimum, a bit slower than largest+max (seconds)
% search5: finds optimum, rather slower than smallest+max (a few minutes)
% searchTL: fix a high leaf value, then see whether it can be realized,
% finds optimum in a few minutes
% search2: finds optimum, rather slower than smallest+min (multiple minutes)
% search1: does not find optimum within 15 mins
% search3: finds worst value within 15 mins
%
% ssearch1: redundant sequential search equivalent to search 1 alone
% ssearch2: optimistic search: set the total leaves to a high value, then
% search for a branch/path that matches (finds optimum in about a minute)

ann: search1 = int_search(leave_list, input_order, indomain_min);
ann: search2 = int_search(leave_list, input_order, indomain_max);
ann: search3 = int_search(leave_list, largest, indomain_min);
ann: search4 = int_search(leave_list, largest, indomain_max);
ann: search5 = int_search(leave_list, smallest, indomain_min);
ann: search6 = int_search(leave_list, smallest, indomain_max);

ann: searchTL = int_search([total_leaves], input_order, indomain_max);

ann: ssearch1 = seq_search([search1,searchTL]);
ann: ssearch2 = seq_search([searchTL,search1]);

% ---
% Info output
% ---

function string: braced(SEGMENTS: s, SEGMENTS: chosen, int: val) =
if s == chosen then
if val<10 then " [" ++ show(val) ++ "]"
elseif val<100 then " [" ++ show(val) ++ "]"
else "[" ++ show(val) ++ "]"
endif
else
if val<10 then " " ++ show(val) ++ " "
elseif val<100 then " " ++ show(val) ++ " "
else " " ++ show(val) ++ " "
endif
endif;

output ["% Number of potions: \(n)\n" ];
output ["% Min leaves-on-segments required in a window of size \(w): \(p)\n" ];
output ["% Max capacity of nutrients available for any branch: \(capacity)\n" ];
output ["% Nutrients needed by each of the up to \(m) segments:\n"];
output ["% Potion " ++ show_int(3,i) ++ ": " ++
join(",", [ braced(s,fix(choice[i]),nutrient[i,s]) | s in SEGMENTS where nutrient[i,s]<=capacity ]) ++ "\n"
| i in POTIONS ];
output ["% Leaves grown on each of the up to \(m) segments:\n"];
output ["% Potion " ++ show_int(3,i) ++ ": " ++
join(",", [ braced(s,fix(choice[i]),leaf[i,s]) | s in SEGMENTS where leaf[i,s]>0]) ++ "\n"
| i in POTIONS ];
output ["\n"];

ann: ssearch1 = seq_search([search1,
int_search([total_leaves], input_order, indomain_max, complete) ]);
ann: ssearch2 = seq_search([
int_search([total_leaves], input_order, indomain_max, complete),
search1 ]);
% ---
% Solution output
% ---

output ["choice = ",show(choice),";\n","total_leaves = ",show(total_leaves),";\n","total_nutrient = ", show(total_nutrient)];
output ["choice = \(choice);\ntotal_leaves = \(total_leaves);\ntotal_nutrient = \(total_nutrient);\n"];