Python 和 Java 代码实现:黄金分割法求解一维最优化问题

本文主要是介绍Python 和 Java 代码实现:黄金分割法求解一维最优化问题,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Python 和 Java 代码实现:黄金分割法求解一维最优化问题

  • 问题描述
    • 区间消去法
    • 黄金分割法
  • 代码实现
    • Python代码
    • Java代码
  • 求解实例

开启一个新系列的学习,这位大佬的文章写的很通透,且有代码实践,个人觉得只有自己把代码写出来了才是真的会了,我对自己的算法学习要求也是这样的,所以推荐!

问题描述

我不是运筹学科班出身,工作之前只做过梯度优化算法和智能优化算法在航天场景中的改进和应用。毕业后虽然选择了运筹优化算法工程师的道路,但却深知自己的运筹认知不够体系化,很想找些书,系统补一下这方面的基础内容。

不过现在国内的运筹学教材大多都是单纯形法起步,看起来挺费劲的。而且我的关注点有:算法原理、不同算法间的联系和区别、工程(Python/Java)实现等,很多内容书上也很难都有。所以我打算基于一些比较简单的优化问题为起点,从简单到复杂,自行去认识和理解这些运筹优化算法。

能想到的最简单的优化问题,应该就是一维最优化问题了:在一个搜索区间内,包含了目标函数的极小值点,而且是个单峰区间,即在该区间内目标函数只有一个极值,下图为一维最优化问题的示意图。图片

区间消去法

在这里插入图片描述

图片

按照以上逻辑不断选取两个点做对比,便可以不断缩小搜索区间,直至搜索区间的长度低于某阈值,即找到了极小值。

在这里插入图片描述

黄金分割法

区间消去法虽然给出了搜索区间缩小的原理,但是每次和该如何选择,却并没有给出具体方案。黄金分割法便在区间消去法的基础上,对c和d的选择做了约束,进而给出它们的确定逻辑:

在这里插入图片描述

代码实现

本文会基于Python和Java语言进行算法实现。Python代码简单,便于学习理解;Java运行速度快,便于工程应用;MATLAB版本就不考虑了,对运筹优化算法的学习和落地应用而言,MATLAB基本没有多少竞争力。

在这里插入图片描述

Python代码

以下的golden_section函数为黄金分割法的Python代码。除该代码外,主函数中还增加了一个for循环,该循环的目的是多次重复调用黄金分割法,以此评估Python代码的计算耗时。

import time  # 待优化函数  
def f(t):  return t ** 2 - t * 5 + 8  def golden_section(a, b, eps):  # 统计迭代次数  cnt = 0  while b - a > eps:  # 根据黄金分割法规则选择内部两点  c = a + (b - a) * 0.382  d = a + (b - a) * 0.618  # 区间消去原理  if f(c) < f(d):  b = d  else:  a = c  cnt += 1  # 两点的中点定义为最优解  return (a + b) / 2, f((a + b) / 2), cnt  if __name__ == '__main__':  # 参数设置  left_point = 1  right_point = 7  min_interval_value = 0.1  # 调用黄金分割法函数求解最小值  best_x, best_y, iter_cnt = 0, 0, 0  t0 = time.time()  for i in range(100000):  best_x, best_y, iter_cnt = golden_section(left_point, right_point, min_interval_value)  print('总耗时为:{} ms'.format((time.time() - t0) * 1000))  print('best_x: {}, best_y: {}, iter_cnt: {}.'.format(best_x, best_y, iter_cnt))  

Java代码

以下的goldenSection函数为黄金分割法的Java代码。与上文一样,主函数中也增加了一个for循环,以此评估Java代码的计算耗时。

public class GoldenSection {  // 主函数入口  public static void main(String[] args) {  // 参数设置  int leftPoint = 1;  int rightPoint = 7;  double minIntervalValue = 0.1;  long t0 = System.currentTimeMillis();  Solution best_solution = new Solution();  for (int i = 0; i < 100000; i++) {  // 调用黄金分割法函数求解最小值  best_solution = goldenSection(leftPoint, rightPoint, minIntervalValue);  }  System.out.println("计算总耗时为: " + (System.currentTimeMillis()-t0) + " ms");  // 输出优化结果  System.out.println("best_x: " + best_solution.best_x);  System.out.println("best_y: " + best_solution.best_y);  System.out.println("cnt: " + best_solution.cnt);  }  // 黄金分割法  private static Solution goldenSection(double a, double b, double eps) {  // 统计迭代次数  int cnt = 0;  while (b - a > eps) {  // 根据黄金分割法规则选择内部两点  double c = a + (b - a) * 0.382;  double d = a + (b - a) * 0.618;  // 区间消去原理  if (f(c) < f(d)) {  b = d;  } else {  a = c;  }  // 更新迭代次数  cnt ++;  }  // 构造最优解对象  Solution best_solution = new Solution();  best_solution.best_x = (a + b) / 2;  best_solution.best_y = f((a + b) / 2);  best_solution.cnt = cnt;  return best_solution;  }  // 待优化函数  private static double f(double t) {  return t * t - t * 5 + 8;  }  // 解对象  private static class Solution {  double best_x;  double best_y;  int cnt;  }  
}  

