Home > OS >  How to make operations on index in matrix
How to make operations on index in matrix

Time:01-09

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 ;
  • Related