MiniZinc数组中字符串值的索引 [英] Index of string value in MiniZinc array

查看:203
本文介绍了MiniZinc数组中字符串值的索引的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给出一个MiniZinc字符串数组:

Given a MiniZinc array of strings:

int: numStats;
set of int: Stats = 1..numStats;
array[Stats] of string: statNames;

...从MiniZinc数据文件中加载数据:

... with data loaded from a MiniZinc data file:

numStats = 3;
statNames = ["HEALTH", "ARMOR", "MANA"];

如何查找数组中特定字符串的索引?例如,该ARMOR位于位置2.

How can one look up the index of a specific string in the array? For example, that ARMOR is located at position 2.

我需要针对其统计数据的某些限制找到最佳的项目选择.此信息存储在声明为以下内容的2D数组中:

I need to find an optimal selection of items with regard to some constraints on their stats. This information is stored in a 2D array declared as follows:

int: numItems;
set of int: Items = 1..numItems;
array[Items, Stats] of float: itemStats;

因此,为了对通过选定项获得的最小ARMOR写入约束,我需要知道ARMOR在内部数组中具有索引2.

So in order to write a constraint on, say, the minimum amount of ARMOR obtained through the selected items, I need to know that ARMOR has index 2 in the inner array.

由于数据文件是由外部程序生成的,并且统计信息的数量和顺序是动态的,所以我无法对约束中的索引进行硬编码.

Since the data file is generated by an external program, and the number and order of stats are dynamic, I cannot hardcode the indices in the constraints.

MiniZinc教程使用了一个有趣的技巧来实现某些目标相似:

The MiniZinc tutorial uses an interesting trick to achieve something similar:

set of int: Colors = 1..3;
int: red = 1;
int: yellow = 2;
int: blue = 3;
array[Colors] of string: name = ["red", "yellow", "blue"];

var Colors: x;
constraint x != red;
output [ name[fix(x)] ];

不幸的是,由于MiniZinc数据文件中不允许使用变量声明,因此在我的情况下,此技巧不起作用.

Unfortunately, as variable declarations are not allowed in MiniZinc data files, this trick won't work in my case.

推荐答案

您可以编写自己的自定义函数以获取字符串数组中字符串的索引:

You can write your own custom function to get the index of a string within a string array:

function int: getIndexOfString(string: str, 
                               array[int] of string: string_array) = 
   sum(  [ if str = string_array[i] 
              then i
           else 0 endif  
          | i in index_set(string_array) ]
   );

在此函数中,我创建一个整数数组,其中如果位置i处的整数等于str的索引,如果string_array[i]=str处的整数则等于0的索引.例如,对于示例字符串数组["HEALTH", "ARMOR", "MANA"]和str ARMOR,生成的int数组将为[0,2,0].

In this function I create an array of integers where the integer at position i either equals the index of str if string_array[i]=str and 0 otherwise. For instance, for your sample string array ["HEALTH", "ARMOR", "MANA"] and str ARMOR the resulting int array will be [0,2,0].

这就是为什么我可以简单地对int数组求和以获得字符串的索引的原因.如果未出现字符串,则返回值为0,这很好,因为MiniZinc中的索引默认情况下以1开头.

This is why I can simply sum over the int array to get the index of the string. If the string does not occur, the return value is 0, which is fine since indices in MiniZinc start with 1 by default.

在第一个示例中,可以通过以下方法调用上面的函数:

Here is how you can call the function above for your first example:

int: numStats;
set of int: Stats = 1..numStats;
array[Stats] of string: statNames;

numStats = 3;
statNames = ["HEALTH", "ARMOR", "MANA"];

var int: indexOfArmor;

constraint 
   indexOfArmor = getIndexOfString("ARMOR",statNames);  

solve satisfy;  

但是请注意,上面的功能是有限的,并且有一些缺陷.首先,如果在数组中多次出现该字符串,那么您将收到一个无效的索引(str出现的所有索引的总和).另外,如果您为字符串数组设置了自己的索引(例如(2..6)),则需要调整该函数.

Note however that the function above is limited and has some flaws. First, if you have multiple occurrences of the string in the array, then you will receive an invalid index (the sum of all indices where str occurred). Also, if you have your own index set for your string array (say (2..6)), then you will need to adapt the function.

这篇关于MiniZinc数组中字符串值的索引的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