简体   繁体   中英

How to make operations on index in matrix

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'

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 ;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM