0

你好,社区,

所以我有以下错误:

评估约束 5965 时出错:无法评估 sqrt'(0)。错误:pyomo.opt:求解器(asl)返回非零返回代码(1)错误:pyomo.opt:有关诊断信息,请参阅上面的求解器日志。

Solver (asl) 没有正常退出

实际上问题出在代码的以下部分:

def thermal_lim_ineq_con(model, i, j, k):
    if line_loading_limit == True:
        P_branch_ij = (model.V_magn[i, k]**2) * np.float(real(Y_matrix[i, j])) - model.V_magn[i, k] * model.V_magn[j, k] * (np.float(real(Y_matrix[i, j])) * cos(model.V_angle[i, k]-model.V_angle[j, k]) + np.float(imag(Y_matrix[i,j])) * sin(model.V_angle[i, k]-model.V_angle[j, k]))
        Q_branch_ij = (model.V_magn[i, k]**2) * np.float(imag(Y_matrix[i, j])) + model.V_magn[i, k] * model.V_magn[j, k] * (np.float((real(Y_matrix[i, j]))) * sin(model.V_angle[i, k]-model.V_angle[j, k]) - np.float(imag(Y_matrix[i,j])) * cos(model.V_angle[i, k]-model.V_angle[j, k]))
        return (sqrt((P_branch_ij**2) + (Q_branch_ij**2)) <= limits_flows[i, j]) ########### ATTENTION
    else: 
        return Constraint.Skip 

model.therlim_ineq_con = Constraint(branch_from_to, scenario_set, rule = thermal_lim_ineq_con) # run this constraint for all branches 

有任何想法吗??删除 sqrt 并对右侧的变量 limits_flows 进行平方,解决了这个问题,但是限制非常低(-6、-7 阶)并且问题变得不可行。

谢谢你。

编辑:

最终问题可以通过给随机初始条件来解决

model.V_magn[i, k]
4

1 回答 1

3

这在技术上不是 Pyomo 的问题——而是你的配方的问题。

当求解器将 P_branch_ij 和 Q_branch_ij 的值驱动为 0 时,ASL(求解器可执行文件的一部分)会抛出该错误(这可能是由于行不活动或初始值错误而发生的)。为零时, 的导数sqrt(0)未定义。此数值错误会导致求解器退出而不返回解。

有几种可能的解决方法:

  1. 正如您在编辑中指出的那样,您可以尝试不同的初始变量值。当求解器从不同的起点开始时,它可能不会采用驱动P_branch_ijQ_branch_ij归零的路径。这种方法的缺点是您可能必须尝试许多不同的初始值,然后才能获得一个没有求解器通过的初始值sqrt(0),并且不能保证找到一个有效的初始值(特别是如果问题的解决方案确实为 0 !)。

  2. 绑定变量,使总分支功率 ( P_branch_ij**2 + Q_branch_ij**2) 永远不会达到零。这有点棘手,因为您不能使用简单的约束来做到这一点:大多数求解器在求解过程中被允许违反约束,致命错误是求解器曾经尝试评估 的导数sqrt(0)。幸运的是,大多数求解器将始终尊重变量 bounds。因此,为了防止求解器进行评估sqrt'(0),您需要定义中间 Pyomo 变量(不仅仅是 Python 表达式)PQ2_branch_ij,然后将变量下限设置为大于 0 的值。这种方法的缺点是您现在正在解决一个不同的问题,并且如果原始问题的解决方案确实为 0,则可能会迫使自己获得次优解决方案。

model.PQ2_branch_ij = Var(branch_from_to, scenario_set, bounds=(1e-8, None))
def compute_PQ2_branch_ij(m, i, j, k):
    P_branch_ij = (m.V_magn[i, k]**2) * np.float(real(Y_matrix[i, j])) - m.V_magn[i, k] * m.V_magn[j, k] * (np.float(real(Y_matrix[i, j])) * cos(m.V_angle[i, k]-m.V_angle[j, k]) + np.float(imag(Y_matrix[i,j])) * sin(m.V_angle[i, k]-m.V_angle[j, k]))
    Q_branch_ij = (m.V_magn[i, k]**2) * np.float(imag(Y_matrix[i, j])) + m.V_magn[i, k] * m.V_magn[j, k] * (np.float((real(Y_matrix[i, j]))) * sin(m.V_angle[i, k]-m.V_angle[j, k]) - np.float(imag(Y_matrix[i,j])) * cos(m.V_angle[i, k]-m.V_angle[j, k]))
    return m.PQ2_branch_ij[i,j,k] == P_branch_ij**2 + Q_branch_ij**2
def thermal_lim_ineq_con(m, i, j, k):
    return sqrt(m.PQ2_branch_ij) <= limits_flows[i, j]
if line_loading_limit:
    model.compute_PQ2_branch_ij = Constraint(branch_from_to, scenario_set, rule=compute_PQ2_branch_ij)
    model.thermal_lim_ineq_con = Constraint(branch_from_to, scenario_set, rule=thermal_lim_ineq_con)`
  1. sqrt()通过平方从配方中删除limits_flows[i,j]。这通常是最好的选择:您的问题在数学上是等价的,但不再包含sqrt()函数,并且如果分支流变为 0,则不会出现问题。您在尝试此方法时观察到的不可行性可能完全是一个单独的问题。例如,对于非凸问题(如 ACOPF),您可以初始化求解器,使其无法移动到可行位置并“收敛到局部不可行点”(更多解释,请参阅特定求解器的文档;例如IPOPTKnitro)。
def thermal_lim_ineq_con(model, i, j, k):
    if line_loading_limit == True:
        P_branch_ij = (model.V_magn[i, k]**2) * np.float(real(Y_matrix[i, j])) - model.V_magn[i, k] * model.V_magn[j, k] * (np.float(real(Y_matrix[i, j])) * cos(model.V_angle[i, k]-model.V_angle[j, k]) + np.float(imag(Y_matrix[i,j])) * sin(model.V_angle[i, k]-model.V_angle[j, k]))
        Q_branch_ij = (model.V_magn[i, k]**2) * np.float(imag(Y_matrix[i, j])) + model.V_magn[i, k] * model.V_magn[j, k] * (np.float((real(Y_matrix[i, j]))) * sin(model.V_angle[i, k]-model.V_angle[j, k]) - np.float(imag(Y_matrix[i,j])) * cos(model.V_angle[i, k]-model.V_angle[j, k]))
        return P_branch_ij**2 + Q_branch_ij**2 <= limits_flows[i, j]**2
    else: 
        return Constraint.Skip 
于 2016-08-25T00:02:14.787 回答