如何在MiniZinc中对矩阵元素进行索引与操作?
MiniZinc矩阵元素引用问题解决方法
需求说明
需要创建一个与assignment结构完全一致的矩阵assignment_add_container,仅修改其中某个位置的元素值,使其比原矩阵对应位置的值大1。示例如下:
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 |];
问题与报错
尝试通过以下代码实现需求,但遇到类型错误:
初始代码
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 ;
报错信息:MiniZinc: type error: undefined identifier 'Node2'
尝试整数索引的代码
constraint assignment_add_container[2, 2] = assignment_add_container[2, 2] + 1 ;
报错信息:MiniZinc: type error: array index 1 must be 'Servers', but is 'int'
错误原因与解决方法
- 枚举值引用逻辑错误:原约束
assignment_add_container[Node2, eBay] = assignment_add_container[Node2, eBay] + 1是矛盾约束(变量无法等于自身加1),且需明确:当数组索引为自定义枚举类型时,必须用枚举成员作为索引,不能用整数。 - 整数索引不匹配类型:数组的索引类型是自定义枚举
Servers和Services,而非整数,因此整数索引不适用。
正确代码修改
方法一:拆分约束逻辑
先让新矩阵所有元素与原矩阵一致,再单独修改指定位置的值:
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] ); // 修改指定位置:新矩阵值 = 原矩阵对应位置值 +1 constraint assignment_add_container[Node2, eBay] = assignment[Node2, eBay] + 1;
方法二:合并约束逻辑
将通用规则与特殊规则合并,减少遍历次数:
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) ( if server == Node2 && service == eBay then assignment_add_container[server, service] = assignment[server, service] + 1 else assignment_add_container[server, service] = assignment[server, service] endif );
关键要点
- 数组索引类型为自定义枚举时,必须使用枚举成员作为索引,不能用整数。
- 约束逻辑需符合变量赋值规则,避免出现
X = X + 1这类矛盾式约束。
内容的提问来源于stack exchange,提问作者Monica
相关产品推荐
相关产品推荐

