Arrays 在Minizing中计算数组中最频繁的元素

Arrays 在Minizing中计算数组中最频繁的元素,arrays,count,minizinc,Arrays,Count,Minizinc,这是一个非常简单的事情,我想在迷你锌。我有一个整数值数组,我想知道其中最常见的值出现的次数。我不知道该怎么做。我希望有人能帮上忙。我不知道这是否是最有效的方法,但它很有效,基本上对于数组中的每个元素,求该值在数组中出现的次数之和,并将其存储在auxliar数组中,然后取“查找auxliar数组中出现的最大值”命令,因此,在示例中,14出现了3次,因此对于与14对应的每个元素,重复保持3。 最后,我添加了上面所有内容的一行程序版本,其中不是存储生成的重复数组,而是max_repeats行 我不知道

这是一个非常简单的事情,我想在迷你锌。我有一个整数值数组,我想知道其中最常见的值出现的次数。我不知道该怎么做。我希望有人能帮上忙。

我不知道这是否是最有效的方法,但它很有效,基本上对于数组中的每个元素,求该值在数组中出现的次数之和,并将其存储在auxliar数组中,然后取“查找auxliar数组中出现的最大值”命令,因此,在示例中,14出现了3次,因此对于与14对应的每个元素,重复保持3。 最后,我添加了上面所有内容的一行程序版本,其中不是存储生成的重复数组,而是max_repeats行


我不知道这是否是最有效的方法,但它是有效的,基本上对于数组中的每个元素,求该值在数组中出现的次数之和,并将其存储在auxliar数组中,然后取“查找auxliar数组中出现的最大值”,因此,在示例中,14出现了3次,因此对于与14对应的每个元素,重复保持3。 最后,我添加了上面所有内容的一行程序版本,其中不是存储生成的重复数组,而是max_repeats行


解决这个问题的经典方法是使用全局constriant全局_基数和max

下面是使用这些约束对该问题建模的一种方法;它还显示了最常见的数字

使用这种方法的缺点是,必须为全局基数计数创建一个新的数组gcc,其中包括每个数字0..upb的出现次数,其中upb是数组a的上限,如果数组中有大量数字,则可能会非常大。此外,必须对索引稍微小心一点,例如,不要忘记在gcc中包含0

这种方法的优点——除了可以在解算器中高效实现之外——是可以在gcc数组上添加一些额外的约束:在这里,我添加了使用arg_maxa显示最频繁的数字的特性;它可能不止一个这样的数字,然后将给出多个解决方案

include "globals.mzn";   

int: n = 7;
array[1..n] of int: a = [15, 14, 39, 23, 14, 14, 8];
% array[1..n] of var 0..29: a; % using decision variables

% upper value of a
int: upb = ub_array(a);

% Number of occurrences in a
array[0..upb] of var 0..n: gcc;

% max number of occurrenes
var 0..upb: z = max(gcc);

% The value of the max number of occurrences
var 0..upb: max_val = arg_max(gcc)-1;

solve satisfy;

constraint
    % count the number of occurrences in a
    global_cardinality(a, array1d(0..upb,[i | i in 0..upb]), gcc)
;

output [
    "a: \(a)\n",
    "upb: \(upb)\n",
    "gcc: \(gcc)\n",
    "z: \(z)\n",
    "max_val: \(max_val)\n",        
    "ub_array(a): \(lb_array(a))..\(ub_array(a))\n",
  ];
以下是此模型的输出:

a: [15, 14, 39, 23, 14, 14, 8]
upb: 39
gcc: [0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 3, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]
z: 3
max_val: 14
ub_array(a): 8..39
----------
==========

解决这个问题的经典方法是使用全局constriant全局_基数和max

下面是使用这些约束对该问题建模的一种方法;它还显示了最常见的数字

使用这种方法的缺点是,必须为全局基数计数创建一个新的数组gcc,其中包括每个数字0..upb的出现次数,其中upb是数组a的上限,如果数组中有大量数字,则可能会非常大。此外,必须对索引稍微小心一点,例如,不要忘记在gcc中包含0

这种方法的优点——除了可以在解算器中高效实现之外——是可以在gcc数组上添加一些额外的约束:在这里,我添加了使用arg_maxa显示最频繁的数字的特性;它可能不止一个这样的数字,然后将给出多个解决方案

include "globals.mzn";   

int: n = 7;
array[1..n] of int: a = [15, 14, 39, 23, 14, 14, 8];
% array[1..n] of var 0..29: a; % using decision variables

% upper value of a
int: upb = ub_array(a);

% Number of occurrences in a
array[0..upb] of var 0..n: gcc;

% max number of occurrenes
var 0..upb: z = max(gcc);

% The value of the max number of occurrences
var 0..upb: max_val = arg_max(gcc)-1;

solve satisfy;

constraint
    % count the number of occurrences in a
    global_cardinality(a, array1d(0..upb,[i | i in 0..upb]), gcc)
;

output [
    "a: \(a)\n",
    "upb: \(upb)\n",
    "gcc: \(gcc)\n",
    "z: \(z)\n",
    "max_val: \(max_val)\n",        
    "ub_array(a): \(lb_array(a))..\(ub_array(a))\n",
  ];
以下是此模型的输出:

a: [15, 14, 39, 23, 14, 14, 8]
upb: 39
gcc: [0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 3, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]
z: 3
max_val: 14
ub_array(a): 8..39
----------
==========