我正在尝试在Minizinc中创建模型,但出现以下错误:
Error: Gecode: Float::linear: Number out of limits
我正在使用Minizinc版本“ 2.2.3”和求解器“ Geocode 6.1.0”。
谁能解释为什么我会收到此错误?模型或求解器是否存在错误?
此代码正在尝试优化电池,以最大化产生的收入。
约束条件描述了一个时间段内电池可以放电/充电的量以及能量的大小
代码如下:
%enumerators
enum ACTION = {charging, discharging, no_action};
%paramters
int: Num_intervals;
float: start_battery_state;
float: battery_max_charge;
float: battery_max_discharge;
float: battery_max_storage;
float: battery_min_storage;
array[int] of float: charge_prices;
array[int] of float: discharge_prices;
%sets
set of int: TIME = 1..Num_intervals;
set of int: TIME2 = 2..Num_intervals;
%variables
array[TIME] of var -4.0..4.0: battery_activity;
array[TIME] of var float: battery_state;
array[TIME] of var ACTION: choice;
array[TIME] of var float: revenue_generated;
var float: total_revenue = sum(t in TIME)(revenue_generated[t]);
%constraints - determining battery state - cannot go below min or above max
constraint battery_state[1] = start_battery_state;
constraint forall(t in TIME2)(battery_state[t] = battery_state[t-1] + battery_activity[t]);
constraint forall(t in TIME2)(battery_state[t] >= battery_min_storage);
constraint forall(t in TIME2)(battery_state[t] <= battery_max_storage);
%constraints - if charging, calculate revenue/cost using charge_prices
%if discharging, calculate revenue/cost using discharge prices
constraint forall(t in TIME)(if choice[t] = charging then revenue_generated[t] = -battery_activity[t] * charge_prices[t]
elseif choice[t] = discharging then revenue_generated[t] = battery_activity[t] * discharge_prices[t]
else revenue_generated[t] = 0 endif);
%setting the the choice variable (charging, discharging, no-action)
%depending on battery activity
constraint forall(t in TIME)(if battery_activity[t] > 0 then choice[t] = charging
elseif battery_activity[t] < 0 then choice[t] = discharging
else choice[t] = no_action endif);
solve maximize total_revenue;
我正在使用以下输入文件:
% number of time intervals
Num_intervals = 5;
start_battery_state = 8.0;
battery_max_charge = 4.0;
battery_max_discharge = -4.0;
battery_min_storage = 0.0;
battery_max_storage = 7.0;
%charge_efficiency = 0.85;
%discharge_efficiency = 1.0;
charge_prices = [35.0,20.0,60.0,-5.0,20.0];
discharge_prices = [35.0,20.0,60.0,-5.0,20.0];
答案 0 :(得分:0)
这是Gecode求解器的错误。 Gecode仅对Float变量提供了有限的支持,抛出该错误表示该浮点变量的域之一超出了Gecode可以支持的范围。
正如评论所示,当模型包含浮点变量时,约束编程求解器通常不是最佳求解器。相反,您可能想尝试基于混合整数编程的求解器。 MiniZinc软件包包括OsiCBC并支持Gurobi和CPLEX,这些求解器很可能会更好地求解您的模型。
答案 1 :(得分:0)
如果这是一个选项,则可以将所有float
参数的类型修改为int
。变量battery_activity
和battery_state
的类型也更改为int
,并且通过将边界乘以因子F
来调整域。在输出部分,变量将变回原来的状态。
int: F = 100;
%variables
array[TIME] of var -F*4..F*4: battery_activity;
array[TIME] of var F*min([battery_min_storage, start_battery_state])..F*max([battery_max_storage, start_battery_state]): battery_state;
array[TIME] of var ACTION: choice;
array[TIME] of var int: revenue_generated;
var int: total_revenue = sum(t in TIME2)(revenue_generated[t]);
%constraints - determining battery state - cannot go below min or above max
constraint battery_state[1] = F * start_battery_state;
constraint forall(t in TIME2)(battery_state[t] = battery_state[t-1] + battery_activity[t]);
constraint forall(t in TIME2)(battery_state[t] >= F * battery_min_storage);
constraint forall(t in TIME2)(battery_state[t] <= F * battery_max_storage);
%constraints - if charging, calculate revenue/cost using charge_prices
%if discharging, calculate revenue/cost using discharge prices
constraint forall(t in TIME2)(
revenue_generated[t] =
(battery_activity[t] > 0) * (-battery_activity[t] * charge_prices[t]) +
(battery_activity[t] < 0) * (battery_activity[t] * discharge_prices[t]));
solve
maximize total_revenue;
output ["total_revenue = ", show(total_revenue / F), ";\n" ] ++
["revenue_generated = ", show([revenue_generated[t] / F | t in TIME2]), ";\n" ] ++
["battery_state = ", show([battery_state[t] / F | t in TIME]), ";\n" ] ++
["battery_activity = ", show([battery_activity[t] / F | t in TIME2]), ";\n" ] ++
["choice = ", show([if battery_activity[t] > 0 then charging elseif battery_activity[t] < 0 then discharging else no_action endif| t in TIME2]), ";\n" ]
对于给定的数据,似乎可以与OsiCBC配合使用。