Optimization 将Minizin模型分解为用户定义函数

Optimization 将Minizin模型分解为用户定义函数,optimization,minizinc,Optimization,Minizinc,对于我的更大的Minizing模型,我需要一个函数,它基本上回答:“这个数组中是否有一个子集的总和在$tolerance和$target之间”(并返回一个布尔值) 就其本身而言,用Minizing编写这篇文章相当容易。e、 g int: tolerance = 3; int: target = 200; int: amountsCount = 7; array[1..amountsCount] of int: amounts = [23, 345, 230, 100, 25, 28, 25];

对于我的更大的Minizing模型,我需要一个函数,它基本上回答:“这个数组中是否有一个子集的总和在$tolerance和$target之间”(并返回一个布尔值)

就其本身而言,用Minizing编写这篇文章相当容易。e、 g

int: tolerance = 3;
int: target = 200;
int: amountsCount = 7;
array[1..amountsCount] of int: amounts = [23, 345, 230, 100, 25, 28, 25];


array[1..amountsCount] of var bool: includeAmount;

var int: subsetAmount = sum([(if includeAmount[i] then amounts[i] else  0 endif) | i in 1..amountsCount]);


var bool: solvable = abs(subsetAmount - target) < tolerance;
solve maximize bool2int(solvable);

output ["solvable=", show(solvable), " included: ", show(includeAmount), " subset amount:", show(subsetAmount)];
int:公差=3;
int:目标=200;
int:amountscont=7;
int:amounts=[23345230100,25,28,25]的数组[1..amountsCount];
var bool的数组[1..amountsCount]:includeAmount;
var int:subsetAmount=总和([(如果包含金额[i],则金额[i]否则为0 endif)| 1.金额中的i]);
var bool:solvable=abs(Substamount-目标)<公差;
求解最大bool2int(可解);
输出[“可解=”,显示(可解),“包含:”,显示(包含金额),“子集金额:”,显示(子集金额)];

但是我如何才能将其设置为用户定义的函数(返回布尔“可解”)以便从实际模型中使用它呢?

您可以在模型中引入一个用户定义的谓词,该谓词返回
可解的值:

predicate has_subset_within_tolerance(array[1..amountsCount] of int: amounts_array) =
    let {
         var int: subsetAmount = sum([(if includeAmount[i] then amounts[i] else  0 endif) | i in 1..amountsCount]);
    } in 
         abs(subsetAmount - target) < tolerance
    ;
编辑

您还可以将变量
includeAmount
作为参数添加到预测中:

predicate has_subset_within_tolerance(array[1..amountsCount] of int: amounts_array,
                                      array[1..amountsCount] of var bool: includeAmount)=
 let {
     var int: subsetAmount = sum([(if includeAmount[i] then amounts_array[i] else  0 endif) | i in 1..amountsCount]);
  } in 
     abs(subsetAmount - target) < tolerance
 ; 

您还可以将
target
tolerance
作为参数添加到谓词中,以防它们也依赖于不同的
includeAmount
变量。

您可以引入一个用户定义的谓词,该谓词在您的模型中返回
solvable
的值:

predicate has_subset_within_tolerance(array[1..amountsCount] of int: amounts_array) =
    let {
         var int: subsetAmount = sum([(if includeAmount[i] then amounts[i] else  0 endif) | i in 1..amountsCount]);
    } in 
         abs(subsetAmount - target) < tolerance
    ;
编辑

您还可以将变量
includeAmount
作为参数添加到预测中:

predicate has_subset_within_tolerance(array[1..amountsCount] of int: amounts_array,
                                      array[1..amountsCount] of var bool: includeAmount)=
 let {
     var int: subsetAmount = sum([(if includeAmount[i] then amounts_array[i] else  0 endif) | i in 1..amountsCount]);
  } in 
     abs(subsetAmount - target) < tolerance
 ; 

您还可以将
target
tolerance
作为参数添加到谓词中,以防它们也依赖于不同的
includeAmount
变量。

谢谢Andrea!然而,这并不能完全满足我的需要,因为我需要在不同(和不相关)数组上应用函数
的_subset_在_公差范围内
,并且不能依赖于使用相同的全局
includeAmount
。就像我需要
将\u子集\u在\u公差范围内
作为一个自包含函数一样,我明白了,Rojer。您可以扩展谓词以将变量作为输入(请参阅我的回复的编辑版本)。我希望这能提供您所需要的功能。谢谢Andrea!然而,这并不能完全满足我的需要,因为我需要在不同(和不相关)数组上应用函数
的_subset_在_公差范围内
,并且不能依赖于使用相同的全局
includeAmount
。就像我需要
将\u子集\u在\u公差范围内
作为一个自包含函数一样,我明白了,Rojer。您可以扩展谓词以将变量作为输入(请参阅我的回复的编辑版本)。我希望这提供了您需要的功能。