错误:在文件 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,224109,470164,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 行:内存分配失败的主要内容,如果未能解决你的问题,请参考以下文章

错误 LNK1104:无法打开文件 'mfc90.lib'

制作自己的第一个网页

制作自己的第一个网页

CodeForces463C Gargari and Bishops(贪心)

如何在wpf中创建DataGrid ReadOnly的第一行

hdu4240 求一条流量最大的路/(此题网上百分之90以上算法是错误的)