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

相关文章

C#高效实现在Word文档中自动化创建图表的可视化方案

《C#高效实现在Word文档中自动化创建图表的可视化方案》本文将深入探讨如何利用C#,结合一款功能强大的第三方库,实现在Word文档中自动化创建图表,为你的数据呈现和报告生成提供一套实用且高效的解决方... 目录Word文档图表自动化:为什么选择C#?从零开始:C#实现Word文档图表的基本步骤深度优化:C

Nginx服务器部署详细代码实例

《Nginx服务器部署详细代码实例》Nginx是一个高性能的HTTP和反向代理web服务器,同时也提供了IMAP/POP3/SMTP服务,:本文主要介绍Nginx服务器部署的相关资料,文中通过代码... 目录Nginx 服务器SSL/TLS 配置动态脚本反向代理总结Nginx 服务器Nginx是一个‌高性

SpringBoot整合AOP及使用案例实战

《SpringBoot整合AOP及使用案例实战》本文详细介绍了SpringAOP中的切入点表达式,重点讲解了execution表达式的语法和用法,通过案例实战,展示了AOP的基本使用、结合自定义注解以... 目录一、 引入依赖二、切入点表达式详解三、案例实战1. AOP基本使用2. AOP结合自定义注解3.

Python中Request的安装以及简单的使用方法图文教程

《Python中Request的安装以及简单的使用方法图文教程》python里的request库经常被用于进行网络爬虫,想要学习网络爬虫的同学必须得安装request这个第三方库,:本文主要介绍P... 目录1.Requests 安装cmd 窗口安装为pycharm安装在pycharm设置中为项目安装req

Python容器转换与共有函数举例详解

《Python容器转换与共有函数举例详解》Python容器是Python编程语言中非常基础且重要的概念,它们提供了数据的存储和组织方式,下面:本文主要介绍Python容器转换与共有函数的相关资料,... 目录python容器转换与共有函数详解一、容器类型概览二、容器类型转换1. 基本容器转换2. 高级转换示

nginx跨域访问配置的几种方法实现

《nginx跨域访问配置的几种方法实现》本文详细介绍了Nginx跨域配置方法,包括基本配置、只允许指定域名、携带Cookie的跨域、动态设置允许的Origin、支持不同路径的跨域控制、静态资源跨域以及... 目录一、基本跨域配置二、只允许指定域名跨域三、完整示例四、配置后重载 nginx五、注意事项六、支持

Qt实现对Word网页的读取功能

《Qt实现对Word网页的读取功能》文章介绍了几种在Qt中实现Word文档(.docx/.doc)读写功能的方法,包括基于QAxObject的COM接口调用、DOCX模板替换及跨平台解决方案,重点讨论... 目录1. 核心实现方式2. 基于QAxObject的COM接口调用(Windows专用)2.1 环境

MySQL查看表的历史SQL的几种实现方法

《MySQL查看表的历史SQL的几种实现方法》:本文主要介绍多种查看MySQL表历史SQL的方法,包括通用查询日志、慢查询日志、performance_schema、binlog、第三方工具等,并... 目录mysql 查看某张表的历史SQL1.查看MySQL通用查询日志(需提前开启)2.查看慢查询日志3.

Java实现字符串大小写转换的常用方法

《Java实现字符串大小写转换的常用方法》在Java中,字符串大小写转换是文本处理的核心操作之一,Java提供了多种灵活的方式来实现大小写转换,适用于不同场景和需求,本文将全面解析大小写转换的各种方法... 目录前言核心转换方法1.String类的基础方法2. 考虑区域设置的转换3. 字符级别的转换高级转换

使用Python将PDF表格自动提取并写入Word文档表格

《使用Python将PDF表格自动提取并写入Word文档表格》在实际办公与数据处理场景中,PDF文件里的表格往往无法直接复制到Word中,本文将介绍如何使用Python从PDF文件中提取表格数据,并将... 目录引言1. 加载 PDF 文件并准备 Word 文档2. 提取 PDF 表格并创建 Word 表格