简体   繁体   English

在 minizinc 中使用 forall() 谓词作为没有“约束”的赋值语句

[英]Using forall() predicate in minizinc as assignment statement without 'constraint'

I have a Minizinc program for generating the optimal charge/discharge schedule for a grid-connected battery, given a set of prices by time-interval.我有一个 Minizinc 程序,用于为并网电池生成最佳充电/放电时间表,给定一组按时间间隔的价格。

My program works (sort of; subject to some caveats), but my question is about two 'constraint' statements which are really just assignment statements:我的程序有效(有点;受到一些警告),但我的问题是关于两个“约束”语句,它们实际上只是赋值语句:

constraint forall(t in 2..T)(MW_SETPOINT[t-1] - SALE[t] = MW_SETPOINT[t]);
constraint forall(t in 1..T)(PROFIT[t] = SALE[t] * PRICE[t]);

These just mean Energy SALES is the delta in MW_SETPOINT from t-1 to 1 , and PROFIT is SALE * PRICE for each interval.这些只是意味着 Energy SALESMW_SETPOINTt-11的增量, PROFIT是每个间隔的SALE * PRICE So it seems counterintuitive to me to declare them as 'constraints'.因此,将它们声明为“约束”对我来说似乎违反直觉。 But I've been unable to formulate them as assignment statements without throwing syntax errors.但是我一直无法将它们表述为赋值语句而不会引发语法错误。

Question:问题:

  • Is there a more idiomatic way to declare such assignment statements for an array which is a function of other params/variables?是否有更惯用的方法来为数组声明此类赋值语句,该数组是其他参数/变量的 function? Or is making assignments for arrays in constraint s the recommended/idiomatic way to do it in Minizinc?或者是在 Minizinc 中为 arrays 分配constraint s 的推荐/惯用方式?

Full program for context:上下文的完整程序:

% PARAMS
int: MW_CAPACITY = 10;
array[int] of float: PRICE; 

% DERIVED PARAMS
int: STARTING_MW = MW_CAPACITY div 2;  % integer division
int: T = length(PRICE);

% DECISION VARIABLE - MW SETPOINT EACH INTERVAL
array[1..T] of var 0..MW_CAPACITY: MW_SETPOINT;

% DERIVED/INTERMEDIATE VARIABLES
array[1..T] of var -1*MW_CAPACITY..MW_CAPACITY: SALE;  
array[1..T] of var float: PROFIT;
var float: NET_PROFIT = sum(PROFIT);

% CONSTRAINTS
%% If start at 5MW, and sell 5 first interval, setpoint for first interval is 0 
constraint MW_SETPOINT[1] = STARTING_MW - SALE[1];  

%% End where you started; opt schedule from arbitrage means no net MW over time
constraint MW_SETPOINT[T] = STARTING_MW;            

%% these are really justassignment statements for SALE & PROFIT
constraint forall(t in 2..T)(MW_SETPOINT[t-1] - SALE[t] = MW_SETPOINT[t]);
constraint forall(t in 1..T)(PROFIT[t] = SALE[t] * PRICE[t]);

% OBJECTIVE: MAXIMIZE REVENUE
solve maximize NET_PROFIT;

output["DAILY_PROFIT: " ++ show(NET_PROFIT) ++ 
      "\nMW SETPOINTS: " ++ show(MW_SETPOINT) ++ 
      "\nMW SALES: " ++ show(SALE) ++
      "\n$/MW PRICES: " ++ show(PRICE)++
      "\nPROFITS: " ++ show(PROFIT)
      ]; 

It can be run with它可以运行

