Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >【进化计算】遗传算法求解gr48数据集

【进化计算】遗传算法求解gr48数据集

作者头像
zstar
发布于 2023-10-25 07:13:15
发布于 2023-10-25 07:13:15
25500
代码可运行
举报
文章被收录于专栏:往期博文往期博文
运行总次数:0
代码可运行

本文是研究生课程《进化计算》的作业题,和我之前的博文遗传算法求解TSP问题基本类似,在数据加载部分略有区别,这里留作备份。

数据集简介

数据集选用TspLIB中的gr48。 注:数据集中包含每一组的最优解和最优解城市编码。

目前最优距离解:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
rand50 : 5553
rand75 : 7054
rand100 : 7891
rand200 : 10649
rand300 : 11865
rand400 : 14722
rand400b : 144595
a280 : 2579 
ali535 : 202339 
att48 : 33522 
att532 : 86729 
bayg29 : 1610 
bays29 : 2020 
berlin52 : 7542 
bier127 : 118282 
brazil58 : 25395 
brd14051 : 469385 
brg180 : 1950 
burma14 : 3323
chn31 : 15377 
ch130 : 6110 
ch150 : 6528 
d198 : 15780 
d493 : 35002 
d657 : 48912 
d1291 : 50801 
d1655 : 62128 
d2103 : 80450 
d15112 : 1573084 
d18512 : 645238
dantzig42 : 699 
dsj1000 : 18659688
dsj1000 : 18660188
eil51 : 426 
eil76 : 538 
eil101 : 629 
fl417 : 11861 
fl1400 : 20127 
fl1577 : 22249 
fl3795 : 28772 
fnl4461 : 182566 
fri26 : 937 
gil262 : 2378 
gr17 : 2085 
gr21 : 2707 
gr24 : 1272 
gr48 : 5046 
gr96 : 55209 
gr120 : 6942 
gr137 : 69853 
gr202 : 40160 
gr229 : 134602 
gr431 : 171414 
gr666 : 294358 
hk48 : 11461 
kroA100 : 21282 
kroB100 : 22141 
kroC100 : 20749 
kroD100 : 21294 
kroE100 : 22068 
kroA150 : 26524 
kroB150 : 26130 
kroA200 : 29368 
kroB200 : 29437 
lin105 : 14379 
lin318 : 42029 
linhp318 : 41345 
nrw1379 : 56638 
oliver30 : 420
p654 : 34643 
pa561 : 2763 
pcb442 : 50778 
pcb1173 : 56892 
pcb3038 : 137694 
pla7397 : 23260728 
pla33810 : 66048945 
pla85900 : 142382641 
pr76 : 108159 
pr107 : 44303 
pr124 : 59030 
pr136 : 96772 
pr144 : 58537 
pr152 : 73682 
pr226 : 80369 
pr264 : 49135 
pr299 : 48191 
pr439 : 107217 
pr1002 : 259045 
pr2392 : 378032 
rat99 : 1211 
rat195 : 2323 
rat575 : 6773 
rat783 : 8806 
rd100 : 7910 
rd400 : 15281 
rl1304 : 252948 
rl1323 : 270199 
rl1889 : 316536 
rl5915 : 565530 
rl5934 : 556045 
rl11849 : 923288 
si175 : 21407 
si535 : 48450 
si1032 : 92650 
st70 : 675 
swiss42 : 1273 
ts225 : 126643 
tsp225 : 3916 
u159 : 42080 
u574 : 36905 
u724 : 41910 
u1060 : 224094 
u1432 : 152970 
u1817 : 57201 
u2152 : 64253 
u2319 : 234256 
ulysses16 : 72
ulysses22 : 74 
usa13509 : 19982859 
vm1084 : 239297 
vm1748 : 336556 

数据集读取

数据集为城市距离的下三角矩阵,0表示对角线上的数据。

读取思路是先根据换行符进行换行,然后根据0的位置对距离矩阵相应位置进行填充,读取代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
def load_data(cityNum, file_path):
    with open(file_path, 'r', encoding='utf-8') as f:
        context = f.read()
        # print(context)
        # 根据换行进行分隔
        row_list = context.splitlines()
        data_list = []
        for row in row_list:
            for i in row.strip().split(" "):
                data_list.append(int(i))
    distance = np.zeros([cityNum, cityNum])
    # 遍历data[],填入distance[][]
    p = 0
    for i in range(cityNum):
        for j in range(cityNum):
            distance[i][j] = data_list[p]
            distance[j][i] = data_list[p]
            p += 1
            # 每行读到"0"跳出列循环,到下一行
            if data_list[p - 1] == 0:
                break
    return distance

