如何解决Gekko 返回错误的成功解决方案
以下代码返回 Successful Solution
Objective: 0.
。但这不是最优解。最优解是-6
。通过阅读其他问题,我认为在目标函数中使用非 Gekko 函数存在问题,但我使用的唯一非 Gekko 函数是 np.matmul
。 np.matmul
是否适用于壁虎阵列?注意 sigma_post
是一个 nxn numpy 单位矩阵。
m = GEKKO(remote=False)
m.options.max_iter=1000
#m.options.ipopt_integer_tol=1
#m.solver_options = ['minlp_integer_tol 50']
#m.solver_options = ['minlp_max_iter_with_int_sol 1000',# 'minlp_branch_method 1']
N = 2
b = m.Array(m.Var,(N,n),lb=0,ub=1,integer=True)
for i in range(N):
for j in range(n):
if j in [qb_index_range[0],rb_index_range[0],wr_index_range[0]]:
b[i][j].value = 1
else:
b[i][j].value = 0
print('b: ',b)
# CONSTRAINT: Each Lineup must be less than budget
z = np.array([None]*N)
for i in range(N):
z[i] = m.Intermediate(sum(b[i,:]*list(info_df['cost'])))
m.Equations([z[i] <= budget for i in range(N)])
# CONSTRAINT: Each Lineup has one QB
z_1 = np.array([None]*N)
for i in range(N):
z_1[i] = m.Intermediate(sum(b[i,qb_index_range[0]: qb_index_range[1]+1]))
m.Equations([z_1[i] == 1 for i in range(N)])
# CONSTRAINT: Each Lineup has one RB
z_2 = np.array([None]*N)
for i in range(N):
z_2[i] = m.Intermediate(sum(b[i,rb_index_range[0]: rb_index_range[1]+1]))
m.Equations([z_2[i] == 1 for i in range(N)])
# CONSTRAINT: Each Lineup has one WR
z_3 = np.array([None]*N)
for i in range(N):
z_3[i] = m.Intermediate(sum(b[i,wr_index_range[0]: wr_index_range[1]+1]))
m.Equations([z_3[i] == 1 for i in range(N)])
#OBJECTIVE: maximize with two lineups
sigma_1 = np.array([[None]*N for i in range(N)])
sig = np.matmul(np.matmul(b,sigma_post),b.T)
for i in range(N):
for j in range(N):
sigma_1[i][j] = m.Intermediate(sig[i][j])
m.Obj(-(sigma_1[0][0] + sigma_1[1][1]- 2*sigma_1[1][0]))
m.options.soLVER = 1
m.solve(debug=0)
编辑:
为了透明,理想情况下我关心的目标函数在下面,但上面详述的更简单的目标函数会导致问题,所以我决定从那里开始故障排除。以下目标为 Warning: no more possible trial points and no integer solution Maximum iterations
的某些值抛出 mu
,但 mu
不存在于约束中。非常感谢您的建议!
pi = 3.14159
eps = 1.0E-6
def normal_cdf(x,m):
return 1/(1+m.exp(-1.65451*x))
def normal_pdf(x,m):
return (1/((2*pi)**(.5)))*m.exp((x**2)/2)
def theta(s,m):
return m.sqrt(s[0][0]+s[1][1] - 2*s[0][1])
# OBJECTIVE: Maximize
mu_1 = np.array([None]*N)
for i in range(N):
mu_1[i] = m.Intermediate(np.matmul(b[i,:],mu))
inter = m.if2(theta(sigma_1,m)-eps,.5*mu_1[0]+.5*mu_1[1],(mu_1[0]*normal_cdf((mu_1[0]-mu_1[1])/theta(sigma_1,m),m) + \
mu_1[1]*normal_cdf((mu_1[1]-mu_1[0])/theta(sigma_1,m) + \
theta(sigma_1,m)*normal_pdf((mu_1[0]-mu_1[1])/theta(sigma_1,m)))
m.Obj(-inter)
解决方法
使用 np.matmul
或任何其他允许对象而不是数字值的函数都没有问题。需要对象是因为 b
是 Gekko 类型值的数组,需要使用自动微分计算导数。您还可以使用新的 @
运算符来简化表达式。您的原始问题陈述不完整,缺少许多定义。我添加了一些示例值,以便脚本可以在没有定义错误的情况下运行。这是guidelines to help reproduce the error。
N = 2
n = 3
qb_index_range = [0,2]
rb_index_range = [0,2]
wr_index_range = [0,2]
info_df = pd.DataFrame({'cost':np.ones(n)})
budget = 100
sigma_post = np.random.rand(n,n)
这是一个使用 np.matmul()
的例子,它也可以是点积 np.dot()
。
sigma_1 = np.matmul(np.matmul(b,sigma_post),b.T)
这也可以用矩阵乘法运算符来写。
sigma_1 = b@sigma_post@b.T
这是完整的脚本。
from gekko import GEKKO
import numpy as np
import pandas as pd
m = GEKKO(remote=False)
m.options.max_iter=1000
N = 2
n = 3
b = m.Array(m.Var,(N,n),lb=0,ub=1,integer=True)
qb_index_range = [0,2]
info_df = pd.DataFrame({'cost':np.ones(n)})
budget = 100
sigma_post = np.eye(n)
for i in range(N):
for j in range(n):
if j in [qb_index_range[0],rb_index_range[0],wr_index_range[0]]:
b[i][j].value = 1
else:
b[i][j].value = 0
# CONSTRAINT: Each Lineup must be less than budget
z = [None]*N
for i in range(N):
z[i] = m.Intermediate(sum(b[i,:]*list(info_df['cost'])))
m.Equations([z[i] <= budget for i in range(N)])
# CONSTRAINT: Each Lineup has one QB
z_1 = [None]*N
for i in range(N):
z_1[i] = m.Intermediate(sum(b[i,qb_index_range[0]: qb_index_range[1]+1]))
m.Equations([z_1[i] == 1 for i in range(N)])
# CONSTRAINT: Each Lineup has one RB
z_2 = np.array([None]*N)
for i in range(N):
z_2[i] = m.Intermediate(sum(b[i,rb_index_range[0]: rb_index_range[1]+1]))
m.Equations([z_2[i] == 1 for i in range(N)])
# CONSTRAINT: Each Lineup has one WR
z_3 = np.array([None]*N)
for i in range(N):
z_3[i] = m.Intermediate(sum(b[i,wr_index_range[0]: wr_index_range[1]+1]))
m.Equations([z_3[i] == 1 for i in range(N)])
#OBJECTIVE: maximize with two lineups
#sigma_1 = np.matmul(np.matmul(b,b.T)
sigma_1 = b@sigma_post@b.T
m.Maximize(sigma_1[0][0] + sigma_1[1][1]- 2*sigma_1[1][0])
m.options.SOLVER = 1
m.solve(debug=0,disp=False)
print(b)
这产生了一个成功的解决方案。无法验证正确的解决方案,因为原始问题陈述不完整。
[[[1.0] [0.0] [0.0]]
[[1.0] [0.0] [0.0]]]
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。