一、算法描述
随机尝试各种题解是非常低效的,因为这种方法没有充分利用已经发现的优解。在我们的例子中,拥有较低总成本的时间安排很可能接近于其他低成本安排。因为随机优化是到处跳跃的(jumps around),所以它不会自动去寻找与已经被发现的优解相接近的题解。随机搜索的一个替代方法叫做爬山法。爬山法以一个随机解开始,然后在其临近的解集中寻找更好的题解(具有更低的成本)。
爬山法是指经过评价当前的问题状态后,限于条件,不是去缩小,而是去增加这一状态与目标状态的差异,经过迂回前进,最终达到解决问题的总目标。就如同爬山一样,为了到达山顶,有时不得不先上矮山顶,然后再下来-------,这样翻越一个个的小山头,直到最终达到山顶。可以说,爬山法是一种"以退为进"的方法,往往具有"退一步进两步"的作用,后退乃是为了更有效地前进。爬山法也叫逐个修改法、瞎子摸象法或k-means法。
二、主要思想
一种简单的爬山算法的步骤描述:
(1)根据问题产生一组随机解current
(2)根据当前解,按照一定的规则递增或者改变current,并使得获得的结果更优,记为neighbor
(3)重复第(2)步,直到没有更好地结果
我们可以应用爬山法求解根号a的解。
可以利用f(x) = x^2 - a = 0 求解根号a的解。
三、爬山法(Climbing)的PHP实现
<?php
class Climbing
{
private $a;
public function __construct($_a)
{
$this->a = $_a;
}
//相当于估值函数
public function f($_x)
{
return pow($_x,2) - $this->a;
}
//爬山计算
public function calculate()
{
//初始化给一个随机解
$x0 = 0;
$i = 0;
while(pow($i,2)<$this->a)
{
$i++;
}
$x0 = $i-1;
//构造函数已经确定根号a的值在$i 和 $i+1 之间,以0.0001为步长规则爬山
$k = 0;
while($k < 100000)
{
//利用牛顿迭代公示更新x
$x1 = 0.5*($x0 + $this->a/$x0);
//判断是否满足条件
if($this->f($x1)-$this->f($x0) < 0.00001&&$this->f($x1)-$this->f($x0) > -0.00001)
break;
$x0 = $x1;
$k++;
}
echo $x1;
}
}
?>
调用如下:
$C = new Climbing(115);
$C->calculate();
结果如下:
10.723805294764
计算机计算结果:
10.723805294763608
附件 参考资料:
http://baike.baidu.com/view/2577461.htm?fr=aladdin
http://blog.youkuaiyun.com/ximenchuixuezijin/article/details/5624297
http://blog.sina.com.cn/s/blog_4eccffe401008zmm.html
http://book.51cto.com/art/200812/103498.htm