完整代码

完整代码如下所示,由于每次运行都容易陷入局部最优,因此,代码中我对每次运行的结果和数据集提供的最优解进行比较,若需要接近最优解,调整random.seed即可。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import time
import numpy as np
import matplotlib.pyplot as plt

plt.rcParams['font.sans-serif'] = ["SimHei"]

# 载入数据
def load_data(cityNum, file_path):
    with open(file_path, 'r', encoding='utf-8') as f:
        context = f.read()
        # print(context)
        # 根据换行进行分隔
        row_list = context.splitlines()
        data_list = []
        for row in row_list:
            for i in row.strip().split(" "):
                data_list.append(int(i))
    distance = np.zeros([cityNum, cityNum])
    # 遍历data[],填入distance[][]
    p = 0
    for i in range(cityNum):
        for j in range(cityNum):
            distance[i][j] = data_list[p]
            distance[j][i] = data_list[p]
            p += 1
            # 每行读到"0"跳出列循环,到下一行
            if data_list[p - 1] == 0:
                break
    return distance

# 初始化种群
def rand_pop(city_num, pop_num, pop, distance, matrix_distance):
    rand_ch = np.array(range(city_num))
    for i in range(pop_num):
        np.random.shuffle(rand_ch)
        pop[i, :] = rand_ch
        distance[i] = comp_dis(city_num, matrix_distance, rand_ch)  # 这里的适应度其实是距离

# 计算每个个体的总距离
def comp_dis(city_num, matrix_distance, one_path):
    res = 0
    for i in range(city_num - 1):
        res += matrix_distance[one_path[i], one_path[i + 1]]
    res += matrix_distance[one_path[-1], one_path[0]]  # 最后一个城市和第一个城市的距离,需单独处理
    return res

# 打印最优城市编码
def print_path(city_num, one_path):
    bm = [str(one_path[0] + 1)]
    for i in range(1, city_num):
        bm.append(str(one_path[i] + 1))
    print("最优解城市编码为:")
    print(bm)

# 轮盘赌的方式选择子代
def select_sub(pop_num, pop, distance):
    fit = 1. / distance  # 适应度函数
    p = fit / sum(fit)
    q = p.cumsum()  # 累积概率
    select_id = []
    for i in range(pop_num):
        r = np.random.rand()  # 产生一个[0,1)的随机数
        for j in range(pop_num):
            if r < q[0]:
                select_id.append(0)
                break
            elif q[j] < r <= q[j + 1]:
                select_id.append(j + 1)
                break
    next_gen = pop[select_id, :]
    return next_gen

# 交叉操作-每个个体对的某一位置进行交叉
def cross_sub(city_num, pop_num, next_gen, cross_prob, evbest_path):
    for i in range(0, pop_num):
        best_gen = evbest_path.copy()
        if cross_prob >= np.random.rand():
            next_gen[i, :], best_gen = intercross(city_num, next_gen[i, :], best_gen)

# 具体的交叉方式:部分映射交叉(Partial-Mapped Crossover)
def intercross(city_num, ind_a, ind_b):
    r1 = np.random.randint(city_num)
    r2 = np.random.randint(city_num)
    while r2 == r1:
        r2 = np.random.randint(city_num)
    left, right = min(r1, r2), max(r1, r2)
    ind_a1 = ind_a.copy()
    ind_b1 = ind_b.copy()
    for i in range(left, right + 1):
        ind_a2 = ind_a.copy()
        ind_b2 = ind_b.copy()
        ind_a[i] = ind_b1[i]
        ind_b[i] = ind_a1[i]
        # 每个个体包含的城市序号是唯一的,因此交叉时若两个不相同,就会产生冲突
        x = np.argwhere(ind_a == ind_a[i])
        y = np.argwhere(ind_b == ind_b[i])
        # 产生冲突,将不是交叉区间的数据换成换出去的原数值,保证城市序号唯一
        if len(x) == 2:
            ind_a[x[x != i]] = ind_a2[i]
        if len(y) == 2:
            ind_b[y[y != i]] = ind_b2[i]
    return ind_a, ind_b

