我希望使用Pyomo优化Fortran函数。目标函数和约束都用Fortran编写。根据给定的答案here,我们可以使用ExternalFunction
表达式对象。但是,即使是最简单的功能,我也无法获得结果。下面给出的是一个可复制的示例,该示例由Fortran函数,python(Python 2.7.12)脚本,为优化而执行的命令和错误组成。
Fortran函数文件(funcs.f
)-
SUBROUTINE OBJ1(ARG,OBJ)
DOUBLE PRECISION, INTENT(IN) :: ARG(2)
DOUBLE PRECISION, INTENT(OUT) :: OBJ
OBJ = ARG(1)+ARG(2)
RETURN
END SUBROUTINE
Python脚本(pytest.py
)-
import funcs
from pyomo.environ import *
from pyomo.opt import *
from pyomo.core import *
m = ConcreteModel()
m.a = Var(RangeSet(1,2),within=NonNegativeReals,bounds=(0,10))
m.f = ExternalFunction(library='funcs.so',function='OBJ1')
expr = m.f(m.a)
m.obj = Objective(expr=expr,sense=minimize)
opt = SolverFactory('ipopt')
results = opt.solve(m,tee=True)
print(results)
在终端执行的命令-
>> f2py -c -m funcs funcs.f
>> python pytest.py
错误-
File "/usr/local/lib/python2.7/dist-packages/pyomo/core/base/external.py", line 160, in load_library
FUNCADD(('funcadd_ASL', self._so))(byref(AE))
AttributeError: /home/utkarsh/Desktop/python/modules/blackboxOptimization/funcs.so: undefined symbol: funcadd_ASL
我只给出了我认为相关的错误的一小部分。
鉴于此,我有以下问题-
如何使用pyomo成功解决这个不受约束的优化问题?
对于我的整个项目,我将不得不限制Fortran本身。约束子例程将返回一个实数,该实数将使用pyomo进行限制。如何为这些类型的约束建模?
我假设Pyomo将此黑盒视为非线性优化。因此,我正在使用ipopt
求解器。这个假设正确吗?
软件包的版本-
Pyomo-5.5.1(VOTD)(Linux 4.4.0-127-generic上的CPython 2.7.12)
ipopt-Ipopt 3.12.8
f2py-与numpy 1.16.2一起安装
感谢您的帮助!
答案 0 :(得分:0)
如果您不受Pyomo的束缚,则可以使用出色的Pygmo软件包,该软件包为包括黑盒求解器在内的各种问题提供求解器。
这里有一个小例子,说明如何在连续受限的单目标测试问题上使用它:
import pygmo as pg
import pandas as pd
class Rosenbrock():
"""Rosenbrock function constrained to a disk.
See: https://en.wikipedia.org/wiki/Test_functions_for_optimization
"""
def fitness(self, x):
"""Evaluate fitness.
Instead of the Rosenbrock function you could call your Fortran
code here e.g. by using F2PY: https://www.numfys.net/howto/F2PY/
"""
obj = (1-x[0])**2+100*(x[1]-x[0]**2)**2
ineq = x[0]**2+x[1]**2-2
return [obj, ineq]
def get_bounds(self):
"""Return boundaries."""
return ([-1.5]*2, [1.5]*2)
def get_nic(self):
"""Determine number of inequalities."""
return 1
# set up and solve problem
pro = pg.problem(Rosenbrock())
pop = pg.population(pro, size=200)
# see: https://github.com/esa/pagmo2/blob/master/include/pagmo/algorithms/
algo = pg.algorithm(pg.ihs(gen=10000))
algo.set_verbosity(100)
pop = algo.evolve(pop)
# extract solutions
fits = pd.DataFrame(pop.get_f())
vectors = pd.DataFrame(pop.get_x())
best_idx = pop.best_idx()
best_vector = vectors.loc[best_idx].to_frame().T
best_fitness = fits.loc[best_idx].to_frame().T
print(best_vector)
print(best_fitness)
然后,您只需要在适应性函数中处理“连接”您的Fortran代码即可。
希望这会有所帮助!