MiniZinc选择产品的子集-问题类别

时间:2018-09-03 15:05:12

标签: modeling minizinc

在观看了“基础建模”课程之后,我试图对我的问题进行分类,以便在MiniZinc上选择合适的模型表示形式。

我有10种产品,每一种都有其4个特殊功能/属性(表4x10)。该表具有固定值。用户将提供4个参数作为输入。 将以用户输入参数确定产品属性值的方式创建约束。

决策变量将是与用户输入匹配的产品子集。

据我了解,这是从一组对象中选择一个子集的问题,是否有任何示例建议可与上述Minizinc模型描述相对应,以供参考?

1 个答案:

答案 0 :(得分:0)

我(仍然)不能完全确定问题的确切说明,但是这里有一个模型可以识别所有“最接近”输入数据的产品。我已经将“最近”定义为产品的每个功能与input数组(由score函数计算)之间的绝对差之和。

int: k; % number of products
int: n; % number of features

array[1..k, 1..n] of int: data;
array[1..n] of int: input;


% decision variables
array[1..k] of var int: x; % the closeness score for each product
array[1..k] of var 0..1: y; % 1: this products is nearest (as array)
% var set of 1..k: y;  % products closest to input (as set)
var int: z; % the minimum score

function var int: score(array[int] of var int: a, array[int] of var int: b) =
  let  {
     var int: t = sum([abs(a[i]-b[i]) | i in index_set(a)])
  } in
    t
;

solve minimize z;

constraint
  forall(i in 1..k) (
    x[i] = score(data[i,..], input) /\
    (y[i] = 1 <-> z = x[i]) % array 
    % (i in y <-> x[i] = z) % set
  )
  /\
  minimum(z, x)
 ;

 output [
  "input: \(input)\n",
  "z: \(z)\n",
  "x: \(x)\n",
  "y: \(y)\n\n"
]
++
[
  % using array representation of y 
  if fix(y[i]) = 1 then 
    "nearest: ix:\(i) \(data[i,..])\n" else  "" endif
  | i in 1..k
];

% data
k = 10;
n = 4;

% random features for the products
data = array2d(1..k,1..n,
 [
 3,6,7,5,
 3,5,6,2,
 9,1,2,7,
 0,9,3,6,
 0,5,2,4, % score 5
 1,8,7,9,
 2,0,2,3, % score 5
 7,5,9,2,
 2,8,9,7,
 3,6,1,2]);

 input = [1,2,3,4];
 % input = [7,5,9,2]; % exact match for product 8

输出为:

 input: [1, 2, 3, 4]
 z: 5
 x: [11, 10, 13, 10, 5, 15, 5, 17, 16, 10]
 y: [0, 0, 0, 0, 1, 0, 1, 0, 0, 0]

 nearest: ix:5 [0, 5, 2, 4]
 nearest: ix:7 [2, 0, 2, 3]