首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >自定义python求解器用于pyomo

自定义python求解器用于pyomo
EN

Stack Overflow用户
提问于 2022-10-24 09:53:44
回答 2查看 65关注 0票数 0

我负责一系列非线性优化的练习。我认为从一些优化问题的例子开始,用pyomo +一些黑匣子解决它们是很酷的。

然而,随着学生们对优化算法的了解越来越多,我希望他们也能实现一些简单的方法,并对相同的例子进行测试。我希望有一种“简单”的方式来向pyomo添加一个自定义的解决程序,但是我找不到有关这方面的任何信息。

基本上,这将允许学生通过更改代码中的一行代码来检查其实现,并将其与经过良好测试的求解器进行比较。

我也会尝试自己实现一个简单的包装器,但是我对pyomo内部组件一无所知。

pyomo**?问:我可以把用python编写的自己的求解器添加到中吗?求解器可以有一个类似于** scipy.optimize**.**的接口

是为了读书,

弗兰兹

相关信息:

EN

回答 2

Stack Overflow用户

发布于 2022-10-24 14:55:26

简短的回答是:“是的: Pyomo被设计成可扩展的,并且用户定义的解决器绝对是支持的。”

细节涉及得更多一些。虽然Pyomo定义了几个“解决器”类层次结构,但它们绝不是必需的。在注册和使用解决程序时,核心Pyomo依赖于鸭子类型,而不是继承。目前,最简单的解决程序接口只需要实现以下方法:

代码语言:javascript
运行
复制
class GenericSolverInterface(object):
    def solve(self,
              model: _BlockData,
              tee: bool = False,
              load_solutions: bool = True,
              logfile: Optional[str] = None,
              solnfile: Optional[str] = None,
              timelimit: Optional[float] = None,
              report_timing: bool = False,
              solver_io: Optional[str] = None,
              suffixes: Optional[Sequence] = None,
              options: Optional[Dict] = None,
              keepfiles: bool = False,
              symbolic_solver_labels: bool = False):
        pass

    def available(self, exception_flag=True) -> bool:
        pass

    def license_is_valid(self) -> bool:
        pass

    def version(self) -> Tuple:
        pass

    @property
    def options(self) -> ConfigDict:
        pass

    @options.setter
    def options(self, val):
        pass

求解者通过装饰类来在SolverFactory中“注册”:

代码语言:javascript
运行
复制
from pyomo.opt import SolverFactory

@SolverFactory.register('demo', doc='DEMO Solver interface')
class DemoSolver(GenericSolverInterface):
    #...

或者通过显式调用注册函数

代码语言:javascript
运行
复制
SolverFactory.register('demo', doc='DEMO Solver Interface')(DemoSolver)

现在真正的诀窍是如何实现solve()方法。Pyomo将向solve()传递用户希望解决的模型(或Block)。然后,solve()需要将Pyomo模型/块转换为求解器所需的格式。这一步(显然)非常特定于解决程序,尽管对于一些常见的解决程序接口标准(例如LP文件、MPS文件、NL文件、BAR文件等)有一些标准化的方法。还有其他的“开发中”接口,它们更适合于特定的用例(直接内存中的解决器接口、APPSI、PyNumero)。

最简单(而且性能不太好)的方法可能是定义一个助手类,该类将Pyomo数据结构映射到一组简单的列表:

代码语言:javascript
运行
复制
from pyomo.core.base import Objective, Constraint
from pyomo.core.expr.visitor import identify_variables

class model_interface(object):
    def __init__(self, model):
        self.model = model
        self._obj = list(model.component_data_objects(Objective, active=True))
        self._con = list(model.component_data_objects(Constraint, active=True))
        self._var = {}
        for c in self._con:
            self._var.update({id(v): v for v in identify_variables(c.body)})
        self._var = list(self._var.values())

    @property
    def x(self):
        """Return the current list of variable values"""
        return [v.value for v in self._var]

    @x.setter
    def x(self, values):
        """Set the variables to new values"""
        for v, val in zip(self._var, values):
            v.set_value(val)

    @property
    def x_lb(self):
        """Return the list of variable lower bounds (may include None)"""
        return [v.lb for v in self._var]

    @property
    def x_ub(self):
        """Return the list of variable upper bounds (may include None)"""
        return [v.ub for v in self._var]

    @property
    def obj(self):
        """Return the list of objective values (computed using the current
        variable values)"""
        return [value(o) for o in self._obj]

    @property
    def con(self):
        """Return the list of constraint 'body' values (computed using the
        current variable values)
        """
        return [value(c) for c in self._con]

    @property
    def con_lb(self):
        """Return the list of constraint lower bounds (may include None)"""
        return [c.lb for c in self._con]

    @property
    def con_ub(self):
        """Return the list of constraint upper bounds (may include None)"""
        return [c.ub for c in self._con]
票数 0
EN

Stack Overflow用户

发布于 2022-10-24 15:00:05

是的,我们在Pyomo中有很多方法可以做到这一点,在pyomo.contrib中的各个模块中也有很多例子。我认为对学生来说最简单的方法是利用一个叫做PyNumero的Pyomo扩展模块,它是为用Python编写非线性优化算法而设计的,可以在这里找到:https://github.com/Pyomo/pyomo/tree/main/pyomo/contrib/pynumero

下面是使用PyNumero的几个实现示例:

SQP -> https://github.com/Pyomo/pyomo/blob/main/pyomo/contrib/pynumero/examples/sqp.py

内点-> https://github.com/Pyomo/pyomo/tree/main/pyomo/contrib/interior_point

与枕木方解器的接口--> https://github.com/Pyomo/pyomo/blob/main/pyomo/contrib/pynumero/algorithms/solvers/scipy_solvers.py

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74179391

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档