Minizinc,如何创建 map 或字典数据结构

标签 minizinc gecode

我有一个关于 Minizinc 语法的简单问题。我的输入 .dzn 文件包含一组 2 维数组(大约多达 30 个数组),声明如下:

rates_index_0 = array2d(1..3, 1..501, [ 15, 20, 23, ....
rates_index_12 = array2d(1..3, 1..501, [ 21, 24, 27, ....
...

注意:索引号之间有间隙(例如,12 -> 20)

在我的模型中,我需要根据变量的值使用这些数组之一。在通用编程语言中,我会使用 map 或字典数据结构来解决它。但是在 Minizinc 中,我通过以下方式对其进行了硬编码:
function var int: get_rate(int: index, var int: load, int: dc_size) =

        if index == 0 then
          rates_index_0[dc_size, load]
        else if index == 12 then
          rates_index_12[dc_size, load]
        else if index == 16 then
          rates_index_16[dc_size, load]
        else if index == 20 then
          rates_index_20[dc_size, load]
        else
          assert(false, "unknown index", 0)
        endif endif endif endif;

这段代码的一个明显问题是每次更改输入时都需要更改模型。有没有更好的方法可以以通用方式对此进行编码?

谢谢!

最佳答案

以更抽象的方式,映射结构只不过是将某种类型的输入映射到数组的函数。因此可以用数组和函数替换映射。 (不同之处在于您必须自己定义函数)

在我开始其他部分之前,我想指出,如果您的模型编译速度通常很快,您可能想要尝试不带函数的三重数组,rates_index = array3d(0..60, 1..3, 1..501, [ 15, 20, 23, .... .这将花费更多内存,但会使模型更加灵活。

使用 map 结构的一般方法是定义一个函数 map_index ,将您的输入(在本例中为整数)映射到数组的索引,也是整数。这意味着我们可以定义一个额外的级别数组来指向正确的级别:rates_index = array3d(0..nr_arrays, 1..3, 1..501, .... .这意味着 get_rates 的内容然后可以是:rates_index[map_index(index), dc_size, load] .

函数map_index其最简单的形式将包含您的 if-then-else 的另一个版本。声明:

function int: map_index(int: index) =  
    if index == 0 then
        0
    else if index == 12 then
        1
    else if index == 16 then
        2
    else if index == 20 then
        3
    else
        assert(false, "unknown index", 0)
    endif endif endif endif;

但是,您可以通过生成一个包含每个索引的数组编号的额外数组来使其动态化,为所有不可用的数组放置 -1。对于您的示例,映射将如下所示:array[0..20] of int: mapping = [0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, -1, 2, -1, -1, -1, 3]; . map_index函数然后可以动态定义为:
function int: map_index(int: index) =  
    mapping[index];

关于Minizinc,如何创建 map 或字典数据结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46262667/

相关文章:

minizinc - 如何为 Minizinc 中的函数创建等效项以简化谓词

minizinc - 找到总和为 n 的最小全差数组

linux - 如何使用 cmake 将 gecode 作为外部库包含在我的 c++ 项目中?

linker-errors - 在 OS/X 上链接 Gecode

gecode - 在Gecode中,从评价函数访问家庭/空间变量值

c++ - 我如何在 Gecode 中使用评价函数?

graph - 使用 MiniZinc 检查是否存在连接图中两个顶点的路径

minizinc - 类似 MiniZinc 约束之间的差异