MiniZinc найти набор инт - PullRequest
0 голосов
/ 11 ноября 2018

У меня есть скрипт в минизинке, который пытается найти набор int, но не может это сделать. Для постановки задачи задан набор из 2 классов, минимальный набор поддержки должен быть найден с ограничениями, что его длина должна быть меньше некоторого k, а для некоторого массива набора он должен содержать хотя бы одно из значений индекса из них. Итак, предположим, что решением является {3,4,7} и массив set (назовем это - atmostone) atmostone = [{1,2,3}, {4,5,6}, {7,8 , 9}], поэтому пересечение решения и каждого множества из массива atmostone должно быть ровно одной длины.

Это ограничения, которые я реализовал, но ошибка связана с несоответствием модели.

include "globals.mzn";
include "alldifferent.mzn";

int: t; %number of attributes
int: k; %maximum size of support set
int: n; %number of positive instances
int: m; %number of negative instances
int: c; %number of atMostOne Constraints
array [1..n, 1..t] of 0..1: omegap;
array [1..m, 1..t] of 0..1: omegan;
array [int] of set of int: atMostOne;

set of int: K = 1..k;
set of int: T = 1..t;    
var set of T: solution;


function array[int] of var opt int : set2array(var set of int: a) = 
  [i | i in a];

% constraint alldifferent(solution);
constraint length(set2array(solution)) <= k;
constraint forall(i in 1..length(atMostOne))(length(set2array(solution intersect atMostOne[i])) <= 1);
constraint forall(i in 1..n, j in 1..m)(not(omegap[i, fix(solution)] == omegan[j, fix(solution)]));

solve satisfy;

Это ошибка:

Compiling support_send.mzn

  WARNING: model inconsistency detected
Running support_send.mzn
=====UNSATISFIABLE=====
% Top level failure!
Finished in 88msec

Обновление:

Данные:

t=8; %number of attributes
k=3; %maximum size of support set
n=5; %number of positive instances
m=3; %number of negative instances
c=4; %number of atMostOne Constraints
omegap=[| 0,0,1,0,1,0,0,0 |
1,0,1,1,0,0,0,1|
0,1,0,1,0,0,1,1|
0,1,1,0,1,1,0,1|
0,0,1,0,1,1,1,1
|];
omegan=[| 1,1,0,0,1,0,1,1|
0,1,0,0,1,1,0,0|
1,0,0,1,1,0,0,1
|];

atMostOne =
[{1,2,3},
{4,5,6},
{3,5},
{7,8}];

Любая помощь будет оценена.

Спасибо.

1 Ответ

0 голосов
/ 13 ноября 2018

Проблемы в вашей модели проистекают из заданной переменной solutions.

Первая проблема вызвана функцией set2array. Вы можете подумать, что это возвращает массив с целыми числами, которые находятся в вашем массиве; Однако это не так. Вместо этого он возвращает массив необязательных целых чисел . Это означает, что все значения, которые возможны в вашем наборе, хранятся в массиве, но некоторые из них могут быть просто помечены отсутствует . В этом случае это почти то же самое, что наличие массива логических переменных, которые просто говорят, находится ли значение в наборе или нет.

Обратите внимание, что ограничение length(set2array(solution)) <= k невозможно выполнить. Поскольку solution имеет больше возможностей, чем k, длина массива всегда будет больше. Ограничение, которое вы, вероятно, хотите применить: card(solution) <= k. Функция card(X) возвращает кардинальность / размер набора. Та же проблема может быть найдена во втором ограничении.

У вашего последнего ограничения есть другая проблема: оно содержит выражение fix(solution). В контексте вашей модели вы не можете написать это, потому что не будут исправлены во время компиляции. Выражение также оценивается в set of int. Хотя вы можете использовать наборы для доступа к массиву, нарезка массивов, в настоящее время это запрещено для наборов переменных. Я предложил бы попытаться найти другую формулировку для этого ограничения. (Поскольку я не могу понять, что он должен делать, боюсь, я ничего не могу предложить)

В качестве последнего замечания, закомментированное ограничение, alldifferent(solution), не нужно. Поскольку solution - это набор, он гарантированно содержит значения только один раз.

...