2017-09-17 60 views
1

我有一个关于Minizinc的语法的简单问题。我的.dzn文件输入包含一组2门维阵列(约高达30阵列),声明如下:Minizinc,如何创建地图或字典数据结构

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

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

在我的模型中,我需要根据变量的值使用这些数组中的一个。在通用编程语言中,我会使用映射或字典数据结构来解决它。但在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; 

这段代码的一个明显的问题是,我需要每个更改输入时间来改变模式。有没有更好的方式如何以通用的方式编码?

谢谢!

回答

3

以更抽象的方式,映射结构不过是一种将某种类型的输入映射到数组的功能。因此地图可以被数组和函数取代。 (不同之处在于你必须自己定义函数)

在我开始研究其余的内容之前,我想指出,如果你的模型编译速度一般很快,你可能想尝试一个没有函数的三元数组, rates_index = array3d(0..60, 1..3, 1..501, [ 15, 20, 23, ....。这会花费更多的内存,但会使模型更加灵活。

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

以最简单的形式将包含您if-then-else语句的另一个版本的功能map_index本身:

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]; 
+0

好的,我明白了,请您澄清一下关于编译时间和内存使用情况的声明。 array3d(0..60,1..3,1..501)比60 array2d(1..3,1..501)需要更多的计算/内存资源吗? 我明白你的解决方案,基本上我只是将我的array2ds合并到一个3d中,然后映射索引。唯一的缺点是数据对于人类来说更难以理解。但是现在我不需要改变模型。谢谢! – kirbo

+2

我想你明白了!关于内存消耗:60二维数组在编译期间不会占用比组合的三维数组更多的内存。但是,如果您不想执行转换步骤并选择在3d数组中添加不在2d数组之间的额外(空)数组,则可能会有大的内存开销。 – Dekker

+0

明白了,谢谢! – kirbo