【问题标题】:Python Gekko ToolPython Gekko 工具
【发布时间】:2022-01-04 04:12:18
【问题描述】:

我刚刚开始使用 Gekko 优化软件。到目前为止,我想出了如何为我的问题获得最佳解决方案。但我不确定是否有可能看到满足约束的所有可能结果? (不仅是最优值)。问题是,对于我的特定任务,我需要进行多次优化,尽管最优值在某一点上是最优的,但随着时间的推移,最优决策顺序可能会有所不同。我想通过创建一个 MDP 来检查这一点。但要做到这一点,我需要知道可能的状态,这些状态代表要优化的变量的所有可能值,它们满足约束条件。我还没有找到如何在 Gekko 中执行此操作,所以也许有人遇到过类似的问题?

谢谢!

【问题讨论】:

    标签: python optimization gekko


    【解决方案1】:

    等高线图是显示最佳解决方案和所有可能的可行解决方案的好方法。下面是Tubular Column Design Optimization problem 的示例等高线图。

    # -*- coding: utf-8 -*-
    """
    BYU Intro to Optimization. Column design
    https://apmonitor.com/me575/index.php/Main/TubularColumn
    Contour plot additions by Al Duke 11/30/2019
    """
    from gekko import GEKKO
    import matplotlib.pyplot as plt
    import numpy as np
    from scipy.optimize import fsolve
    
    m = GEKKO()
    
    #%% Constants
    pi = m.Const(3.14159,'pi')
    P = 2300 # compressive load (kg_f)
    o_y = 450 # allowable yield stress (kg_f/cm^2)
    E = 0.65e6 # elasticity (kg_f/cm^2)
    p = 0.0020 # weight density (kg_f/cm^3)
    l = 300 # length of the column (cm)
    
    #%% Variables (the design variables available to the solver)
    d = m.Var(value=8.0,lb=2.0,ub=14.0) # mean diameter (cm)
    t = m.Var(value=0.3,lb=0.2 ,ub=0.8) # thickness (cm)
    cost = m.Var()
    
    #%% Intermediates (computed by solver from design variables and constants)
    d_i = m.Intermediate(d - t)
    d_o = m.Intermediate(d + t)
    W = m.Intermediate(p*l*pi*(d_o**2 - d_i**2)/4) # weight (kgf)
    o_i = m.Intermediate(P/(pi*d*t)) # induced stress
    
    # second moment of area of the cross section of the column
    I = m.Intermediate((pi/64)*(d_o**4 - d_i**4))
    
    # buckling stress (Euler buckling load/cross-sectional area)
    o_b = m.Intermediate((pi**2*E*I/l**2)*(1/(pi*d*t)))
    
    #%% Equations (constraints, etc. Cost could be an intermediate variable)
    m.Equations([
    o_i - o_y <= 0,
    o_i - o_b <= 0,
    cost == 5*W + 2*d
    ])
    
    #%% Objective
    m.Minimize(cost)
    
    #%% Solve and print solution
    m.options.SOLVER = 1
    m.solve()
    
    print('Optimal cost: ' + str(cost[0]))
    print('Optimal mean diameter: ' + str(d[0]))
    print('Optimal thickness: ' + str(t[0]))
    
    minima = np.array([d[0], t[0]]) 
    
    #%% Contour plot
    # create a cost function as a function of the design variables d and t
    f = lambda d, t: 2 * d + 5 * p * l * np.pi * ((d+t)**2 - (d-t)**2)/4 
    
    xmin, xmax, xstep = 2, 14, .2 # diameter
    ymin, ymax, ystep = .2, .8, .05 # thickness
    
    d, t = np.meshgrid(np.arange(xmin, xmax + xstep, xstep), \
                       np.arange(ymin, ymax + ystep, ystep))
    z = f(d, t)
    
    # Determine the compressive stress constraint line. 
    #stress = P/(pi*d*t) # induced axial stress
    t_stress = np.arange(ymin, ymax, .025) # use finer step to get smoother constraint line
    d_stress = []
    for tt in t_stress:
        dd = P/(np.pi * tt * o_y)
        d_stress.append(dd)
    
    # Determine buckling constraint line. This is tougher because we cannot
    #  solve directly for t from d. Used scipy.optimize.fsolve to find roots 
    d_buck = []
    t_buck = []
    for d3 in np.arange(6, xmax, .005): 
        fb = lambda t : o_y-np.pi**2*E*((d3+t)**4-(d3-t)**4)/(64*l**2*d3*t)
        tr = np.array([0.3])
        roots = fsolve(fb, tr)
        if roots[0] != 0: 
            if roots[0] >= .1 and roots[0]<=1.:
                t_buck.append(roots[0])
                d_buck.append(d3)
    
    # Create contour plot
    plt.style.use('ggplot') # to make prettier plots
    fig, ax = plt.subplots(figsize=(10, 6))
    
    CS = ax.contour(d, t, z, levels=15,) 
    ax.clabel(CS, inline=1, fontsize=10)
    ax.set_xlabel('mean diameter $d$')
    ax.set_ylabel('half thickness $t$')
    
    ax.set_xlim((xmin, xmax))
    ax.set_ylim((ymin, ymax))
    
    # Add constraint lines and optimal marker
    ax.plot(d_stress, t_stress, "->", label="Stress constraint")
    ax.plot(d_buck, t_buck, "->", label="Buckling constraint" )
    
    minima_ = minima.reshape(-1, 1)
    ax.plot(*minima_, 'r*', markersize=18, label="Optimum")
    ax.text(10,.25,"Contours = Cost (objective)\nConstraint line markers point\ntowards feasible space.")
    plt.title('Column Design')
    plt.legend()
    plt.show()
    

    包含超过 2D 的内容更具挑战性,但时间或 3D 图可以显示可行空间,因为参数发生变化,例如在 Interior Point solution 演示中。

    Design Optimization course 中还有许多其他示例问题演示了这种方法。

    【讨论】:

    • 等高线图仅适用于 2D、3D 或 4D(3D+时间)。其他维度的可视化确实具有挑战性,因此我建议您使用多个 2D 绘图并固定其他设计变量。
    • 感谢您提供此示例!
    猜你喜欢
    • 2023-03-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-25
    • 2021-11-20
    相关资源
    最近更新 更多