求解实例

首先运行Python代码,可以得到最优解为1.75,迭代次数为9次。计算100000次,共耗时515毫秒。

总耗时为:515.2740478515625 ms  
best_x: 2.5045211503093046, best_y: 1.7500204408001192, iter_cnt: 9.  

再运行Java代码,可以得到和Python代码相同的解。计算100000次,仅耗时11毫秒。相比之下,Java代码耗时仅为Python代码耗时的2%。对运筹优化算法来说,计算速度是非常重要的,所以如果代码能力允许,尽量使用Java。

计算总耗时为: 11 ms  
best_x: 2.5045211503093046  
best_y: 1.7500204408001192  
cnt: 9  

这篇关于Python 和 Java 代码实现:黄金分割法求解一维最优化问题的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/614094

相关文章

springboot健康检查监控全过程

《springboot健康检查监控全过程》文章介绍了SpringBoot如何使用Actuator和Micrometer进行健康检查和监控,通过配置和自定义健康指示器,开发者可以实时监控应用组件的状态,... 目录1. 引言重要性2. 配置Spring Boot ActuatorSpring Boot Act

使用Java解析JSON数据并提取特定字段的实现步骤(以提取mailNo为例)

《使用Java解析JSON数据并提取特定字段的实现步骤(以提取mailNo为例)》在现代软件开发中,处理JSON数据是一项非常常见的任务,无论是从API接口获取数据,还是将数据存储为JSON格式,解析... 目录1. 背景介绍1.1 jsON简介1.2 实际案例2. 准备工作2.1 环境搭建2.1.1 添加

Java实现任务管理器性能网络监控数据的方法详解

《Java实现任务管理器性能网络监控数据的方法详解》在现代操作系统中,任务管理器是一个非常重要的工具,用于监控和管理计算机的运行状态,包括CPU使用率、内存占用等,对于开发者和系统管理员来说,了解这些... 目录引言一、背景知识二、准备工作1. Maven依赖2. Gradle依赖三、代码实现四、代码详解五

Redis连接失败:客户端IP不在白名单中的问题分析与解决方案

《Redis连接失败:客户端IP不在白名单中的问题分析与解决方案》在现代分布式系统中,Redis作为一种高性能的内存数据库,被广泛应用于缓存、消息队列、会话存储等场景,然而,在实际使用过程中,我们可能... 目录一、问题背景二、错误分析1. 错误信息解读2. 根本原因三、解决方案1. 将客户端IP添加到Re

java如何分布式锁实现和选型

《java如何分布式锁实现和选型》文章介绍了分布式锁的重要性以及在分布式系统中常见的问题和需求,它详细阐述了如何使用分布式锁来确保数据的一致性和系统的高可用性,文章还提供了基于数据库、Redis和Zo... 目录引言:分布式锁的重要性与分布式系统中的常见问题和需求分布式锁的重要性分布式系统中常见的问题和需求

SpringBoot基于MyBatis-Plus实现Lambda Query查询的示例代码

《SpringBoot基于MyBatis-Plus实现LambdaQuery查询的示例代码》MyBatis-Plus是MyBatis的增强工具,简化了数据库操作,并提高了开发效率,它提供了多种查询方... 目录引言基础环境配置依赖配置(Maven)application.yml 配置表结构设计demo_st

使用Python绘制蛇年春节祝福艺术图

《使用Python绘制蛇年春节祝福艺术图》:本文主要介绍如何使用Python的Matplotlib库绘制一幅富有创意的“蛇年有福”艺术图,这幅图结合了数字,蛇形,花朵等装饰,需要的可以参考下... 目录1. 绘图的基本概念2. 准备工作3. 实现代码解析3.1 设置绘图画布3.2 绘制数字“2025”3.3

在Ubuntu上部署SpringBoot应用的操作步骤

《在Ubuntu上部署SpringBoot应用的操作步骤》随着云计算和容器化技术的普及,Linux服务器已成为部署Web应用程序的主流平台之一,Java作为一种跨平台的编程语言,具有广泛的应用场景,本... 目录一、部署准备二、安装 Java 环境1. 安装 JDK2. 验证 Java 安装三、安装 mys

Springboot的ThreadPoolTaskScheduler线程池轻松搞定15分钟不操作自动取消订单

《Springboot的ThreadPoolTaskScheduler线程池轻松搞定15分钟不操作自动取消订单》:本文主要介绍Springboot的ThreadPoolTaskScheduler线... 目录ThreadPoolTaskScheduler线程池实现15分钟不操作自动取消订单概要1,创建订单后

详谈redis跟数据库的数据同步问题

《详谈redis跟数据库的数据同步问题》文章讨论了在Redis和数据库数据一致性问题上的解决方案,主要比较了先更新Redis缓存再更新数据库和先更新数据库再更新Redis缓存两种方案,文章指出,删除R... 目录一、Redis 数据库数据一致性的解决方案1.1、更新Redis缓存、删除Redis缓存的区别二