CPLEX无报错但无解,soc部分初始化及决策变量可行性咨询
CPLEX中逐小时更新SOC的解决方案
问题描述
我在使用CPLEX时,程序无报错但未得到求解结果。当前代码提示soc[t][number]存在部分初始化问题——仅给定了第1小时的SOC值,我希望逐小时更新SOC的值,请问能否将SOC设置为决策变量?
原代码
int tavail=5; int n=10; range t=1..tavail; range number =1..n; float soc[t][number]=[[0.6,0.3,0.2,0.7,0.8,0.9,0.3,0.6,0.5,0.9]]; //预测负荷(时段0-4) float pl[t]=[10000000,7000000,9000000,6000000,12000000]; //目标负荷(时段0-11) float pt[t]=[10000000,10000000,10000000,10000000,10000000]; //母线电压(时段0-11) float v[t]=[240,232,229,233,230]; //目标母线电压(时段0-11) float vt[t]=[230,230,230,230,230]; //电动汽车充电功率决策变量 dvar float pevch[t][number] in 0..100000; //电动汽车放电功率决策变量 dvar float pevdis[t][number] in 0..100000; //目标函数 minimize sum(i in t)((pt[i]-pl[i])+sum(j in number)-pevch[i][j]+sum(j in number)pevdis[i][j]); subject to { forall(i in t,j in number:i!=tavail) if(pt[i]-pl[i]<0 && 0.7<soc[i][j]<0.9&& v[i]<vt[i]) {pevdis[i][j]==soc[i][j]*100000; soc[i+1][j]==0.8*soc[i][j];} else {pevdis[i][j]==0 ; soc[i+1][j]==soc[i][j];} forall(i in t,j in number:i!=tavail) if(pt[i]-pl[i]>0 && 0.3<= soc[i][j]<=0.7 && v[i]>vt[i]) {pevch[i][j]==soc[i][j]*800000; soc[i+1][j]==1.1*soc[i][j];} else {pevch[i][j]==0; soc[i][j]==soc[i][j];} }
核心结论
完全可以将soc设置为决策变量,这正是解决当前初始化问题、实现逐小时SOC更新的正确方案。原代码中soc被定义为普通float数组,仅初始化了t=1的数值,t=2到t=5的SOC值未定义,这是导致程序无求解结果的关键原因之一。
修改步骤
将SOC改为决策变量
替换原soc的定义为:dvar float soc[t][number] in 0..1; // SOC取值范围0-1,符合电池荷电状态逻辑同时添加初始值约束,固定第1小时的SOC:
// 初始SOC约束:第1小时的SOC为给定值 forall(j in number) soc[1][j] == [0.6,0.3,0.2,0.7,0.8,0.9,0.3,0.6,0.5,0.9][j];修正语法与逻辑错误
- CPLEX不支持
0.7<soc[i][j]<0.9这类连续比较,需拆分为soc[i][j] > 0.7 && soc[i][j] < 0.9 - 补全原代码中缺失的括号,确保约束块语法正确
- 修正目标函数的符号错误:
sum(j in number)-pevch[i][j]改为-sum(j in number) pevch[i][j],修正后目标函数:minimize sum(i in t) ( (pt[i]-pl[i]) - sum(j in number) pevch[i][j] + sum(j in number) pevdis[i][j] ); - 删除无效约束
soc[i][j]==soc[i][j]
- CPLEX不支持
优化SOC更新逻辑
确保每小时的SOC更新约束覆盖所有场景,添加冗余约束确保SOC始终在0-1范围内,增强模型鲁棒性。
修改后完整代码示例
int tavail=5; int n=10; range t=1..tavail; range number =1..n; //预测负荷(时段0-4) float pl[t]=[10000000,7000000,9000000,6000000,12000000]; //目标负荷(时段0-11) float pt[t]=[10000000,10000000,10000000,10000000,10000000]; //母线电压(时段0-11) float v[t]=[240,232,229,233,230]; //目标母线电压(时段0-11) float vt[t]=[230,230,230,230,230]; //决策变量 dvar float pevch[t][number] in 0..100000; // 电动汽车充电功率 dvar float pevdis[t][number] in 0..100000; // 电动汽车放电功率 dvar float soc[t][number] in 0..1; // SOC作为决策变量,取值范围0-1 //目标函数 minimize sum(i in t) ( (pt[i]-pl[i]) - sum(j in number) pevch[i][j] + sum(j in number) pevdis[i][j] ); subject to { // 初始SOC约束:第1小时SOC固定为给定值 forall(j in number) soc[1][j] == [0.6,0.3,0.2,0.7,0.8,0.9,0.3,0.6,0.5,0.9][j]; // 放电逻辑与SOC更新 forall(i in t, j in number: i != tavail) { if( (pt[i]-pl[i] < 0) && (soc[i][j] > 0.7) && (soc[i][j] < 0.9) && (v[i] < vt[i]) ) { pevdis[i][j] == soc[i][j] * 100000; soc[i+1][j] == 0.8 * soc[i][j]; } else { pevdis[i][j] == 0; soc[i+1][j] == soc[i][j]; } } // 充电逻辑与SOC更新 forall(i in t, j in number: i != tavail) { if( (pt[i]-pl[i] > 0) && (soc[i][j] >= 0.3) && (soc[i][j] <= 0.7) && (v[i] > vt[i]) ) { pevch[i][j] == soc[i][j] * 800000; soc[i+1][j] == 1.1 * soc[i][j]; } else { pevch[i][j] == 0; } } // 冗余约束:确保SOC始终在0-1范围内 forall(i in t, j in number) { soc[i][j] >= 0; soc[i][j] <= 1; } }
内容的提问来源于stack exchange,提问作者Haripriya M R
相关产品推荐
相关产品推荐

