集体智慧编程5-优化算法-爬山法、模拟退火、遗传算法

本文主要是介绍集体智慧编程5-优化算法-爬山法、模拟退火、遗传算法,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

最优化算法的思想在于,我们往往并不需要得到最优解,而是得到一个近似最优解,来节省时间的开销。

图例
* 随机算法
为了解决遍历引发的时间问题,有时候在没有严格要求的情况下,可以通过随机去一定的点,比较这些取的点数,总能找到一个近似最优解的情况。

  • 爬山算法
    随机算法没有逻辑可寻,成本较低,但是效果较差。而爬山算法利用了数据的内在规律。就像爬山一样,为了,爬到上的最顶部,在到达一个点后,我们总是环顾四周,寻找比当前位置高的地方,然后继续往上爬。即比较当前位置的邻近值。

  • 模拟退火
    很显然,爬山算法有个缺陷,比如,如果我们的当前位置是E,当取A,D两个值作比较时,会排除D点,这样结果将陷入到局部最大值A。为了避免在最开始就陷入局部最大值,所以,我们引入了一个概率PP = exp[-(newcost - oldcost)/ T ],即在温度很高时或者之后的值与第一个值相差不大时,会更可能不排除在外。越往后,随着温度的降低,将越来越接近爬山算法。这样在最初就不会排除D,从而可以顺利找到B

  • 遗传算法
    遗传算法类似于人类进化论,即物种总是朝着最优秀的方向进化,进化的方式有重组和变异,重组及优秀个体交换信息,变异即优秀个体内部改变元素。选择即我们通过成本函数进行排序,选择更好的值。

