首页 > 解决方案 > 在 Pymoo 优化中提供约束

问题描述

我有一个目标函数,如下所示:

f1 = -1 * (constant1 * (variable1 - constant2))

而且我有一个约束,使得函数f1应该只取 10 到 20 之间的值,即

10 <= f1 <= 20    where, f1 = -1 * (constant1 * (variable1 - constant2))

如何在pymoo优化问题中编码上述约束。我对边界不感兴趣,因为正如我从文档中看到的那样,边界仅用于定义输入(x)值的限制,而不是用于定义目标函数(f1)本身的输出值的限制。我看到有两种方法可以定义约束:

  1. 直接在目标函数内部定义约束
  2. 定义一个Repair函数并指定其中的约束

repair任何人都可以指导我使用或默认方法构建此约束方程的代码吗?repair会更可取,因为它看起来很灵活

我已经阅读了 pymoo 的文档,这就是我能够为约束方程构建的所有内容:

g1 = f1-10
g2 = 20-f1

标签: pythonpython-3.xoptimization

解决方案


首先,我想指出,您的目标函数是一个简单的线性函数,需要在设计空间中有界才能在目标空间中有界。无论如何,我认为您的示例是概念证明。正如您在问题中已经说过的那样,您必须定义两个约束,一个是限制性f1 < 20的,另一个是限制性的f1 > 10。您不需要任何Repair操作员来实现您想要实现的目标。此外,在目标上设置边界通常会使修复变得非常困难。但是,对于您的简单问题,它也很容易实现(但一般来说并没有真正意义)。

为了实现您打算做的事情,您必须制定问题以符合 pymoo 定义。在pymoo中,约束违规定义如下:所有约束违规都小于零的解决方案被认为是可行的。如果至少一个约束违反大于零,则认为解决方案不可行。因此,上面的表达式需要是正确的(基本上是翻转的)。g1 = 10 - f1当 f1 大于 10 时 g2 = f1 - 20小于零(满足)。当 f1 小于 20 时小于零(满足)。完整的运行代码示例如下所示:

import numpy as np

from pymoo.algorithms.so_pattern_search import PatternSearch
from pymoo.model.problem import Problem
from pymoo.optimize import minimize


class MyProblem(Problem):

    def __init__(self, const_1, const_2):
        super().__init__(n_var=1, n_obj=1, n_constr=2, xl=0, xu=100, type_var=np.double)
        self.const_1 = const_1
        self.const_2 = const_2

    def _evaluate(self, x, out, *args, **kwargs):
        f = - (self.const_1 * (x[:, 0] - self.const_2))

        g1 = f - 20.0
        g2 = 10.0 - f
        G = np.column_stack([g1, g2])

        out["F"], out["G"] = f, G


problem = MyProblem(100.0, 1.0)

algorithm = PatternSearch()

res = minimize(problem,
               algorithm,
               seed=1,
               verbose=False)

print("Best solution found: \nX = %s\nF = %s" % (res.X, res.F))

对于此示例,请确保您定义const_1const_2能够在您定义的范围内获得目标值。否则,算法将无法找到可行的解决方案。

此外,我想提一下,在我们的入门指南中解释了有关在给定数学表达式的情况下实现目标和约束函数的更多细节。


推荐阅读