Reputation: 89
I need some help with the following case. let say I have the following code:
enum x= {p,k,m};
enum y= {t1,t2,t3,t4};
array[y] of set of int:against=[{1,3,6},{3,3,6},{6,1,1},{6,3,6}];
array[x] of set of int:attack=[{3,3,6},{6,2,2},{3,1,3}];
array[x] of set of y: NodesD=[{t2,t3},{t2,t3,t4},{t1,t4}];
array[x]of var y: Select;
constraint forall(p in x)(Select[p] in NodesD[p]);
So for each enum of x I should select only on enum of Y. Then I want to select the one that suitable for each set of attack in the following way:
let take the first enum of x {p} which have two possible chooses of y{t2,t3}, so I want to do like this: t2={1,1,6}, t3={6,3,3} so I want to subtract each value in x attack[] {3,3,6} from each value in y against[] and the sum up the results:
{1,1,6}-
{3,3,6}
-----------
{-2,-2,0} then sum them which is equal to -4
then do the same with t2
{6,3,3}-
{3,3,6}
------------
{3,0,-3} which is equal to 0
and in this case, t3 which is equal to 0 is better than t2=-4. I want to do the same for each enum x and Maximize the power. I tried to do it in the following way but it does not work
var int: power = sum(p in x)(card(against[Select[p]])-(card(attack[p])*Select[p]) );
solve maximize power ;
Any help or hint please,:)
Upvotes: 1
Views: 133
Reputation: 971
If you want to make an element by element comparison a matrix is better suited for that than an array of sets, because that way you ensure that both matrixes have the same width and also the syntax is less cumbersome, so instead of summing with an index from 1 to the cardinality of the set you use a different set to sum over the columns of the matrix.
You could calculate the sum of the element wise difference of the sets with
sum(i in 1..min(card(set_A),card(set_B)))(set_A[i] - set_B[i]);
using the min
to be sure that you only iterate over the smallest set and don't access elements that don't exist.
But written like this is cleaner in my opinion, basically, change the {}
of sets for |
to delimit the rows of the matrix in attack
and against
, and add a new variable that will index the columns of the matrix, I called it FRONTS
in this example, so you pick an X
and compare the difference of forces over the different battlefronts.
enum X = {p,k,m};
enum y = {t1,t2,t3,t4};
set of int : FRONTS = 1..3;
array[y,FRONTS] of int : against=[|1,3,6|3,3,6|6,1,1|6,3,6|];
array[X,FRONTS] of int : attack=[|3,3,6|6,2,2|3,1,3|];
array[X] of set of y : nodesD=[{t2,t3},{t2,t3,t4},{t1,t4}];
array[X] of var y : select;
var int: power;
constraint forall(p in X)(select[p] in nodesD[p]);
constraint power = sum(p in X)( sum(i in FRONTS)( against[ select[p], i] - attack[ p, i ] ) );
solve maximize power;
output [show(select) ++ " = " ++ show(power)];
Upvotes: 3