您的位置:首页 > 运维架构

优化问题Optimization

2015-11-26 14:56 369 查看
优化技术特别擅长用于处理:受多种变量的影响,存在许多可能解的问题,以及结果因这些变量的组合而产生很大变化的问题。

优化算法的典型应用场景,存在大量可能的题解以至于我们无法对它们进行一一尝试的情况。

既然无法一一尝试,怎么做?

成本函数(The Cost Function)

量化解的优劣,要求是函数返回的值越大,表示该方案越差。

随机搜索(Random Searching)

很简单(tubie)的,随机选择解法计算代价成本,在这些随机选择结果中返回代价最小的解即可。

缺点:低效,可能搜索不到最优解

#######random searching#####
def randomoptimize(domain,constf):
best=999999999
bestr=None
for i in range(5):
r=[random.randint(domain[i][0],domain[i][1]) for i in range(len(domain))]
cost=constf(r)
if cost<best:
best=cost
bestr=r
return r


爬山法(Hill Climbing)

爬山法基于贪心思想,以一个随机解开始,在其临近的解集中寻找更好的题解(具有更低的成本),类似于从斜坡上向下走,寻找陡峭下降的路。

理解:得到的解也不一定是最优解,可能是局部的最优解,但和随机搜索相比高效得多。

python代码如下:

#####hillclimb################
def hillclimb(domain,constf):
sol=[random.randint(domain[i][0],domain[i][1]) for i in range(len(domain))]
while 1:
neighbors=[]
for j in range(len(domain)):
if sol[j]>domain[j][0]:
neighbors.append(sol[0:j]+[sol[j]-1]+sol[j+1:])
if sol[j]<domain[j][1]:
neighbors.append(sol[0:j]+[sol[j]+1]+sol[j+1:])
current=constf(sol)
best=current
for j in range(len(neighbors)):
cost=constf(neighbors[j])
if cost<best:
best=cost
sol=neighbors[j]
if best==current:
break
return sol


模拟退火算法(Simulated Annealing)

退火是将合金加热后再慢慢冷却的过程。大量的原子因为收到激发而向周围跳跃,然后又逐渐稳定到一个低能阶的状态。

(不得不感叹物理和数学让我们的生活变得多么美好(*  ̄3)(ε ̄ *))

在某些情况下,在我们能够得到一个更优的解之前转向一个更差的解是很有必要的。模拟退火算法之所以管用,不仅仅是因为它总是接受一个更优的解,而且还因为它在退火过程的开始会接受表现较差的解。随着退火过程的不断进行,算法越来越不可能接受较差的解,直到最后,它将只会接受更优的解,更高成本的题解,其被接受的概率为:

p=e−(highcost−lowcost)/Tp=e^{-(highcost-lowcost)/T}

这里的T:温度,指的是接受较差解的意愿。

一开始T非常之高,指数将总是接近于0,概率几乎等于1.随着温度的递减,高成本值和低成本值之间的差异越来越重要——差异之大,概率越低,因此该算法只倾向于稍差的解而不会是非常差的解。

#####simulated annealing############
def annealingoptimize(domain,constf,T=10000.0,cool=0.98,step=1):
vec=[int(random.randint(domain[i][0],domain[i][1])) for i in range(len(domain))]
while T>0.1:
i=random.randint(0,len(domain)-1)
dir=random.randint(-step,step)
vecb=vec[:]
vecb[i]+=dir
if vecb[i]<domain[i][0]:
vecb[i]=domain[i][0]
elif vecb[i]>domain[i][1]:
vecb[i]=domain[i][1]
ea=constf(vec)
eb=constf(vecb)
if (eb<ea or random.random()<pow(math.e,-(eb-ea)/T)):
vec=vecb
T=T*cool
return vec


由于模拟退火的结果很大程度上取决于其初始值,所以设置一个improvedsa函数,来用多个初始值模拟退火,并返回最优解:

python代码:

def improvedsa(domain,constf,times):
best=99999999
bestf=None
for i in range(times):
vec=annealingoptimize(domain,constf)
costs=constf(vec)
if costs<best:
best=costs
bestf=vec
return vec


遗传算法(Genetic Algorithms)

太懒了。。。先囤着

参考文献

《Programming Collective Intelligence》
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: