如果某些变量是字符串数组,如何在 Minizinc 中构建约束?

问题描述

我刚刚开始使用 Minizinc,如果我对为我的问题构建模型有一些想法,我将不胜感激。

我有三个项目。购买每件物品时,我都会获得一定的现金返还奖金,并且可以购买物品的次数有限制。 我的购物车也有容量。

示例:

items = [ 'i1','i2','i3' ]
cart_capacity = 7

cashback = [30,10,20] 
(meaning,with purchase of item1 I get back $30)

Frequency_of_purchase = [ 2,1,5]
(meaning,item 3 can be purchased 5 times)

我需要一个输出,说明每件商品可以购买多少次,以便我获得最大的现金返还

Desired result = { i1 : 2,i2: 0,i3 : 5}

解决方法

一般我们会说字符串输入主要是作为不同项目的标签。

在 MiniZinc 中,最好的方法是使用枚举类型。枚举类型既可以用作数组的索引,也可以用作变量的可能值。

您的模型可以表示为:

- uses: actions/checkout@v2
  with:
    fetch-depth: 0

您问题中的输入必须稍微调整为:

/* --- Problem Parameters --- */
enum ITEMS;
int: cart_capacity;
array[ITEMS] of int: cash_back;
array[ITEMS] of int: item_capacity;

/* --- Decision Variables --- */
array[ITEMS] of var 0..ub_array(item_capacity): purchases;

/* --- Constraints --- */
constraint forall(it in ITEMS) (purchases[it] < item_capacity[it]);
constraint sum(it in ITEMS) (purchases[it]) < cart_capacity;

/* --- Solving Goal --- */
solve maximize sum(it in ITEMS) (purchases[it]*cash_back[it]);

output ["{"] ++ [show(it) ++ ": " ++ show(purchases[it]) ++ if it == max(ITEMS) then "" else "," endif | it in ITEMS] ++ ["}"];