""" 
@author: zoutai
@file: optimization.py 
@time: 2018/04/22 
@description: 
"""import random
import timeimport mathpeople = [('Seymour', 'BOS'),('Franny', 'DAL'),('Zooey', 'CAK'),('Walt', 'MIA'),('Buddy', 'ORD'),('Les', 'OMA')]# newyork的Laguardia机场
destination = 'LGA'# 第一步,以出发地-目的地为key,以具体的航班信息为value,做字典映射
flights = {}
for line in open('schedule.txt'):origin, dest, departTime, arriveTime, price = line.strip().split(',')flights.setdefault((origin, dest), [])# 多趟航班,使用appendflights[(origin, dest)].append((departTime, arriveTime, int(price)))# 返回时间的分钟表示
def getminutes(t):x = time.strptime(t, '%H:%M')return x[3] * 60 + x[4]def printschedule(r):for d in range(len(r) // 2):name = people[d][0]origin = people[d][1]go = flights[(origin, dest)][r[d * 2]]back = flights[(dest, origin)][r[d * 2 + 1]]print('%10s%10s,%5s-%5s,%3s,%5s-%5s,%3s'% (name, origin, go[0], go[1], go[2], back[0], back[1], back[2]))s = [1, 4, 3, 2, 7, 3, 6, 3, 2, 4, 5, 3]
printschedule(s)# 成本函数=等待时间+机票+出租车
def schedulecost(sol):totalcost = 0earliestDep = 24 * 60latestArrive = 0for d in range(len(sol) // 2):name = people[d][0]origin = people[d][1]go = flights[(origin, dest)][int(sol[d * 2])]back = flights[(dest, origin)][sol[int(d * 2 + 1)]]totalcost += go[2] + back[2]if latestArrive < getminutes(go[1]):latestArrive = getminutes(go[1])if earliestDep > getminutes(back[0]):earliestDep = getminutes(back[0])totalWait = 0for d in range(len(sol) // 2):go = flights[(origin, dest)][sol[d * 2]]back = flights[(origin, dest)][sol[d * 2 + 1]]totalWait += (latestArrive - getminutes(go[1]))totalWait += (getminutes(back[0]) - earliestDep)# 出租车50/天if latestArrive < earliestDep:totalcost += 50return totalcost + totalWaitprint("默认初始化值:",schedulecost(s))domain = [(0, 9)] * (len(people) * 2)# 1、随机法
def randomoptimize(domain, costf):best = 999999999# bestRs = NoneiterNum = 1000for i in range(iterNum):r = [random.randint(domain[i][0], domain[i][1]) for i in range(len(domain))]cost = costf(r)if cost < best:best = cost# bestRs = bestreturn r, bestr, best = randomoptimize(domain,schedulecost)
print("随机法:",best)# 2、爬山法
# 对于每一个未知数,搜索维度方向上的邻近节点,取最小值,直到最小值不变,退出
def hillClimb(domain,costf):# 创建随机解-初始化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 = costf(sol)best = currentfor j in range(len(neighbors)):cost = costf(neighbors[j])if best>cost:best=costsol = neighbors[j]# 整个邻接区都没有更好的,则终止循环if best==current:break;return sol,best
sol,best = hillClimb(domain,schedulecost)
print("爬山法:",best)# 3、模拟退火
# 原理相对于爬山法,为了避免陷入局部最小值,在初期的时候,对于不符合的结果,暂时不排除# T:初始温度,cool:冷却因子,step方向步长
def annealingoptimize(domain,costf,T=10000,cool=0.95,step=1):# 初始化随机值vec = [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)director = random.randint(-step,step)vecb = vec[:]vecb[i]+=director # 偏移# 防止出界if vecb[i]<domain[i][0]:vecb[i]=domain[i][0]elif vecb[i]>domain[i][1]:vecb[i]=domain[i][1]costCur = costf(vec)costB = costf(vecb)if (costB<costCur or random.random()<pow(math.e,-(costB-costCur)/T)):vec = vecb # 即便costB>costCur,也不用保留之前的vec,因为,温度下降后,会再返回到当前值# 降低温度T = T * coolreturn vec,costf(vec)sol,best = annealingoptimize(domain,schedulecost)
print("模拟退火算法:",best)# 4、遗传算法
def geneticoptimize(domain,costf,popsize=50,step=1,mutprob=0.2,elite=0.2,mixiter=100):# 变异def mutate(vec):i = random.randint(0,len(domain)-1)# 随机数什么用?if random.random()<0.5 and vec[i]>domain[i][0]:return vec[:i]+[vec[i]-step]+vec[i+1:]elif vec[i]<domain[i][1]:return vec[:i]+[vec[i]+step]+vec[i+1:]# 重组def crossover(vec1,vec2):i = random.randint(1,len(domain)-2)return vec1[:i]+vec2[i:]# 初始化种群pop = []for i in range(popsize):vec = [random.randint(domain[j][0],domain[j][1]) for j in range(len(domain))]pop.append(vec)toplite = int(popsize * elite)for i in range(mixiter):# 排序,进行物种进化选择scores = [(costf(v),v) for v in pop]scores.sort()ranked = [v for (s,v) in scores]pop = ranked[:toplite]while len(pop)<popsize:if random.random()<mutprob:c = random.randint(0,toplite)pop.append(mutate(ranked[c]))else:c1 = random.randint(0,toplite)c2 = random.randint(0,toplite)pop.append(crossover(ranked[c1],ranked[c2]))print(scores[0][0])return scores[0][1],scores[0][0]sol, best = geneticoptimize(domain, schedulecost)
print("遗传算法:",best)

这篇关于集体智慧编程5-优化算法-爬山法、模拟退火、遗传算法的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/640153

相关文章

PyCharm接入DeepSeek实现AI编程的操作流程

《PyCharm接入DeepSeek实现AI编程的操作流程》DeepSeek是一家专注于人工智能技术研发的公司,致力于开发高性能、低成本的AI模型,接下来,我们把DeepSeek接入到PyCharm中... 目录引言效果演示创建API key在PyCharm中下载Continue插件配置Continue引言

Oracle查询优化之高效实现仅查询前10条记录的方法与实践

《Oracle查询优化之高效实现仅查询前10条记录的方法与实践》:本文主要介绍Oracle查询优化之高效实现仅查询前10条记录的相关资料,包括使用ROWNUM、ROW_NUMBER()函数、FET... 目录1. 使用 ROWNUM 查询2. 使用 ROW_NUMBER() 函数3. 使用 FETCH FI

C#使用HttpClient进行Post请求出现超时问题的解决及优化

《C#使用HttpClient进行Post请求出现超时问题的解决及优化》最近我的控制台程序发现有时候总是出现请求超时等问题,通常好几分钟最多只有3-4个请求,在使用apipost发现并发10个5分钟也... 目录优化结论单例HttpClient连接池耗尽和并发并发异步最终优化后优化结论我直接上优化结论吧,

Java内存泄漏问题的排查、优化与最佳实践

《Java内存泄漏问题的排查、优化与最佳实践》在Java开发中,内存泄漏是一个常见且令人头疼的问题,内存泄漏指的是程序在运行过程中,已经不再使用的对象没有被及时释放,从而导致内存占用不断增加,最终... 目录引言1. 什么是内存泄漏?常见的内存泄漏情况2. 如何排查 Java 中的内存泄漏?2.1 使用 J

Python中的随机森林算法与实战

《Python中的随机森林算法与实战》本文详细介绍了随机森林算法,包括其原理、实现步骤、分类和回归案例,并讨论了其优点和缺点,通过面向对象编程实现了一个简单的随机森林模型,并应用于鸢尾花分类和波士顿房... 目录1、随机森林算法概述2、随机森林的原理3、实现步骤4、分类案例:使用随机森林预测鸢尾花品种4.1

MySQL不使用子查询的原因及优化案例

《MySQL不使用子查询的原因及优化案例》对于mysql,不推荐使用子查询,效率太差,执行子查询时,MYSQL需要创建临时表,查询完毕后再删除这些临时表,所以,子查询的速度会受到一定的影响,本文给大家... 目录不推荐使用子查询和JOIN的原因解决方案优化案例案例1:查询所有有库存的商品信息案例2:使用EX

MySQL中my.ini文件的基础配置和优化配置方式

《MySQL中my.ini文件的基础配置和优化配置方式》文章讨论了数据库异步同步的优化思路,包括三个主要方面:幂等性、时序和延迟,作者还分享了MySQL配置文件的优化经验,并鼓励读者提供支持... 目录mysql my.ini文件的配置和优化配置优化思路MySQL配置文件优化总结MySQL my.ini文件

正则表达式高级应用与性能优化记录

《正则表达式高级应用与性能优化记录》本文介绍了正则表达式的高级应用和性能优化技巧,包括文本拆分、合并、XML/HTML解析、数据分析、以及性能优化方法,通过这些技巧,可以更高效地利用正则表达式进行复杂... 目录第6章:正则表达式的高级应用6.1 模式匹配与文本处理6.1.1 文本拆分6.1.2 文本合并6

C#反射编程之GetConstructor()方法解读

《C#反射编程之GetConstructor()方法解读》C#中Type类的GetConstructor()方法用于获取指定类型的构造函数,该方法有多个重载版本,可以根据不同的参数获取不同特性的构造函... 目录C# GetConstructor()方法有4个重载以GetConstructor(Type[]

Vue3 的 shallowRef 和 shallowReactive:优化性能

大家对 Vue3 的 ref 和 reactive 都很熟悉,那么对 shallowRef 和 shallowReactive 是否了解呢? 在编程和数据结构中,“shallow”(浅层)通常指对数据结构的最外层进行操作,而不递归地处理其内部或嵌套的数据。这种处理方式关注的是数据结构的第一层属性或元素,而忽略更深层次的嵌套内容。 1. 浅层与深层的对比 1.1 浅层(Shallow) 定义