I use MiniZinc to create matrix and I would like to create the same matrix as "assignment" but the value at a certain point is should be greater than one. For example:
assignment =
[| Allegro: eBay:
| Node1: 1, 2
| Node2: 2, 1
| Node3: 1, 2
| Node4: 1, 3
| Node5: 1, 1
|];
assignment_add_container =
[| Allegro: eBay:
| Node1: 1, 2
| Node2: 2, 2
| Node3: 1, 2
| Node4: 1, 3
| Node5: 1, 1
|];
So my question is, how can I refer to an element in a matrix?
this is my code:
enum Servers = {Node1, Node2, Node3, Node4, Node5};
enum Services = {Allegro, eBay};
array[Servers, Services] of var 0..5: assignment;
array[Servers, Services] of var 0..5: assignment_add_container;
constraint forall(server in Servers, service in Services)
(assignment_add_container[server, service] = assignment[server, service])
;
constraint assignment_add_container[Node2, eBay] = assignment_add_container[Node2, eBay] 1
;
but I got error: MiniZinc: type error: undefined identifier `Node2'
I also tried sth like this
constraint assignment_add_container[2, 2] = assignment_add_container[2, 2] 1
But I got MiniZinc: type error: array index 1 must be 'Servers', but is `int'
CodePudding user response:
As for Axel, I don't get any Node2 errors message in MiniZinc 2.6.4 (Linux).
Here's is a way of increasing one of the values by 1 (for server=Node2 and service=eBay). The main point is that you must exclude the Node2/eBay from the plain copying, which is here done using if/then/endif
. The model assumes that the matrix assignment
contains fixed values.
enum Servers = {Node1, Node2, Node3, Node4, Node5};
enum Services = {Allegro, eBay};
array[Servers, Services] of 0..5: assignment;
array[Servers, Services] of var 0..5: assignment_add_container;
constraint forall(server in Servers, service in Services )
(
if server = Node2 /\ service = eBay then
assignment_add_container[Node2, eBay] = assignment[Node2, eBay] 1
else
assignment_add_container[server, service] = assignment[server, service]
endif
)
;
assignment =
[| Allegro: eBay:
| Node1: 1, 2
| Node2: 2, 1
| Node3: 1, 2
| Node4: 1, 3
| Node5: 1, 1
|];
This results in this solution:
assignment_add_container =
[| Allegro: eBay:
| Node1: 1, 2
| Node2: 2, 2
| Node3: 1, 2
| Node4: 1, 3
| Node5: 1, 1
|];
----------
==========
One other way would be to use where
in the forall
loop to exclude the special assignment, and have a separate constraint for incrementing the value:
% ...
forall(server in Servers, service in Services where not (server = Node2 /\ service = eBay) ) (
assignment_add_container[Node2, eBay] = assignment[Node2, eBay] 1
)
;
constraint assignment_add_container[Node2, eBay] = assignment[Node2, eBay] 1 ;