收到错误-Minizinc建模语言“数量超出限制”

时间:2019-01-09 15:48:40

标签: linear-programming minizinc

我正在尝试在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];

2 个答案:

答案 0 :(得分:0)

这是Gecode求解器的错误。 Gecode仅对Float变量提供了有限的支持,抛出该错误表示该浮点变量的域之一超出了Gecode可以支持的范围。

正如评论所示,当模型包含浮点变量时,约束编程求解器通常不是最佳求解器。相反,您可能想尝试基于混合整数编程的求解器。 MiniZinc软件包包括OsiCBC并支持Gurobi和CPLEX,这些求解器很可能会更好地求解您的模型。

答案 1 :(得分:0)

如果这是一个选项,则可以将所有float参数的类型修改为int。变量battery_activitybattery_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配合使用。