【问题标题】:Translating objective function and constraints into code将目标函数和约束转换为代码
【发布时间】:2021-07-09 16:49:57
【问题描述】:

几周以来,我一直在尝试解决个人项目中的问题,但运气不佳。最近我收到了数学堆栈交换的帮助,形式为这个问题的答案:https://math.stackexchange.com/a/4089367/907708,我现在正试图将答案中的方程式翻译成 python 代码,但我一直卡住。

为了便于访问,我将在此处重申问题(我试图发布答案,但格式很古怪,因此您必须参考上述答案的链接才能找到它。哎呀)

问题:

情况:我试图最小化列表中一系列不同高度的点之间的标准偏差,并限制列表中的每个点都可以在 0 到 2 个单位之间的任何位置上升为了最小化点之间的标准差。

示例:我有一个在 x 轴上等距但在 y 轴上不等距的点列表。

h = [20, 24, 28, 24 ,20 ,18, 20, 32 ,30, 28, 20 ,24]

列表中的每个数字代表该点的高度。

我还有一个限制,即列表中的每个点都可以增加一个从 0 到 2 的 c 值,以帮助实现更小的标准偏差。

我正在尝试创建一个算法来优化最小化 h 的点的标准偏差,其约束条件是 h 中的每个点都可以由 0 <= c <= n 提升,对于任何长度的 h 具有任何值和任何n > 0

我对优化问题非常陌生,虽然我看到了与我的问题相似的问题,但我还没有看到任何我能够收集到足够的信息来帮助我进一步找到答案的问题。

如果可能的话,我希望有人能帮助我定义目标函数、约束和其他必要的函数,以帮助我找到答案。

这不是家庭作业问题,因此我没有课程资料可以帮助指导我找到答案。我唯一的指导来自 cmets 和对这篇文章的回答。请理解,我绝不是数学家,所以我真的需要我能得到的所有帮助。谢谢!

结束问题:

我查看了无数 scipy.optimize 示例,试图弄清楚如何格式化我的代码以使其工作,但到目前为止我没有成功。我希望对该主题有更多了解的人可以帮助我翻译这些公式或告诉我应该查看哪些库或材料以帮助回答这个问题。 (我会发布到目前为止我尝试过的代码 sn-ps 集合,但它们都没有让我有任何价值,我认为它们不会提供任何有价值的见解来回答这个问题,所以我故意省略了它们)

非常感谢任何反馈,我一定会迅速回复您的任何问题或问题。非常感谢!

【问题讨论】:

    标签: python scipy statistics data-science scipy-optimize


    【解决方案1】:

    您可以安装PyGad。遗传算法非常适合这种优化问题。此外,它更容易实现,恕我直言。只需执行pip install pygad。以下是解决您的问题的代码。我正在使用 PyGad 的默认配置。适应度函数评估任何候选解决方案的好坏。由于 PyGad 试图最大化(并且我们想要最小化),我们在适应度函数中返回 1/evaluation。我们可以通过为任何无效的候选解决方案返回-100(不良适应度)来设置约束。我插入了数学堆栈解决方案中给出的公式并预计算了x_bar,即使它应该花费不到 5 秒。具体问题的配置是:fitness_funcnum_genesci 值的初始猜测 (init_range_low/high)。

    import pygad
    import numpy as np
    
    
    X = [20, 24, 28, 24 ,20 ,18, 20, 32 ,30, 28, 20 ,24]
    X_BAR = np.array(X).sum()/len(X)
    
    def fitness_function(solution, solution_idx):
        c_bar = np.array(solution).sum()/len(solution)
        accum = 0
        for i, ci in enumerate(solution):
            if ci < 0 or ci > 2:
                return -100
            accum += (X[i] + ci - (X_BAR + c_bar))**2
        fitness = 1/accum
        return fitness
    
    
    ga_instance = pygad.GA(num_generations=100,
                           num_parents_mating=7,
                           fitness_func=fitness_function,
                           sol_per_pop=50,
                           num_genes=len(X),
                           init_range_low=0,
                           init_range_high=2,
                           parent_selection_type="sss",
                           keep_parents=7,
                           crossover_type="single_point",
                           mutation_type="random",
                           mutation_percent_genes=10)
    
    ga_instance.run()
    ga_instance.plot_result()
    
    sol, sol_fitness, sol_idx = ga_instance.best_solution()
    print("Parameters of the best solution : {solution}".format(solution=sol))
    

    以下是适应度的演变方式:

    最后算法给出的解是:

    [1.99574728e+00 1.00786156e+00 2.17545152e-02 1.16404525e+00
     1.98465204e+00 1.98997128e+00 1.98167328e+00 1.32911147e-02
     1.17406735e-03 1.30281600e-04 1.99916130e+00 1.17383310e+00]
    

    【讨论】:

    • 您好,感谢您的回答!我想知道您是否可以解释为算法提供的解决方案意味着什么,因为我对遗传算法的了解严重不足。另外,我想知道是否有任何方法可以告诉您需要从您的解决方案中提出多高的每个点?再次感谢!
    【解决方案2】:

    使用scipy.optimize.minimize的另一种解决方案:

    from scipy.optimize import minimize
    
    x = np.array([20, 24, 28, 24 ,20 ,18, 20, 32 ,30, 28, 20 ,24])
    
    # define the objective to minimize 
    # (here c is the variable and x is a additional argument)
    def obj(c, x): return np.sum((x+c -(np.mean(x) + np.mean(c)))**2)
    
    # Variable bounds: 0 <= ci <= 2
    bounds = [(0, 2) for _ in range(len(x))]
    
    # initial guess for the solver
    c0 = np.ones_like(x)
    
    # call the solver and pass a function that only depends on the variable c
    res = minimize(lambda c: obj(c, x), x0=c0, bounds=bounds)
    
    # your solution
    print(res.x)
    

    给予

    array([2.        , 1.11111256, 0.        , 1.11111256, 2.        ,
           2.        , 2.        , 0.        , 0.        , 0.        ,
           2.        , 1.11111446])
    

    【讨论】:

    • 非常感谢,我真的很喜欢这个答案!我想知道您是否知道我可以验证此结果是否最佳的任何方法。如果不是我仍然非常感谢它!再次感谢!
    • 为此,您可以查看res.message。优化器找到了梯度范数低于给定容差的点,因此它是一个局部最小化器。由于您的问题是凸的,因此每个局部最小化器都是全局最小化器。因此,没有更好的解决方案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-05
    • 1970-01-01
    • 2021-09-22
    • 1970-01-01
    相关资源
    最近更新 更多