错误:在文件 custom.f90 的第 463 行:内存分配失败
Posted
技术标签:
【中文标题】错误:在文件 custom.f90 的第 463 行:内存分配失败【英文标题】:Error: At line 463 of file custom.f90: Memory allocation failed 【发布时间】:2022-01-12 08:09:56 【问题描述】:我在扩展我的优化模型时遇到了一个问题。这是一个最小的示例,当给定足够的实体进行处理时,它会导致所述错误。可以在代码sn -p的顶部调整要处理的实体数。
理想情况下,该脚本应该为数以万计的实体运行。
感谢您的帮助!非常感谢:-)
import numpy as np
import pandas as pd
import datetime
from tqdm import tqdm
from scipy.stats import gaussian_kde
import math
import os
import matplotlib.pyplot as plt
from scipy.stats import norm, poisson
from gekko import GEKKO
NUM_ENTITIES = 50 # 10 crashes already... just a few work out fine
np.random.seed(321)
di_kde = dict()
for entity in range(NUM_ENTITIES):
arr = np.random.normal(14.75, 6, 500)
kernel = gaussian_kde(arr, bw_method='scott')
di_kde[entity] = (kernel, int(np.amax(arr)), int(np.amin(arr)))
def normcdf_gekko(yi, mean, sd):
y = 0.5*(1 + m.erf((yi-mean)/(sd*m.sqrt(2.0))))
z = m.if3(1-y, 1, y)
return z
def cdf_gauss_nogecko(kdes, maxi):
bw = kdes.neff**(-1./(1+4))
res = np.divide(np.cumsum([sum([norm.pdf(i, val, bw) for val in kdes.dataset.flatten()]) for i in np.linspace(0, maxi, 100, endpoint=True)]), max(np.cumsum([sum([norm.pdf(i, val, bw) for val in kdes.dataset.flatten()]) for i in np.linspace(0, maxi, 100, endpoint=True)])))
return res
def cdf_gauss_singular_gecko(kdes, yi):
bw = kdes.neff**(-1./(1+4))
res = m.sum([normcdf_gekko(yi, val, bw) for val in kdes.dataset.flatten()]) / kdes.dataset.flatten().size
return res
def cdf_gauss_singular_nogecko(kdes, yi):
bw = kdes.neff**(-1./(1+4))
res = np.sum([norm.cdf(yi, val, bw) for val in kdes.dataset.flatten()]) / kdes.dataset.flatten().size
return res
def pdf_gauss_gekko(kdes, yi):
bw = kdes.neff**(-1./(1+4))
res_gecko = m.sum([normpdf_gekko(yi, val, bw) for val in kdes.dataset.flatten()])
return res_gecko
def normpdf_gekko(x, mean, sd):
var = float(sd)**2
denom = m.sqrt((2*math.pi*var))
num = m.exp(-(x-float(mean))**2/(2*var))
return num/denom
cost = 0.1
revenue = 1
print(f'datetime.datetime.now().strftime("%H:%M:%S ")Running optimisation under constraint...')
if not os.path.isdir(os.path.abspath(r'.\Logging')):
os.mkdir(os.path.abspath(r'.\Logging'))
m = GEKKO(remote=True) # Initialize gekko
#m.time = np.linspace(0,20,100)
m._path = os.path.abspath(r'.\Logging')
m.options.SOLVER = 3 # APOPT (1) is an MINLP solver
m.options.IMODE = 3 # 3 or 6
m.options.MAX_MEMORY = 10
m.solver_options = ['minlp_maximum_iterations 500', \
# minlp iterations with integer solution
'minlp_max_iter_with_int_sol 10', \
# treat minlp as nlp
'minlp_as_nlp 0', \
# nlp sub-problem max iterations
'nlp_maximum_iterations 50', \
# 1 = depth first, 2 = breadth first
'minlp_branch_method 2', \
# maximum deviation from whole number
'minlp_integer_tol 0.05', \
# covergence tolerance
'minlp_gap_tol 0.01']
print(f'datetime.datetime.now().strftime("%H:%M:%S ")Adding variables...')
qi = [m.FV(value=di_kde[k][1] , lb=di_kde[k][2], ub=di_kde[k][1], integer=True, name=f'qi_k') for idx, k in enumerate(di_kde.keys())]
print(f'datetime.datetime.now().strftime("%H:%M:%S ")Adding constraint equations...')
inter = m.Intermediate(m.sum([cdf_gauss_singular_gecko(di_kde[k][0], qi[idx4]) for idx4, k in enumerate(di_kde.keys())]) / len(di_kde), name='InterConstr')
m.Equation(inter >= 0.9)
print(f'datetime.datetime.now().strftime("%H:%M:%S ")Adding maximisation function...')
for ii, kk in enumerate(di_kde.keys()):
m.Maximize(m.sum([(-cost * (m.max3(0, qi[ii]-j) + m.max3(0, j-qi[ii]) + qi[ii]) + revenue * m.min3(qi[ii], j)) * pdf_gauss_gekko(di_kde[kk][0], j) for j in range(di_kde[kk][2], di_kde[kk][1])]))
print(f'datetime.datetime.now().strftime("%H:%M:%S ")Start solving...')
m.open_folder()
m.options.DIAGLEVEL=10
output = m.solve(disp=True)
print(f'datetime.datetime.now().strftime("%H:%M:%S ")End solving...')
print('Results')
print('qi: ' + str(qi))
print('constraint: ' + str(inter.value))
print('Objective: ' + str(-m.options.objfcnval))
【问题讨论】:
欢迎来到 SO!但是我们不是gekko
的维护者,所以这可能不是一个适当的错误报告论坛。无论如何,您的问题应该包括错误的完整堆栈跟踪,而不仅仅是消息。您不应该期望我们自己解决第 463 行的位置。
观众和我自己都无法访问堆栈跟踪,因为错误是由可执行文件引起的,并被传递给 Python 并被强截断。实际上,维护者鼓励我在这里而不是在 GitHub 上发帖,以吸引更多的观众 :-) github.com/BYU-PRISM/GEKKO/issues/133
【参考方案1】:
模型的大小与gk0_model.apm
中的gk0_model.apm
运行目录中的gk0_model.apm
中的gk0_model.apm
中的53,224
、109,470
、164,195
一起缩放为55486*NUM_ENTITIES-2008
。
模型线与 NUM_ENTITIES
检查模型文件会发现许多可以简化的简单方程。例如,大约 30% 的模型线是这些方程:
v54786=((exp(-951.5365149722506))/(sqrt(0.5231086080192687)))
v54787=((exp(-1699.0345902817821))/(sqrt(0.5231086080192687)))
v54788=((exp(-1123.400950839389))/(sqrt(0.5231086080192687)))
v54789=((exp(-2752.8539627322))/(sqrt(0.5231086080192687)))
v54790=((exp(-4449.244551756981))/(sqrt(0.5231086080192687)))
这些可以替换为 Python 中的简单评估,以删除变量和方程。当您检查 gk0_model.apm
时,您可能还会看到其他机会。
有m.options.REDUCE=1
自动删除简单赋值方程或m.options.REDUCE=2
或更高版本连续扫描和删除简单方程。但是,您可能希望在 Python 中执行此操作,以避免写入较大的 .apm
文件并加快模型编译时间。
【讨论】:
以上是关于错误:在文件 custom.f90 的第 463 行:内存分配失败的主要内容,如果未能解决你的问题,请参考以下文章
CodeForces463C Gargari and Bishops(贪心)