【问题标题】:How to re-evaluate Gekko objective while minimizing objective's parameters如何在最小化目标参数的同时重新评估 Gekko 目标
【发布时间】:2021-11-09 13:26:09
【问题描述】:

提前道歉,我刚开始学习 Gekko,看看我是否可以将它用于项目。我正在尝试在玩游戏状态非常有限(50 ^ 2)和每回合选项(包括 0-10)的游戏时优化胜率。

据我了解,我可以使用m.solve() Gekko 函数来最小化我在这里设置的对手的胜率:

PLAYER_MAX_SCORE = 50 #Score player needs to win
OPPONENT_MAX_SCORE = 50 #Score opponent needs to win

#The opponent's current strategy: always roll 4 dice per turn
OPPONENT_MOVE = 4

m = GEKKO()
m.options.SOLVER = 1

"""
player_moves is a 2-d array where:
 - the row represents player's current score
 - the column represents opponent's current score
 - the element represents the optimal move for the above game state
Thus the player's move for a game is player_moves[pScore, oScore].value.value
"""
player_moves = m.Array(m.Var, (PLAYER_MAX_SCORE, OPPONENT_MAX_SCORE), value=3, lb=0, ub=10, integer=True)

m.Obj(objective(player_moves, OPPONENT_MOVE, PLAYER_MAX_SCORE, OPPONENT_MAX_SCORE, 100))

m.solve(disp=False)

作为参考,objective 是一个函数,它根据当前玩家的行为(以player_moves 表示)返回对手的胜率。

唯一的问题是 m.solve() 只调用一次目标函数,然后立即返回 player_moves 数组中的“已解决”值(当定义 player_moves 时,这只是初始值)。我想让 m.solve() 多次调用目标函数来判断新对手的胜率是下降还是上升。

Gekko 可以做到这一点吗?或者对于这类问题我应该使用不同的库吗?

【问题讨论】:

    标签: optimization gekko


    【解决方案1】:

    Gekko 创建优化问题的符号表示,并编译成字节码。因此,目标函数必须用 Gekko 变量和方程来表示。对于不使用 Gekko 变量的黑盒模型,另一种方法是使用 scipy.optimize.minimize()。有一个comparison of Gekko and Scipy

    Scipy

    import numpy as np
    from scipy.optimize import minimize
    
    def objective(x):
        return x[0]*x[3]*(x[0]+x[1]+x[2])+x[2]
    
    def constraint1(x):
        return x[0]*x[1]*x[2]*x[3]-25.0
    
    def constraint2(x):
        sum_eq = 40.0
        for i in range(4):
            sum_eq = sum_eq - x[i]**2
        return sum_eq
    
    # initial guesses
    n = 4
    x0 = np.zeros(n)
    x0[0] = 1.0
    x0[1] = 5.0
    x0[2] = 5.0
    x0[3] = 1.0
    
    # show initial objective
    print('Initial Objective: ' + str(objective(x0)))
    
    # optimize
    b = (1.0,5.0)
    bnds = (b, b, b, b)
    con1 = {'type': 'ineq', 'fun': constraint1} 
    con2 = {'type': 'eq', 'fun': constraint2}
    cons = ([con1,con2])
    solution = minimize(objective,x0,method='SLSQP',\
                        bounds=bnds,constraints=cons)
    x = solution.x
    
    # show final objective
    print('Final Objective: ' + str(objective(x)))
    
    # print solution
    print('Solution')
    print('x1 = ' + str(x[0]))
    print('x2 = ' + str(x[1]))
    print('x3 = ' + str(x[2]))
    print('x4 = ' + str(x[3]))
    

    壁虎

    from gekko import GEKKO    
    import numpy as np
    
    #Initialize Model
    m = GEKKO()
    
    #initialize variables
    x1,x2,x3,x4 = [m.Var(lb=1,ub=5) for i in range(4)]
    
    #initial values
    x1.value = 1
    x2.value = 5
    x3.value = 5
    x4.value = 1
    
    #Equations
    m.Equation(x1*x2*x3*x4>=25)
    m.Equation(x1**2+x2**2+x3**2+x4**2==40)
    
    #Objective
    m.Minimize(x1*x4*(x1+x2+x3)+x3)
    
    #Solve simulation
    m.solve()
    
    #Results
    print('')
    print('Results')
    print('x1: ' + str(x1.value))
    print('x2: ' + str(x2.value))
    print('x3: ' + str(x3.value))
    print('x4: ' + str(x4.value))
    

    【讨论】:

    • 我使用了 Gekko,因为它具有“仅整数”参数的功能,而 scipy 似乎主要只允许参数浮点数。有没有办法解决这个问题?
    • 大多数求解器也需要相同类型的信息或需要特定类型的变量。以下是一些可能有帮助的附加选项:stackoverflow.com/questions/26305704/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-11
    • 2019-07-03
    • 1970-01-01
    • 2021-09-08
    相关资源
    最近更新 更多