# 变异方式:翻转变异
def mutation_sub(city_num, pop_num, next_gen, mut_prob):
    for i in range(pop_num):
        if mut_prob >= np.random.rand():
            r1 = np.random.randint(city_num)
            r2 = np.random.randint(city_num)
            while r2 == r1:
                r2 = np.random.randint(city_num)
            if r1 > r2:
                temp = r1
                r1 = r2
                r2 = temp
            next_gen[i, r1:r2] = next_gen[i, r1:r2][::-1]

# 局部搜索:随机找两个点位交换
def local_search(city_num, pop_num, next_gen):
    for i in range(pop_num):
        r1 = np.random.randint(city_num)
        r2 = np.random.randint(city_num)
        while r2 == r1:
            r2 = np.random.randint(city_num)
        if r1 > r2:
            temp = next_gen[i, r1]
            next_gen[i, r1] = next_gen[i, r2]
            next_gen[i, r2] = temp

def main(seed):
    np.random.seed(seed)
    # 加载距离矩阵
    city_num = 48
    file_path = 'dataset/gr48.txt'
    matrix_distance = load_data(city_num, file_path)

    pop_num = 1000  # 群体个数
    cross_prob = 0.99  # 交叉概率
    mut_prob = 0.99  # 变异概率
    iteration = 100000  # 迭代代数

    # 初始化初代种群和距离,个体为整数,距离为浮点数
    pop = np.array([0] * pop_num * city_num).reshape(pop_num, city_num)
    distance = np.zeros(pop_num)
    # 初始化种群
    rand_pop(city_num, pop_num, pop, distance, matrix_distance)
    evbest_path = pop[0]
    evbest_distance = float("inf")
    best_path_list = []
    best_distance_list = []

    answer = ['10', '12', '31', '5', '33', '8', '22', '21', '17', '27', '32', '9', '14', '6', '26', '36', '11', '16', '48', '13', '1', '29', '7', '28', '44', '41', '46', '18', '34', '23', '25', '3', '19', '4', '30', '38', '20', '35', '42', '39', '40', '2', '45', '43', '47', '37', '24', '15']

    # 循环迭代遗传过程
    for i in range(iteration):
        # 选择
        next_gen = select_sub(pop_num, pop, distance)
        # 交叉
        cross_sub(city_num, pop_num, next_gen, cross_prob, evbest_path)
        # 变异
        mutation_sub(city_num, pop_num, next_gen, mut_prob)
        # 局部搜索(在每个个体附近领域寻找局部最优解)
        local_search(city_num, pop_num, next_gen)

        # 计算每个个体适应度
        for j in range(pop_num):
            distance[j] = comp_dis(city_num, matrix_distance, next_gen[j, :])
        index = distance.argmin()  # index 记录最小总路程

        # 为了防止曲线波动,每次记录最优值,如迭代后出现退化,则将当前最好的个体回退替换为历史最佳
        if distance[index] <= evbest_distance:
            evbest_distance = distance[index]
            evbest_path = next_gen[index, :]
        else:
            distance[index] = evbest_distance
            next_gen[index, :] = evbest_path

        # 存储每一步的最优路径(个体)及距离
        best_path_list.append(evbest_path)
        best_distance_list.append(evbest_distance)

        if i % 1000 == 0:
            print(i, "最佳距离为:", evbest_distance)

    best_path = evbest_path
    best_distance = evbest_distance

    # 指定10为起始点
    start_point = 10
    split_index = int(np.argwhere(best_path == start_point - 1))
    best_path = np.hstack((best_path[split_index:], (best_path[:split_index])))

    # 迭代完成,打印出最佳路径
    print_path(city_num, best_path)
    output_path = [i+1 for i in best_path]
    answer_right = 0
    for i, j in enumerate(output_path):
        if j == int(answer[i]):
            answer_right += 1
    print("准确的个数为", answer_right)
    print("当前最佳距离为:", best_distance)