minizinc opt_sched_hindsight.mzn --solver org.minizinc.mip.coin-bc -D "PRICE = [29.835, 29.310470000000002, 28.575059999999997, 28.02416, 28.800690000000003, 32.41052, 34.38542, 29.512390000000003, 25.66587, 25.0499, 26.555529999999997, 28.149440000000002, 30.216509999999996, 32.32415, 31.406609999999997, 36.77642, 41.94735, 51.235209999999995, 50.68137, 64.54481, 48.235170000000004, 40.27663, 34.93675, 31.10404];"```

You can play with Array Comprehensions : (quote from the docs)您可以使用Array Comprehensions :(引自文档)

Array comprehensions have this syntax:数组推导具有以下语法:

 <array-comp>::= "[" <expr> "|" <comp-tail> "]"

For example (with the literal equivalents on the right):例如(右边的文字等价物):

 [2*i | i in 1..5] % [2, 4, 6, 8, 10]

Array comprehensions have more flexible type and inst requirements than set comprehensions (see Set Comprehensions ).数组推导比集合推导具有更灵活的类型和 inst 要求(请参阅Set Comprehensions )。

Array comprehensions are allowed over a variable set with finite type, the result is an array of optional type, with length equal to the cardinality of the upper bound of the variable set.数组推导允许对具有有限类型的变量集进行数组推导,结果是一个可选类型的数组,其长度等于变量集上限的基数。 For example:例如:

 var set of 1..5: x; array[int] of var opt int: y = [ i * i | i in x ];

The length of array will be 5.数组的长度为 5。

Array comprehensions are allowed where the where-expression is a var bool .当 where 表达式为var bool时,允许使用数组推导。 Again the resulting array is of optional type, and of length equal to that given by the generator expressions.同样,结果数组是可选类型,并且长度等于生成器表达式给定的长度。 For example:例如:

 var int x; array[int] of var opt int: y = [ i | i in 1..10 where i;= x ];

The length of the array will be 10.数组的长度为 10。

The indices of an evaluated simple array comprehension are implicitly 1..n , where n is the length of the evaluated comprehension.评估的简单数组推导的索引隐含为1..n ,其中n是评估推导的长度。

Example:例子:

int: MW_CAPACITY = 10;
int: STARTING_MW = MW_CAPACITY div 2;

array [int] of float: PRICE = [1.0, 2.0, 3.0, 4.0];
int: T = length(PRICE);

array [1..T] of var -1*MW_CAPACITY..MW_CAPACITY: SALE;

array [1..T] of var 0..MW_CAPACITY: MW_SETPOINT = let {
        int: min_i = min(index_set(PRICE));
    } in  
        [STARTING_MW - sum([SALE[j] | j in min_i..i])
         | i in index_set(PRICE)];

array [1..T] of var float: PROFIT =
        [SALE[i] * PRICE[i]
         | i in index_set(PRICE)];

solve satisfy;

Output: Output:

~$ minizinc test.mzn 
SALE = array1d(1..4, [-10, -5, 0, 0]);
----------

Notice that index_set(PRICE) is nothing else but 1..T and that min(index_set(PRICE)) is nothing else but 1 , so one could write the above array comprehensions also as请注意, index_set(PRICE)只不过是1..T ,而min(index_set(PRICE))只不过是1 ,因此可以将上述数组推导式也写为

array [1..T] of var 0..MW_CAPACITY: MW_SETPOINT =
        [STARTING_MW - sum([SALE[j] | j in 1..i])
         | i in 1..T];

array [1..T] of var float: PROFIT =
        [SALE[i] * PRICE[i]
         | i in 1..T];

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 C 中没有赋值或语句的数字 - Numbers without assignment or statement in C 优化工作计划的MiniZinc代码-约束编程 - Optimizing working scheduling MiniZinc code - constraint programming CPLEX中的此forall语句有什么问题? - What is wrong with this forall -statement in CPLEX? 在Linq中,如何在不使用Count(谓词)的情况下查找集合是否包含元素? - In Linq, how to find if a set contains an element without using Count(predicate)? 在 forall 循环中使用用户定义的函数 - using user defined function inside forall loop 在 OPL 中使用条件 forall 时出错 - Error when using a conditional forall in OPL 解决赋值或与约束匹配的算法 - Algorithm to solve an assignment or matching with a constraint 我可以在约束函数中使用if语句在MATLAB中使用ga进行优化吗? - Can I use if statement in constraint function for optimization using ga in MATLAB? 不使用if语句舍入数字 - Round a number without using if statement 如何在MiniZinc的下游约束中使用数组元素的子集的中间和? - How can I calculate an intermediate sum of a subset of array elements to use in a downstream constraint in MiniZinc?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM