<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>黄金比例搜索算法 &#8211; 编码无悔 /  Intent &amp; Focused</title>
	<atom:link href="https://www.codelast.com/tag/%E9%BB%84%E9%87%91%E6%AF%94%E4%BE%8B%E6%90%9C%E7%B4%A2%E7%AE%97%E6%B3%95/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.codelast.com</link>
	<description>最优化之路</description>
	<lastBuildDate>Sun, 03 May 2020 13:03:23 +0000</lastBuildDate>
	<language>zh-Hans</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>
	<item>
		<title>[原创]黄金比例搜索算法（Golden Section Search）的实现</title>
		<link>https://www.codelast.com/%e5%8e%9f%e5%88%9b-%e9%bb%84%e9%87%91%e6%af%94%e4%be%8b%e6%90%9c%e7%b4%a2%e7%ae%97%e6%b3%95%ef%bc%88golden-ratio-search-algorithm%ef%bc%89%e7%9a%84%e5%ae%9e%e7%8e%b0/</link>
					<comments>https://www.codelast.com/%e5%8e%9f%e5%88%9b-%e9%bb%84%e9%87%91%e6%af%94%e4%be%8b%e6%90%9c%e7%b4%a2%e7%ae%97%e6%b3%95%ef%bc%88golden-ratio-search-algorithm%ef%bc%89%e7%9a%84%e5%ae%9e%e7%8e%b0/#comments</comments>
		
		<dc:creator><![CDATA[learnhard]]></dc:creator>
		<pubDate>Sun, 19 Sep 2010 03:14:43 +0000</pubDate>
				<category><![CDATA[Algorithm]]></category>
		<category><![CDATA[原创]]></category>
		<category><![CDATA[golden section search]]></category>
		<category><![CDATA[optimization]]></category>
		<category><![CDATA[最优化]]></category>
		<category><![CDATA[黄金比例搜索算法]]></category>
		<guid isPermaLink="false">http://www.codelast.com/?p=434</guid>

					<description><![CDATA[<p><span id="more-434"></span></p>
<p>
	<span style="font-size: 14px; font-family: arial, helvetica, sans-serif; color: rgb(0, 0, 255);">黄金比例搜索算法/黄金分割法/0.618法/Golden Section Search/Golden Ratio Search</span><span style="font-size: 14px; font-family: arial, helvetica, sans-serif;"> 表达的都是同一个东西，它是一种精确的一维搜索（line search）算法。</span></p>
<p>
	<br />
	<span style="font-family:arial,helvetica,sans-serif;"><span style="font-size:14px;">黄金比例搜索算法只需要计算目标函数值，而无需计算导数之类的值，因此用起来非常容易，应用广泛。</span></span><br />
	这里要瞎扯一下：我们都知道黄金比例是0.618，但是你可能没注意到黄金比例还有一些神奇的特性，例如1&#247;0.618=1+0.618。在建筑学中，也经常使用黄金比例来达到美学效果，例如，代表了全希腊建筑艺术的最高水平的帕特农神庙的立面高与宽的比例为19比31，接近黄金比例。</p>
<p>
	<span style="font-family:arial,helvetica,sans-serif;"><span style="font-size:14px;">要使用黄金比例搜索算法，函数 <span class='MathJax_Preview'><img src='https://www.codelast.com/wp-content/plugins/latex/cache/tex_50bbd36e1fd2333108437a2ca378be62.gif' style='vertical-align: middle; border: none; padding-bottom:2px;' class='tex' alt="f(x)" /></span><script type='math/tex'>f(x)</script> 需要在某一区间内满足<strong><span style="color:#00f;">单峰</span></strong>（<strong><span style="color:#000080;">unimodal</span></strong>）条件。那么什么是单峰呢？看<a href="http://www.codelast.com/?p=7360" rel="noopener noreferrer" target="_blank"><span style="background-color:#ffa07a;">这里</span></a>。</span></span></p>
<p>
	<span style="color: rgb(255, 255, 255);">文章来源：</span><a href="http://www.codelast.com/" rel="noopener noreferrer" target="_blank"><span style="color: rgb(255, 255, 255);">http://www.codelast.com/</span></a></p>
<p>
	<span style="font-family:arial,helvetica,sans-serif;"><span style="font-size:14px;">在这种情况下，就具备使用该算法的条件了。</span></span></p>
<p>
	<span style="font-family:arial,helvetica,sans-serif;"><span style="font-size:14px;">有人说，我想用golden section search，但是我怎么能保证在我的搜索区间之内函数是单峰的呢？这就涉及到另一种技术了&#8212;&#8212;<a href="http://www.codelast.com/?p=7360" rel="noopener noreferrer" target="_blank"><span style="background-color:#ffa07a;">划界</span></a>。试想一下，<span style="color:#f00;">类似</span>于f(x)=sinx这样的函数图形，在一个区间之内可能有多个波峰波谷，你如何能确定它在一个区间内的极值呢？靠的就是划界。但是，这不在本文的讨论范围内，我们假设你的搜索区间已经使得目标函数在其上是单峰的了。</span></span></p>
<p>
	<span style="font-family:arial,helvetica,sans-serif;"><span style="font-size:14px;">怎么那么麻烦呢？每次只要一涉及到一个算法，就会用到另一个算法/技术，没办法，数学就是这样层层相套。像最优化中的&#8220;单纯形法&#8221;那样对其他算法依赖很少的算法，应该算比较少的吧（相比之下，Powell算法真是个麻烦的角色）。</span></span></p>
<p>
	<span style="font-family:arial,helvetica,sans-serif;"><span style="font-size:14px;">若已知f(x)在[a,b]上单峰，则可用一个含有f(x)最小值的子区间来代替区间I。有一个方法是：选取两个<span style="color:#00f;">内点</span>c,d（其中c&#60;d），即有a&#60;c&#60;d&#60;b。f(x)的单峰保证了f(c) &#60; max {f(a), f(b)} 且 f(d) &#60; max {f(a), f(b)}。</span></span></p>
<p>
	&#160;</p>
<p>
	<span style="font-family:arial,helvetica,sans-serif;"><span style="font-size:14px;">这里又提到了另一个概念：<strong><span style="color: rgb(0, 0, 255); ">内点</span></strong>。什么是内点呢？</span></span></p>
<p>
	<span style="font-family:arial,helvetica,sans-serif;"><span style="font-size:14px;">&#60;<span style="color:#f00;">定义</span>&#62;<span style="color:#008000;">数学上，集合 S 的内部（又称开核）含有所有直观上&#8220;不在 S 的边界上&#8221;的 S 的点。S 的内部中的点称为 S 的内点。</span></span></span></p>
<p>
	<span style="color: rgb(255, 255, 255);">文章来源：</span><a href="http://www.codelast.com/" rel="noopener noreferrer" target="_blank"><span style="color: rgb(255, 255, 255);">http://www.codelast.com/</span></a>&#8230; <a href="https://www.codelast.com/%e5%8e%9f%e5%88%9b-%e9%bb%84%e9%87%91%e6%af%94%e4%be%8b%e6%90%9c%e7%b4%a2%e7%ae%97%e6%b3%95%ef%bc%88golden-ratio-search-algorithm%ef%bc%89%e7%9a%84%e5%ae%9e%e7%8e%b0/" class="read-more">Read More </a></p>]]></description>
										<content:encoded><![CDATA[<p><span id="more-434"></span></p>
<p>
	<span style="font-size: 14px; font-family: arial, helvetica, sans-serif; color: rgb(0, 0, 255);">黄金比例搜索算法/黄金分割法/0.618法/Golden Section Search/Golden Ratio Search</span><span style="font-size: 14px; font-family: arial, helvetica, sans-serif;"> 表达的都是同一个东西，它是一种精确的一维搜索（line search）算法。</span></p>
<p>
	<br />
	<span style="font-family:arial,helvetica,sans-serif;"><span style="font-size:14px;">黄金比例搜索算法只需要计算目标函数值，而无需计算导数之类的值，因此用起来非常容易，应用广泛。</span></span><br />
	这里要瞎扯一下：我们都知道黄金比例是0.618，但是你可能没注意到黄金比例还有一些神奇的特性，例如1&divide;0.618=1+0.618。在建筑学中，也经常使用黄金比例来达到美学效果，例如，代表了全希腊建筑艺术的最高水平的帕特农神庙的立面高与宽的比例为19比31，接近黄金比例。</p>
<p>
	<span style="font-family:arial,helvetica,sans-serif;"><span style="font-size:14px;">要使用黄金比例搜索算法，函数 <span class='MathJax_Preview'><img src='https://www.codelast.com/wp-content/plugins/latex/cache/tex_50bbd36e1fd2333108437a2ca378be62.gif' style='vertical-align: middle; border: none; padding-bottom:2px;' class='tex' alt="f(x)" /></span><script type='math/tex'>f(x)</script> 需要在某一区间内满足<strong><span style="color:#00f;">单峰</span></strong>（<strong><span style="color:#000080;">unimodal</span></strong>）条件。那么什么是单峰呢？看<a href="http://www.codelast.com/?p=7360" rel="noopener noreferrer" target="_blank"><span style="background-color:#ffa07a;">这里</span></a>。</span></span></p>
<p>
	<span style="color: rgb(255, 255, 255);">文章来源：</span><a href="http://www.codelast.com/" rel="noopener noreferrer" target="_blank"><span style="color: rgb(255, 255, 255);">http://www.codelast.com/</span></a></p>
<p>
	<span style="font-family:arial,helvetica,sans-serif;"><span style="font-size:14px;">在这种情况下，就具备使用该算法的条件了。</span></span></p>
<p>
	<span style="font-family:arial,helvetica,sans-serif;"><span style="font-size:14px;">有人说，我想用golden section search，但是我怎么能保证在我的搜索区间之内函数是单峰的呢？这就涉及到另一种技术了&mdash;&mdash;<a href="http://www.codelast.com/?p=7360" rel="noopener noreferrer" target="_blank"><span style="background-color:#ffa07a;">划界</span></a>。试想一下，<span style="color:#f00;">类似</span>于f(x)=sinx这样的函数图形，在一个区间之内可能有多个波峰波谷，你如何能确定它在一个区间内的极值呢？靠的就是划界。但是，这不在本文的讨论范围内，我们假设你的搜索区间已经使得目标函数在其上是单峰的了。</span></span></p>
<p>
	<span style="font-family:arial,helvetica,sans-serif;"><span style="font-size:14px;">怎么那么麻烦呢？每次只要一涉及到一个算法，就会用到另一个算法/技术，没办法，数学就是这样层层相套。像最优化中的&ldquo;单纯形法&rdquo;那样对其他算法依赖很少的算法，应该算比较少的吧（相比之下，Powell算法真是个麻烦的角色）。</span></span></p>
<p>
	<span style="font-family:arial,helvetica,sans-serif;"><span style="font-size:14px;">若已知f(x)在[a,b]上单峰，则可用一个含有f(x)最小值的子区间来代替区间I。有一个方法是：选取两个<span style="color:#00f;">内点</span>c,d（其中c&lt;d），即有a&lt;c&lt;d&lt;b。f(x)的单峰保证了f(c) &lt; max {f(a), f(b)} 且 f(d) &lt; max {f(a), f(b)}。</span></span></p>
<p>
	&nbsp;</p>
<p>
	<span style="font-family:arial,helvetica,sans-serif;"><span style="font-size:14px;">这里又提到了另一个概念：<strong><span style="color: rgb(0, 0, 255); ">内点</span></strong>。什么是内点呢？</span></span></p>
<p>
	<span style="font-family:arial,helvetica,sans-serif;"><span style="font-size:14px;">&lt;<span style="color:#f00;">定义</span>&gt;<span style="color:#008000;">数学上，集合 S 的内部（又称开核）含有所有直观上&ldquo;不在 S 的边界上&rdquo;的 S 的点。S 的内部中的点称为 S 的内点。</span></span></span></p>
<p>
	<span style="color: rgb(255, 255, 255);">文章来源：</span><a href="http://www.codelast.com/" rel="noopener noreferrer" target="_blank"><span style="color: rgb(255, 255, 255);">http://www.codelast.com/</span></a></p>
<p>
	<span style="font-family:arial,helvetica,sans-serif;"><span style="font-size:14px;">现在有两种情况需要考虑：</span></span></p>
<p>
	<span style="font-family:arial,helvetica,sans-serif;"><span style="font-size:14px;">（1）</span></span> <span class='MathJax_Preview'><img src='https://www.codelast.com/wp-content/plugins/latex/cache/tex_8dde956d55b3a51d0a1d90bcb05a1cd6.gif' style='vertical-align: middle; border: none; padding-bottom:2px;' class='tex' alt="f(c) \le f(d)" /></span><script type='math/tex'>f(c) \le f(d)</script> <span style="font-size: 14px; font-family: arial, helvetica, sans-serif;">，则极小值出现在子区间</span> <span class='MathJax_Preview'><img src='https://www.codelast.com/wp-content/plugins/latex/cache/tex_2e3641787f2efdb94c0f01f2b279538a.gif' style='vertical-align: middle; border: none; padding-bottom:2px;' class='tex' alt="[a,d]" /></span><script type='math/tex'>[a,d]</script> <span style="font-family: arial, helvetica, sans-serif; font-size: 14px;">中，所以我们用d代替b，继续在子区间</span> <span class='MathJax_Preview'><img src='https://www.codelast.com/wp-content/plugins/latex/cache/tex_2e3641787f2efdb94c0f01f2b279538a.gif' style='vertical-align: middle; border: none; padding-bottom:2px;' class='tex' alt="[a,d]" /></span><script type='math/tex'>[a,d]</script> <span style="font-family: arial, helvetica, sans-serif; font-size: 14px;">中搜索；</span></p>
<p>
	<span style="font-family:arial,helvetica,sans-serif;"><span style="font-size:14px;">（2）</span></span> <span class='MathJax_Preview'><img src='https://www.codelast.com/wp-content/plugins/latex/cache/tex_61c06d01dcf37df477ac939e906f64e3.gif' style='vertical-align: middle; border: none; padding-bottom:2px;' class='tex' alt="f(d) < f(c)" /></span><script type='math/tex'>f(d) < f(c)</script> <span style="font-family:arial,helvetica,sans-serif;"><span style="font-size:14px;">，则极小值出现在子区间</span></span> <span class='MathJax_Preview'><img src='https://www.codelast.com/wp-content/plugins/latex/cache/tex_d6033df87877013a91e322ce6a5bc181.gif' style='vertical-align: middle; border: none; padding-bottom:2px;' class='tex' alt="[c,b]" /></span><script type='math/tex'>[c,b]</script> <span style="font-size: 14px; font-family: arial, helvetica, sans-serif;">中，所以我们用c代替a，继续在子区间</span> <span class='MathJax_Preview'><img src='https://www.codelast.com/wp-content/plugins/latex/cache/tex_209f61583177d88b1f24c85f6a43c6ff.gif' style='vertical-align: middle; border: none; padding-bottom:2px;' class='tex' alt="[a,c]" /></span><script type='math/tex'>[a,c]</script> <span style="font-size: 14px; font-family: arial, helvetica, sans-serif;">中搜索。</span></p>
<p>
	<span style="font-family:arial,helvetica,sans-serif;"><span style="font-size:14px;">这里要注意了：我们选取的两个内点不是随意选定的，而是特殊选定的，我们人为地使[a, c]与[d, b]对称，即b-d = c-a，从而：</span></span></p>
<p>
	<span style="font-family:arial,helvetica,sans-serif;"><span style="font-size:14px;">（3）c=a+(1-r)(b-a)=ra+(1-r)b</span></span></p>
<p>
	<span style="font-family:arial,helvetica,sans-serif;"><span style="font-size:14px;">（4）d=b-(1-r)(b-a)=(1-r)a+rb<br />
	</span></span></p>
<p>
	<span style="font-family:arial,helvetica,sans-serif;"><span style="font-size:14px;">此处r&isin;(0.5, 1)可以保证c &lt; d<br />
	</span></span></p>
<p>
	<span style="font-family:arial,helvetica,sans-serif;"><span style="font-size:14px;">其中，r是未知的，我们要求出来。<br />
	</span></span></p>
<p>
	<span style="font-family:arial,helvetica,sans-serif;"><span style="font-size:14px;">我们想让r值在每一个子区间内均保持不变，另外，在每一次搜索的过程中，其中一个旧的内点将被用作新的子区间的一个内点，而一个旧的内点则会成为新的子区间的一个端点。这样，每一次迭代过程中只需要找到一个新点，并且只需要计算一次新函数值。如果f(c) &lt;= f(d)且只需计算一次新函数值的话，那么我们就有：<br />
	</span></span></p>
<p>
	<img loading="lazy" decoding="async" alt="" height="78" src="http://www.codelast.com/wp-content/uploads/2011/02/GRS_1.png" width="199" /></p>
<p>
	<span style="font-family:arial,helvetica,sans-serif;"><span style="font-size:14px;">也可以写成：<br />
	</span></span></p>
<p>
	<img loading="lazy" decoding="async" alt="" height="86" src="http://www.codelast.com/wp-content/uploads/2011/02/GRS_2.png" width="279" /></p>
<p>
	<span style="color: rgb(255, 255, 255);">文章来源：</span><a href="http://www.codelast.com/" rel="noopener noreferrer" target="_blank"><span style="color: rgb(255, 255, 255);">http://www.codelast.com/</span></a></p>
<p>
	<span style="font-family:arial,helvetica,sans-serif;"><span style="font-size:14px;">将（3）、（4）式代入此式，得：<br />
	</span></span></p>
<p>
	<img loading="lazy" decoding="async" alt="" height="232" src="http://www.codelast.com/wp-content/uploads/2011/02/GRS_3.png" width="332" /></p>
<p>
	<span style="font-family:arial,helvetica,sans-serif;"><span style="font-size:14px;">由于r&isin;(0.5, 1)，故：<br />
	</span></span></p>
<p>
	<img decoding="async" alt="" src="http://www.codelast.com/wp-content/uploads/2011/02/GRS_4.png" /></p>
<p>
	<span style="font-family:arial,helvetica,sans-serif;"><span style="font-size:14px;">此r值即所谓的黄金比例。平常我们老是说&ldquo;黄金分割点&rdquo;，就是这个0.618了。<br />
	</span></span></p>
<p>
	<span style="font-family:arial,helvetica,sans-serif;"><span style="font-size:14px;">同理，当</span></span> <span class='MathJax_Preview'><img src='https://www.codelast.com/wp-content/plugins/latex/cache/tex_61c06d01dcf37df477ac939e906f64e3.gif' style='vertical-align: middle; border: none; padding-bottom:2px;' class='tex' alt="f(d) < f(c)" /></span><script type='math/tex'>f(d) < f(c)</script> <span style="font-size: 14px; font-family: arial, helvetica, sans-serif;">时，也可求得同样的 <span class='MathJax_Preview'><img src='https://www.codelast.com/wp-content/plugins/latex/cache/tex_4b43b0aee35624cd95b910189b3dc231.gif' style='vertical-align: middle; border: none; padding-bottom:2px;' class='tex' alt="r" /></span><script type='math/tex'>r</script> 值。</span></p>
<p>
	<span style="color: rgb(255, 255, 255);">文章来源：</span><a href="http://www.codelast.com/" rel="noopener noreferrer" target="_blank"><span style="color: rgb(255, 255, 255);">http://www.codelast.com/</span></a><br />
	下面我用一幅图，从另一个角度来说明黄金比例搜索算法的寻优过程。</p>
<p style="text-align: center;">
	<img decoding="async" alt="" src="http://www.codelast.com/wp-content/uploads/ckfinder/images/optimization_golden_section_search_1.png" style="width: 300px; height: 299px;" /></p>
<p>
	上图来自<a href="http://en.wikipedia.org/wiki/Golden_section_search" rel="noopener noreferrer" target="_blank"><span style="background-color:#ffa07a;">Wiki</span></a>。<br />
	 <span class='MathJax_Preview'><img src='https://www.codelast.com/wp-content/plugins/latex/cache/tex_d6f3d1d9909196efa449a9ac9ee99b3e.gif' style='vertical-align: middle; border: none; padding-bottom:2px;' class='tex' alt="{x_1},{x_2},{x_3}" /></span><script type='math/tex'>{x_1},{x_2},{x_3}</script> 是已知的三个点（函数值&ldquo;高&rarr;低&rarr;高&rdquo;），它们划界了一个单峰区间，函数值分别为 <span class='MathJax_Preview'><img src='https://www.codelast.com/wp-content/plugins/latex/cache/tex_373fd033d8799189f51d1faac9d1dabc.gif' style='vertical-align: middle; border: none; padding-bottom:2px;' class='tex' alt="{f_1},{f_2},{f_3}" /></span><script type='math/tex'>{f_1},{f_2},{f_3}</script> 。现在的问题是：如何通过一个新点 <span class='MathJax_Preview'><img src='https://www.codelast.com/wp-content/plugins/latex/cache/tex_d8bda56b49dbee9553f35ce3c29db728.gif' style='vertical-align: middle; border: none; padding-bottom:2px;' class='tex' alt="{x_4}" /></span><script type='math/tex'>{x_4}</script> ，不断缩小该区间的范围，从而逼近极小值点？</p>
<p>	首先，在最大的区间 <span class='MathJax_Preview'><img src='https://www.codelast.com/wp-content/plugins/latex/cache/tex_19802e1d646cec5ed78bbe9b8686cb80.gif' style='vertical-align: middle; border: none; padding-bottom:2px;' class='tex' alt="({x_2},{x_3})" /></span><script type='math/tex'>({x_2},{x_3})</script> 内安插 <span class='MathJax_Preview'><img src='https://www.codelast.com/wp-content/plugins/latex/cache/tex_d8bda56b49dbee9553f35ce3c29db728.gif' style='vertical-align: middle; border: none; padding-bottom:2px;' class='tex' alt="{x_4}" /></span><script type='math/tex'>{x_4}</script> 是最高效的，因为我们更倾向于相信极小值更有可能出现在大的区间内。<br />
	当 <span class='MathJax_Preview'><img src='https://www.codelast.com/wp-content/plugins/latex/cache/tex_d8bda56b49dbee9553f35ce3c29db728.gif' style='vertical-align: middle; border: none; padding-bottom:2px;' class='tex' alt="{x_4}" /></span><script type='math/tex'>{x_4}</script> 的函数值为图中 <span class='MathJax_Preview'><img src='https://www.codelast.com/wp-content/plugins/latex/cache/tex_d2beabb4e8306ffba2b607c40660f5dc.gif' style='vertical-align: middle; border: none; padding-bottom:2px;' class='tex' alt="{f_{4a}}" /></span><script type='math/tex'>{f_{4a}}</script> 所示时（即 <span class='MathJax_Preview'><img src='https://www.codelast.com/wp-content/plugins/latex/cache/tex_cab4a9eede37a87b9277099906317379.gif' style='vertical-align: middle; border: none; padding-bottom:2px;' class='tex' alt="{f_{4a}} > {f_2}" /></span><script type='math/tex'>{f_{4a}} > {f_2}</script> ），此时，区间缩小为 <span class='MathJax_Preview'><img src='https://www.codelast.com/wp-content/plugins/latex/cache/tex_280b4d7591ef8e918cea58d93d758bf8.gif' style='vertical-align: middle; border: none; padding-bottom:2px;' class='tex' alt="{x_1},{x_2},{x_4}" /></span><script type='math/tex'>{x_1},{x_2},{x_4}</script> （函数值&ldquo;高&rarr;低&rarr;高&rdquo;的3个点）；当 <span class='MathJax_Preview'><img src='https://www.codelast.com/wp-content/plugins/latex/cache/tex_d8bda56b49dbee9553f35ce3c29db728.gif' style='vertical-align: middle; border: none; padding-bottom:2px;' class='tex' alt="{x_4}" /></span><script type='math/tex'>{x_4}</script> 的函数值为图中 <span class='MathJax_Preview'><img src='https://www.codelast.com/wp-content/plugins/latex/cache/tex_067d7af0c63a766d999bcbacced54110.gif' style='vertical-align: middle; border: none; padding-bottom:2px;' class='tex' alt="{f_{4b}}" /></span><script type='math/tex'>{f_{4b}}</script> 所示时（即 <span class='MathJax_Preview'><img src='https://www.codelast.com/wp-content/plugins/latex/cache/tex_0660c49e54c2a0582bd18775bfa52d0f.gif' style='vertical-align: middle; border: none; padding-bottom:2px;' class='tex' alt="{f_{4b}} < {f_2}" /></span><script type='math/tex'>{f_{4b}} < {f_2}</script> ），此时，区间缩小为 <span class='MathJax_Preview'><img src='https://www.codelast.com/wp-content/plugins/latex/cache/tex_0bdd2b24cd470f2fe6bb725f3eaa9abd.gif' style='vertical-align: middle; border: none; padding-bottom:2px;' class='tex' alt="{x_2},{x_4},{x_3}" /></span><script type='math/tex'>{x_2},{x_4},{x_3}</script> （函数值&ldquo;高&rarr;低&rarr;高&rdquo;的3个点），每次迭代均按此规则进行选取。<br />
	<span style="color: rgb(255, 255, 255);">文章来源：</span><a href="http://www.codelast.com/" rel="noopener noreferrer" target="_blank"><span style="color: rgb(255, 255, 255);">http://www.codelast.com/</span></a><br />
	其次， <span class='MathJax_Preview'><img src='https://www.codelast.com/wp-content/plugins/latex/cache/tex_d8bda56b49dbee9553f35ce3c29db728.gif' style='vertical-align: middle; border: none; padding-bottom:2px;' class='tex' alt="{x_4}" /></span><script type='math/tex'>{x_4}</script> 应该放在什么位置上呢？随意放置的话，若运气不好，有可能会导致收敛很慢。而事实证明，黄金比例是极好的，即 <span class='MathJax_Preview'><img src='https://www.codelast.com/wp-content/plugins/latex/cache/tex_33fde508245fdb4af9d308ed137ad120.gif' style='vertical-align: middle; border: none; padding-bottom:2px;' class='tex' alt="\frac{c}{b} = 1 - 0.618" /></span><script type='math/tex'>\frac{c}{b} = 1 - 0.618</script> 。<br />
	黄金比例搜索算法是<span style="color:#0000ff;">线性收敛</span>的，那么其收敛准则是什么呢？也就是说，我们逐步逼近了极小值所在的区间，到什么程度的时候，我们就可以&ldquo;收手&rdquo;，不用再搜索下去了呢？各种参考资料上给出了不同的收敛准则，例如：<br />
	 <span class='MathJax_Preview'><img src='https://www.codelast.com/wp-content/plugins/latex/cache/tex_8a6e428e8628fa3a5eeb614653df1b50.gif' style='vertical-align: middle; border: none; padding-bottom:2px;' class='tex' alt="|{x_3} - {x_1}| < \tau \cdot |{x_2}| + |{x_4}|" /></span><script type='math/tex'>|{x_3} - {x_1}| < \tau \cdot |{x_2}| + |{x_4}|</script> <br />
	或：<br />
	 <span class='MathJax_Preview'><img src='https://www.codelast.com/wp-content/plugins/latex/cache/tex_1a024ab202389e1781db25404c0f7f55.gif' style='vertical-align: middle; border: none; padding-bottom:2px;' class='tex' alt="|{x_3} - {x_1}| < \tau \cdot INIT" /></span><script type='math/tex'>|{x_3} - {x_1}| < \tau \cdot INIT</script> （ <span class='MathJax_Preview'><img src='https://www.codelast.com/wp-content/plugins/latex/cache/tex_faee4ca3c30ee18148ce3ada37466498.gif' style='vertical-align: middle; border: none; padding-bottom:2px;' class='tex' alt="INIT" /></span><script type='math/tex'>INIT</script> 为初始区间长度）<br />
	<span style="color: rgb(255, 255, 255);">文章来源：</span><a href="http://www.codelast.com/" rel="noopener noreferrer" target="_blank"><span style="color: rgb(255, 255, 255);">http://www.codelast.com/</span></a><br />
	需要一提的是，在给定一个精度 <span class='MathJax_Preview'><img src='https://www.codelast.com/wp-content/plugins/latex/cache/tex_f10f03c9836c36537d2539196058bfa2.gif' style='vertical-align: middle; border: none; padding-bottom:2px;' class='tex' alt="\delta " /></span><script type='math/tex'>\delta </script> 的情况下，我们可以计算出试验的次数（即需要多少次能找到极小值点）为：<br />
	 <span class='MathJax_Preview'><img src='https://www.codelast.com/wp-content/plugins/latex/cache/tex_dbf573787d88a8cba7fdb626dba0aa46.gif' style='vertical-align: middle; border: none; padding-bottom:2px;' class='tex' alt="n \ge \frac{{\lg \delta }}{{\lg 0.618}} + 1" /></span><script type='math/tex'>n \ge \frac{{\lg \delta }}{{\lg 0.618}} + 1</script> 取整数。<br />
	例如：求函数 <span class='MathJax_Preview'><img src='https://www.codelast.com/wp-content/plugins/latex/cache/tex_13d5760fbbf672af396631aeff1d167f.gif' style='vertical-align: middle; border: none; padding-bottom:2px;' class='tex' alt="f(x) = x2 - x + 2" /></span><script type='math/tex'>f(x) = x2 - x + 2</script> 在 <span class='MathJax_Preview'><img src='https://www.codelast.com/wp-content/plugins/latex/cache/tex_dd32f8d3a5e254299238e7a819dc22e8.gif' style='vertical-align: middle; border: none; padding-bottom:2px;' class='tex' alt="[ - 1,3]" /></span><script type='math/tex'>[ - 1,3]</script> 上的极小值点，精度要求 <span class='MathJax_Preview'><img src='https://www.codelast.com/wp-content/plugins/latex/cache/tex_4bfe4365de16efa733dacf7b16f8f2e1.gif' style='vertical-align: middle; border: none; padding-bottom:2px;' class='tex' alt="\delta = 0.08" /></span><script type='math/tex'>\delta = 0.08</script> （即搜索区间缩小为初始区间长的8%时停止搜索，就认为找到了极小值）。<br />
	则：估计试验次数 <span class='MathJax_Preview'><img src='https://www.codelast.com/wp-content/plugins/latex/cache/tex_a8cd188224d9b5ff43789b44d38ef61c.gif' style='vertical-align: middle; border: none; padding-bottom:2px;' class='tex' alt="n \ge \frac{{\lg 0.08}}{{\lg 0.618}} + 1 = 6.24" /></span><script type='math/tex'>n \ge \frac{{\lg 0.08}}{{\lg 0.618}} + 1 = 6.24</script> ，实际实验次数 <span class='MathJax_Preview'><img src='https://www.codelast.com/wp-content/plugins/latex/cache/tex_6f4a95286e8d860eb44fae507c4ccb26.gif' style='vertical-align: middle; border: none; padding-bottom:2px;' class='tex' alt="n = 7" /></span><script type='math/tex'>n = 7</script> （按第二个收敛准则）。<br />
	<span style="color: rgb(255, 255, 255);">文章来源：</span><a href="http://www.codelast.com/" rel="noopener noreferrer" target="_blank"><span style="color: rgb(255, 255, 255);">http://www.codelast.com/</span></a><br />
	最后来看一下简单的黄金比例搜索算法代码（我根据<a href="http://en.wikipedia.org/wiki/Golden_section_search" rel="noopener noreferrer" target="_blank"><span style="background-color:#ffa07a;">Wiki</span></a>中的代码修改的，更易于理解）：</p>
<pre style="margin-top: 0px; margin-bottom: 0px; font-stretch: normal; font-size: 0.9333em; line-height: 1.5em; font-family: Consolas, &quot;Lucida Console&quot;, &quot;DejaVu Sans Mono&quot;, Monaco, &quot;Courier New&quot;, monospace; background: rgb(0, 34, 64); color: rgb(255, 255, 255);">
  <span style="color: rgb(255, 238, 128);">public</span> <span style="color: rgb(255, 238, 128);">static</span> <span style="color: rgb(255, 238, 128);">double</span> <span style="color: rgb(255, 98, 140);">PHI</span> <span style="color: rgb(255, 157, 0);">=</span> (<span style="color: rgb(255, 98, 140);">1</span> <span style="color: rgb(255, 157, 0);">+</span> <span style="color: rgb(255, 238, 128);">Math</span><span style="color: rgb(255, 157, 0);">.</span>sqrt<span style="color: rgb(225, 239, 255);">(</span><span style="color: rgb(255, 98, 140);">5</span><span style="color: rgb(225, 239, 255);">)</span>) <span style="color: rgb(255, 157, 0);">/</span> <span style="color: rgb(255, 98, 140);">2</span><span style="color: rgb(225, 239, 255);">;</span>    <span style="color: rgb(0, 136, 255); font-style: italic;"><span style="color: rgb(225, 239, 255);">//</span> 0.618...</span>
  <span style="color: rgb(255, 238, 128);">public</span> <span style="color: rgb(255, 238, 128);">static</span> <span style="color: rgb(255, 238, 128);">double</span> <span style="color: rgb(255, 98, 140);">RESPHI</span> <span style="color: rgb(255, 157, 0);">=</span> <span style="color: rgb(255, 98, 140);">2</span> <span style="color: rgb(255, 157, 0);">-</span> <span style="color: rgb(255, 98, 140);">PHI</span><span style="color: rgb(225, 239, 255);">;</span>  <span style="color: rgb(0, 136, 255); font-style: italic;"><span style="color: rgb(225, 239, 255);">//</span> 0.382...</span>

  <span style="color: rgb(0, 136, 255); font-style: italic;"><span style="color: rgb(225, 239, 255);">/**</span>
   * Golden section search.
   *
   * <span style="color: rgb(255, 157, 0);"><span style="color: rgb(225, 239, 255);">@</span>author</span> Darran Zhang @ codelast.com
   * <span style="color: rgb(255, 157, 0);"><span style="color: rgb(225, 239, 255);">@</span>param</span> x1  The left bound of current bounds.
   * <span style="color: rgb(255, 157, 0);"><span style="color: rgb(225, 239, 255);">@</span>param</span> x2  An interior point between (x1, x3).
   * <span style="color: rgb(255, 157, 0);"><span style="color: rgb(225, 239, 255);">@</span>param</span> x3  The right bound of current bounds.
   * <span style="color: rgb(255, 157, 0);"><span style="color: rgb(225, 239, 255);">@</span>param</span> tau The error tolerance to judge the convergence, recommended value is e^0.5, where e is is the required absolute precision of f(x).
   <span style="color: rgb(225, 239, 255);">*/</span></span>
  <span style="color: rgb(255, 238, 128);">public</span> <span style="color: rgb(255, 238, 128);">double</span> goldenSectionSearch<span style="color: rgb(225, 239, 255);">(</span><span style="color: rgb(255, 238, 128);">double</span> x1<span style="color: rgb(225, 239, 255);">,</span> <span style="color: rgb(255, 238, 128);">double</span> x2<span style="color: rgb(225, 239, 255);">,</span> <span style="color: rgb(255, 238, 128);">double</span> x3<span style="color: rgb(225, 239, 255);">,</span> <span style="color: rgb(255, 238, 128);">double</span> tau<span style="color: rgb(225, 239, 255);">)</span> {
    <span style="color: rgb(255, 238, 128);">double</span> x4<span style="color: rgb(225, 239, 255);">;</span>
    <span style="color: rgb(255, 157, 0);">if</span> (x3 <span style="color: rgb(255, 157, 0);">-</span> x2 <span style="color: rgb(255, 157, 0);">&gt;</span> x2 <span style="color: rgb(255, 157, 0);">-</span> x1) {    <span style="color: rgb(0, 136, 255); font-style: italic;"><span style="color: rgb(225, 239, 255);">//</span> b &gt; a，右半区间长度较大</span>
      x4 <span style="color: rgb(255, 157, 0);">=</span> x2 <span style="color: rgb(255, 157, 0);">+</span> <span style="color: rgb(255, 98, 140);">RESPHI</span> <span style="color: rgb(255, 157, 0);">*</span> (x3 <span style="color: rgb(255, 157, 0);">-</span> x2)<span style="color: rgb(225, 239, 255);">;</span>   <span style="color: rgb(0, 136, 255); font-style: italic;"><span style="color: rgb(225, 239, 255);">//</span> x4安插在右半区间</span>
    } <span style="color: rgb(255, 157, 0);">else</span> {    <span style="color: rgb(0, 136, 255); font-style: italic;"><span style="color: rgb(225, 239, 255);">//</span> b &lt;= a，左半区间长度较大</span>
      x4 <span style="color: rgb(255, 157, 0);">=</span> x2 <span style="color: rgb(255, 157, 0);">-</span> <span style="color: rgb(255, 98, 140);">RESPHI</span> <span style="color: rgb(255, 157, 0);">*</span> (x2 <span style="color: rgb(255, 157, 0);">-</span> x1)<span style="color: rgb(225, 239, 255);">;</span>   <span style="color: rgb(0, 136, 255); font-style: italic;"><span style="color: rgb(225, 239, 255);">//</span> x4安插在左半区间</span>
    }
    <span style="color: rgb(255, 157, 0);">if</span> (<span style="color: rgb(255, 238, 128);">Math</span><span style="color: rgb(255, 157, 0);">.</span>abs<span style="color: rgb(225, 239, 255);">(</span>x3 <span style="color: rgb(255, 157, 0);">-</span> x1<span style="color: rgb(225, 239, 255);">)</span> <span style="color: rgb(255, 157, 0);">&lt;</span> tau <span style="color: rgb(255, 157, 0);">*</span> (<span style="color: rgb(255, 238, 128);">Math</span><span style="color: rgb(255, 157, 0);">.</span>abs<span style="color: rgb(225, 239, 255);">(</span>x2<span style="color: rgb(225, 239, 255);">)</span> <span style="color: rgb(255, 157, 0);">+</span> <span style="color: rgb(255, 238, 128);">Math</span><span style="color: rgb(255, 157, 0);">.</span>abs<span style="color: rgb(225, 239, 255);">(</span>x4<span style="color: rgb(225, 239, 255);">)</span>)) {    <span style="color: rgb(0, 136, 255); font-style: italic;"><span style="color: rgb(225, 239, 255);">//</span> 判断是否达到收敛条件</span>
      <span style="color: rgb(255, 157, 0);">return</span> (x3 <span style="color: rgb(255, 157, 0);">+</span> x1) <span style="color: rgb(255, 157, 0);">/</span> <span style="color: rgb(255, 98, 140);">2</span><span style="color: rgb(225, 239, 255);">;</span>   <span style="color: rgb(0, 136, 255); font-style: italic;"><span style="color: rgb(225, 239, 255);">//</span> 达到收敛条件，取区间长度的一半作为极小值点输出</span>
    }

    <span style="color: rgb(255, 157, 0);">assert</span> (function<span style="color: rgb(255, 157, 0);">.</span>func<span style="color: rgb(225, 239, 255);">(</span>x4<span style="color: rgb(225, 239, 255);">)</span> <span style="color: rgb(255, 157, 0);">!=</span> function<span style="color: rgb(255, 157, 0);">.</span>func<span style="color: rgb(225, 239, 255);">(</span>x2<span style="color: rgb(225, 239, 255);">)</span>)<span style="color: rgb(225, 239, 255);">;</span>

    <span style="color: rgb(0, 136, 255); font-style: italic;"><span style="color: rgb(225, 239, 255);">/*</span> 未达到收敛条件，继续搜索 <span style="color: rgb(225, 239, 255);">*/</span></span>
    <span style="color: rgb(255, 157, 0);">if</span> (function<span style="color: rgb(255, 157, 0);">.</span>func<span style="color: rgb(225, 239, 255);">(</span>x4<span style="color: rgb(225, 239, 255);">)</span> <span style="color: rgb(255, 157, 0);">&lt;</span> function<span style="color: rgb(255, 157, 0);">.</span>func<span style="color: rgb(225, 239, 255);">(</span>x2<span style="color: rgb(225, 239, 255);">)</span>) {    <span style="color: rgb(0, 136, 255); font-style: italic;"><span style="color: rgb(225, 239, 255);">//</span> x4点的函数值如图中f4b所示时</span>
      <span style="color: rgb(255, 157, 0);">if</span> (x3 <span style="color: rgb(255, 157, 0);">-</span> x2 <span style="color: rgb(255, 157, 0);">&gt;</span> x2 <span style="color: rgb(255, 157, 0);">-</span> x1) {    <span style="color: rgb(0, 136, 255); font-style: italic;"><span style="color: rgb(225, 239, 255);">//</span> b &gt; a，右半区间长度较大</span>
        <span style="color: rgb(255, 157, 0);">return</span> goldenSectionSearch<span style="color: rgb(225, 239, 255);">(</span>x2<span style="color: rgb(225, 239, 255);">,</span> x4<span style="color: rgb(225, 239, 255);">,</span> x3<span style="color: rgb(225, 239, 255);">,</span> tau<span style="color: rgb(225, 239, 255);">)</span><span style="color: rgb(225, 239, 255);">;</span>  <span style="color: rgb(0, 136, 255); font-style: italic;"><span style="color: rgb(225, 239, 255);">//</span> 以x2，x4，x3作为新三点，继续搜索</span>
      } <span style="color: rgb(255, 157, 0);">else</span> {    <span style="color: rgb(0, 136, 255); font-style: italic;"><span style="color: rgb(225, 239, 255);">//</span> b &lt;= a，左半区间长度较大</span>
        <span style="color: rgb(255, 157, 0);">return</span> goldenSectionSearch<span style="color: rgb(225, 239, 255);">(</span>x1<span style="color: rgb(225, 239, 255);">,</span> x4<span style="color: rgb(225, 239, 255);">,</span> x2<span style="color: rgb(225, 239, 255);">,</span> tau<span style="color: rgb(225, 239, 255);">)</span><span style="color: rgb(225, 239, 255);">;</span>  <span style="color: rgb(0, 136, 255); font-style: italic;"><span style="color: rgb(225, 239, 255);">//</span> 以x1，x4，x2作为新三点，继续搜索</span>
      }
    } <span style="color: rgb(255, 157, 0);">else</span> {    <span style="color: rgb(0, 136, 255); font-style: italic;"><span style="color: rgb(225, 239, 255);">//</span> x4点的函数值如图中f4a所示时</span>
      <span style="color: rgb(255, 157, 0);">if</span> (x3 <span style="color: rgb(255, 157, 0);">-</span> x2 <span style="color: rgb(255, 157, 0);">&gt;</span> x2 <span style="color: rgb(255, 157, 0);">-</span> x1) {    <span style="color: rgb(0, 136, 255); font-style: italic;"><span style="color: rgb(225, 239, 255);">//</span> b &gt; a，右半区间长度较大</span>
        <span style="color: rgb(255, 157, 0);">return</span> goldenSectionSearch<span style="color: rgb(225, 239, 255);">(</span>x1<span style="color: rgb(225, 239, 255);">,</span> x2<span style="color: rgb(225, 239, 255);">,</span> x4<span style="color: rgb(225, 239, 255);">,</span> tau<span style="color: rgb(225, 239, 255);">)</span><span style="color: rgb(225, 239, 255);">;</span>  <span style="color: rgb(0, 136, 255); font-style: italic;"><span style="color: rgb(225, 239, 255);">//</span> 以x1，x2，x4作为新三点，继续搜索</span>
      } <span style="color: rgb(255, 157, 0);">else</span> {  <span style="color: rgb(0, 136, 255); font-style: italic;"><span style="color: rgb(225, 239, 255);">//</span> b &lt;= a，左半区间长度较大</span>
        <span style="color: rgb(255, 157, 0);">return</span> goldenSectionSearch<span style="color: rgb(225, 239, 255);">(</span>x4<span style="color: rgb(225, 239, 255);">,</span> x2<span style="color: rgb(225, 239, 255);">,</span> x3<span style="color: rgb(225, 239, 255);">,</span> tau<span style="color: rgb(225, 239, 255);">)</span><span style="color: rgb(225, 239, 255);">;</span>  <span style="color: rgb(0, 136, 255); font-style: italic;"><span style="color: rgb(225, 239, 255);">//</span> 以x4，x2，x3作为新三点，继续搜索</span>
      }
    }
  }</pre>
<p>
	这段使用递归方式（并不好）实现的代码要配合上面的图来看。<br />
	<span style="color: rgb(255, 255, 255);">文章来源：</span><a href="https://www.codelast.com/" rel="noopener noreferrer" target="_blank"><span style="color: rgb(255, 255, 255);">https://www.codelast.com/</span></a><br />
	<span style="color: rgb(255, 0, 0);">➤➤</span>&nbsp;版权声明&nbsp;<span style="color: rgb(255, 0, 0);">➤➤</span>&nbsp;<br />
	转载需注明出处：<u><a href="https://www.codelast.com/" rel="noopener noreferrer" target="_blank"><em><span style="color: rgb(0, 0, 255);"><strong style="font-size: 16px;"><span style="font-family: arial, helvetica, sans-serif;">codelast.com</span></strong></span></em></a></u>&nbsp;<br />
	感谢关注我的微信公众号（微信扫一扫）：</p>
<p style="border: 0px; font-size: 13px; margin: 0px 0px 9px; outline: 0px; padding: 0px; color: rgb(77, 77, 77);">
	<img decoding="async" alt="wechat qrcode of codelast" src="https://www.codelast.com/codelast_wechat_qr_code.jpg" style="width: 200px; height: 200px;" /></p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.codelast.com/%e5%8e%9f%e5%88%9b-%e9%bb%84%e9%87%91%e6%af%94%e4%be%8b%e6%90%9c%e7%b4%a2%e7%ae%97%e6%b3%95%ef%bc%88golden-ratio-search-algorithm%ef%bc%89%e7%9a%84%e5%ae%9e%e7%8e%b0/feed/</wfw:commentRss>
			<slash:comments>4</slash:comments>
		
		
			</item>
	</channel>
</rss>