if __name__ == '__main__':
    seed = 68
    print("编程语言:Python")
    start_time = time.time()
    main(seed)
    print("算法运行时间:", time.time() - start_time, "秒")
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-10-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
基于遗传算法(GA)的TSP(Python实现)
基于遗传算法(GA)求解TSP问题是一种常见且有效的方法,它通过模拟进化过程中的选择、交叉和变异等操作,逐步优化解的质量,最终找到较优的旅行路径。在GA算法中,候选解被看作是个体的染色体,并通过适应度函数对每个个体进行评估。在TSP中,适应度函数通常是路径长度的计算,即评估候选解的旅行路径质量。
不去幼儿园
2024/12/03
2120
基于遗传算法(GA)的TSP(Python实现)
【人工智能那些事】2、遗传算法求解TSP问题
本篇博文是该视频的讲义和程序代码 视频地址:https://player.bilibili.com/player.html?aid=808642011 遗传算法求解TSP问题 完整代码 import
zstar
2022/06/14
4410
【人工智能那些事】2、遗传算法求解TSP问题
数学建模学习笔记(二十)TSP问题遗传算法求解
什么是TSP问题? TSP问题(Travelling Salesman Problem)又译为旅行推销员问题、货郎担问题,即假设有一个旅行商人要拜访n个城市,从某个城市出发,每个城市只能访问一次且最后回到出发城市,问该推销员应如何选择路线,才能使总的行程最短?
zstar
2022/06/14
7050
数学建模学习笔记(二十)TSP问题遗传算法求解
【优化算法】遗传算法(Genetic Algorithm) (附代码及注释)
遗传算法(Genetic Algorithm, GA)是模拟达尔文生物进化论的自然选择和遗传学机理的生物进化过程的计算模型,是一种通过模拟自然进化过程搜索最优解的方法。
短短的路走走停停
2019/05/14
27.7K2
【优化算法】遗传算法(Genetic Algorithm) (附代码及注释)
《毕业设计》基于遗传算法的旅游路程和资金需求最优规划方案
随着社会经济的蓬勃发展,民众对于旅游的热爱与追求持续升温,展现出不断增长的热情与渴望。本文提出了一种基于遗传算法的旅游路程和资金需求最优规划方案。该方法旨在解决旅游者在规划行程时面临的关键问题,即如何在满足旅游需求的同时,实现旅行路程最短和资金需求最低。通过引入遗传算法,本文能够将这一复杂问题转化为一个优化问题,并在给定的约束条件下寻找最优解。本文首先构建了旅游路程和资金需求的数学模型,该模型综合考虑了旅游者的出行距离、住宿费用、餐饮费用等多个因素。然后,利用遗传算法通过不断迭代和进化,能够找到满足旅游者需求的最优行程规划方案。
不去幼儿园
2024/12/03
1870
《毕业设计》基于遗传算法的旅游路程和资金需求最优规划方案
基于粒子群算法(PSO)的TSP(Python实现)
基于粒子群算法(Particle Swarm Optimization, PSO)的TSP(Traveling Salesman Problem,旅行商问题),求解方法源自对集体智慧的模拟,通过模拟鸟群在搜索食物时的协作行为,不断调整每个“粒子”的位置和速度,以寻找全局最优解。在TSP问题中,粒子代表可能的路径解,通过不断更新粒子的位置,寻找一条最短的路径来访问所有城市。
不去幼儿园
2024/12/03
3100
基于粒子群算法(PSO)的TSP(Python实现)
数学建模暑期集训27:粒子群+遗传算法求解多目标规划问题
在实际问题中大都具有多个目标且需要同时满足,即在同一问题模型中同时存在几个非线性目标,而这些目标函数需要同时进行优化处理,并且这些目标又往往是互相冲突的,称这类问题称为多目标规划问题。
zstar
2022/06/14
8310
数学建模暑期集训27:粒子群+遗传算法求解多目标规划问题
遗传算法实例解析_遗传算法例子
大家好,又见面了,我是你们的朋友全栈君。 遗传算法实例及MATLAB程序解析
全栈程序员站长
2022/09/30
1.2K0
遗传算法实例解析_遗传算法例子
如何用遗传算法进化出一只聪明的小鹦鹉
现在有一些样本数据,如下表所示。你是否能找到其中的规律,然后计算出新样本的output是多少?
Stanley Sun
2019/09/23
5190
如何用遗传算法进化出一只聪明的小鹦鹉
人脸数据增强
在计算机视觉相关任务中,数据增强(Data Augmentation)是一种常用的技术,用于扩展训练数据集的多样性。它包括对原始图像进行一系列随机或有规律的变换,以生成新的训练样本。数据增强的主要目的是增加模型的泛化能力、提高模型的鲁棒性,并减轻过拟合的风险。以下是进行数据增强的几个重要原因:
用户3578099
2023/09/20
5231
遗传算法实例:句子匹配 python实现
1)当你的算法总是不收敛,诶反正就是你怎么改参数它都不收敛的时候,可能是fitness函数写错了(幽怨脸),问问自己,numpy矩阵操作对了吗?打个输出看看真的符合预期吗?
kalifa_lau
2019/04/01
1.3K0
遗传算法实例:句子匹配 python实现
遗传算法的应用实例python实现_python遗传算法库
遗传算法是用于解决最优化问题的一种搜索算法。从名字来看,遗传算法借用了生物学里达尔文的进化理论:”适者生存,不适者淘汰“,将该理论以算法的形式表现出来就是遗传算法的过程。
全栈程序员站长
2022/11/09
1.7K0
遗传算法的应用实例python实现_python遗传算法库
基于遗传算法的函数极值求取_遗传算法计算二元函数最大值
前面在《遗传算法通识》中介绍了基本原理,这里结合实例,看看遗传算法是怎样解决实际问题的。
全栈程序员站长
2022/09/30
9220
基于遗传算法的函数极值求取_遗传算法计算二元函数最大值
遗传算法求解最值问题并可视化
import numpy as np import matplotlib.pyplot as plt # 找到函数f(x)在区间self.x_bounder上的最大值 def f(x): return np.sin(x) + np.cos(x) class GeneticAlgorithm(object): """遗传算法. Parameters: ----------- cross_rate: float 交配的可能性大小. mut
用户3577892
2020/06/12
5880
遗传算法解决TSP问题MATLAB实现(详细)
给定一组n个城市和俩俩之间的直达距离,寻找一条闭合的旅程,使得每个城市刚好经过一次且总的旅行距离最短。
里克贝斯
2021/05/21
5.3K0
遗传算法解决TSP问题MATLAB实现(详细)
python常用函数技巧汇总
通过numpy的genfromtxt来读取txt文件 delimiter 分隔符 usecols 指定读取的列
zstar
2022/06/14
4570
python常用函数技巧汇总
遗传算法求解混合流水车间调度问题(HFSP)二:算法实现一
上图中,第1、2行是第1工序的2台设备,第3、4行是第2工序的2台设备,第5、6行是第3工序的两台设备,纵轴代表时间。按照最优序列[ 3 4 6 2 1 5]赋予每个零件优先级,一共用时25.
mwangblog
2018/12/25
2K0
遗传算法求解混合流水车间调度问题(HFSP)二:算法实现一
遗传算法python(含例程代码与详解)「建议收藏」
遗传算法简称GA(Genetic Algorithms)模拟自然界生物遗传学(孟德尔)和生物进化论(达尔文)通过人工方式所构造的一类 并行随机搜索最优化方法,是对生物进化过程**“优胜劣汰,适者生存”**这一过程进行的一种数学仿真。
全栈程序员站长
2022/09/30
3.4K0
遗传算法python(含例程代码与详解)「建议收藏」
SA solve TSP
本文采用模拟退火算法(SA)来解决TSP问题,如果你之前看过理解了遗传算法(GA)来解决TSP问题,再看到本篇SA算法,会发现模拟退火算法简单了好多,实现起来也很简单。
AngelNH
2020/05/08
8960
干货 | 遗传算法(Genetic Algorithm) Java 详细代码及注释
代码说明 遗传算法解决TSP旅行商问题 算法分为4个类: GeneticAlgorithm SpeciesIndividual SpeciesPopulation TSPData 数据规模: 10 cities, 20 cities and 31 cities. 类说明: GeneticAlgorithm: 遗传算法的主体部分,包括选择、交叉、变异 SpeciesIndividual: 物种个体类 SpeciesPopulation: 物种种群类 TSPData:
用户1621951
2018/06/11
6.7K0
推荐阅读
相关推荐
基于遗传算法(GA)的TSP(Python实现)
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验