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

相关文章

Java NoClassDefFoundError运行时错误分析解决

《JavaNoClassDefFoundError运行时错误分析解决》在Java开发中,NoClassDefFoundError是一种常见的运行时错误,它通常表明Java虚拟机在尝试加载一个类时未能... 目录前言一、问题分析二、报错原因三、解决思路检查类路径配置检查依赖库检查类文件调试类加载器问题四、常见

Java注解之超越Javadoc的元数据利器详解

《Java注解之超越Javadoc的元数据利器详解》本文将深入探讨Java注解的定义、类型、内置注解、自定义注解、保留策略、实际应用场景及最佳实践,无论是初学者还是资深开发者,都能通过本文了解如何利用... 目录什么是注解?注解的类型内置注编程解自定义注解注解的保留策略实际用例最佳实践总结在 Java 编程

Python中模块graphviz使用入门

《Python中模块graphviz使用入门》graphviz是一个用于创建和操作图形的Python库,本文主要介绍了Python中模块graphviz使用入门,具有一定的参考价值,感兴趣的可以了解一... 目录1.安装2. 基本用法2.1 输出图像格式2.2 图像style设置2.3 属性2.4 子图和聚

Python使用Matplotlib绘制3D曲面图详解

《Python使用Matplotlib绘制3D曲面图详解》:本文主要介绍Python使用Matplotlib绘制3D曲面图,在Python中,使用Matplotlib库绘制3D曲面图可以通过mpl... 目录准备工作绘制简单的 3D 曲面图绘制 3D 曲面图添加线框和透明度控制图形视角Matplotlib

一文教你Python如何快速精准抓取网页数据

《一文教你Python如何快速精准抓取网页数据》这篇文章主要为大家详细介绍了如何利用Python实现快速精准抓取网页数据,文中的示例代码简洁易懂,具有一定的借鉴价值,有需要的小伙伴可以了解下... 目录1. 准备工作2. 基础爬虫实现3. 高级功能扩展3.1 抓取文章详情3.2 保存数据到文件4. 完整示例

使用Python实现IP地址和端口状态检测与监控

《使用Python实现IP地址和端口状态检测与监控》在网络运维和服务器管理中,IP地址和端口的可用性监控是保障业务连续性的基础需求,本文将带你用Python从零打造一个高可用IP监控系统,感兴趣的小伙... 目录概述:为什么需要IP监控系统使用步骤说明1. 环境准备2. 系统部署3. 核心功能配置系统效果展

解决IDEA报错:编码GBK的不可映射字符问题

《解决IDEA报错:编码GBK的不可映射字符问题》:本文主要介绍解决IDEA报错:编码GBK的不可映射字符问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录IDEA报错:编码GBK的不可映射字符终端软件问题描述原因分析解决方案方法1:将命令改为方法2:右下jav

Java 实用工具类Spring 的 AnnotationUtils详解

《Java实用工具类Spring的AnnotationUtils详解》Spring框架提供了一个强大的注解工具类org.springframework.core.annotation.Annot... 目录前言一、AnnotationUtils 的常用方法二、常见应用场景三、与 JDK 原生注解 API 的

基于Python打造一个智能单词管理神器

《基于Python打造一个智能单词管理神器》这篇文章主要为大家详细介绍了如何使用Python打造一个智能单词管理神器,从查询到导出的一站式解决,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1. 项目概述:为什么需要这个工具2. 环境搭建与快速入门2.1 环境要求2.2 首次运行配置3. 核心功能使用指

Java controller接口出入参时间序列化转换操作方法(两种)

《Javacontroller接口出入参时间序列化转换操作方法(两种)》:本文主要介绍Javacontroller接口出入参时间序列化转换操作方法,本文给大家列举两种简单方法,感兴趣的朋友一起看... 目录方式一、使用注解方式二、统一配置场景:在controller编写的接口,在前后端交互过程中一般都会涉及