Python 遗传算法路径规划

article/2025/10/2 0:06:43

        了却一个心愿

文章目录

目录

文章目录

前言

二、主要内容

三、使用步骤

1.将压缩包下载解压

2.读入数据

3.最终结果


前言

        遗传算法(Genetic Algorithm,GA)最早是由美国的 John holland于20世纪70年代提出,该算法是根据大自然中生物体进化规律而设计提出的。是模拟达尔文生物进化论的自然选择和遗传学机理的生物进化过程的计算模型,是一种通过模拟自然进化过程搜索最优解的方法。相信对于路径规划来说,这种方法其实也是一种目前较好的寻找最优解的方法。


一、遗传算法原理

        原理都是一样的,有很多博客都写得很好,其理论的都是万变不离其宗。

二、主要内容

        虽然理论摆在那里,有人能够看懂,有人看不懂,我也是只能看懂一点点,这就使得理论运用到代码当中就变得相当困难了,所以对于路径规划这样的题目,我想自己编出一个合适的遗传算法几乎就不可能了,还好在github里面发现了一个关于遗传算法TSP问题的代码,代码简单易懂(注释多),我自己试着运行了一下,发现效果也还不错,运行时间短,结果也不会总变来变去(几乎就是正确答案)。

GItHub链接

大哥的视频讲解

三、使用步骤

1.将压缩包下载解压

会发现有如下三个代码文件:

config.py:各参数配置
ga.py:遗传算法实现
main.py:程序入口,数据预处理,效果展示

 ga.py:就用了Python的一两个基础库,强我只能说。

from config import ConfigParser
import randomcity_dist_mat = None
Cf = ConfigParser(city_nums=101, gen_nums=10000)
config = Cf.get_config()
# 各项参数
gene_len = config.city_num
individual_num = config.individual_num
gen_num = config.gen_num
mutate_prob = config.mutate_probdef copy_list(old_arr: [int]):new_arr = []for element in old_arr:new_arr.append(element)return new_arr# 个体类
class Individual:def __init__(self, genes=None):# 随机生成序列if genes is None:genes = [i for i in range(gene_len)]random.shuffle(genes)self.genes = genesself.fitness = self.evaluate_fitness()def evaluate_fitness(self):# 计算个体适应度fitness = 0.0for i in range(gene_len - 1):# 起始城市和目标城市from_idx = self.genes[i]to_idx = self.genes[i + 1]fitness += city_dist_mat[from_idx, to_idx]# 连接首尾fitness += city_dist_mat[self.genes[-1], self.genes[0]]return fitnessclass Ga:def __init__(self, input_):global city_dist_matcity_dist_mat = input_self.best = None  # 每一代的最佳个体self.individual_list = []  # 每一代的个体列表self.result_list = []  # 每一代对应的解self.fitness_list = []  # 每一代对应的适应度def cross(self):new_gen = []random.shuffle(self.individual_list)for i in range(0, individual_num - 1, 2):# 父代基因genes1 = copy_list(self.individual_list[i].genes)genes2 = copy_list(self.individual_list[i + 1].genes)index1 = random.randint(0, gene_len - 2)index2 = random.randint(index1, gene_len - 1)pos1_recorder = {value: idx for idx, value in enumerate(genes1)}pos2_recorder = {value: idx for idx, value in enumerate(genes2)}# 交叉for j in range(index1, index2):value1, value2 = genes1[j], genes2[j]pos1, pos2 = pos1_recorder[value2], pos2_recorder[value1]genes1[j], genes1[pos1] = genes1[pos1], genes1[j]genes2[j], genes2[pos2] = genes2[pos2], genes2[j]pos1_recorder[value1], pos1_recorder[value2] = pos1, jpos2_recorder[value1], pos2_recorder[value2] = j, pos2new_gen.append(Individual(genes1))new_gen.append(Individual(genes2))return new_gendef mutate(self, new_gen):for individual in new_gen:if random.random() < mutate_prob:# 翻转切片old_genes = copy_list(individual.genes)index1 = random.randint(0, gene_len - 2)index2 = random.randint(index1, gene_len - 1)genes_mutate = old_genes[index1:index2]genes_mutate.reverse()individual.genes = old_genes[:index1] + genes_mutate + old_genes[index2:]# 两代合并self.individual_list += new_gendef select(self):# 锦标赛group_num = 10  # 小组数group_size = 10  # 每小组人数group_winner = individual_num // group_num  # 每小组获胜人数winners = []  # 锦标赛结果for i in range(group_num):group = []for j in range(group_size):# 随机组成小组player = random.choice(self.individual_list)player = Individual(player.genes)group.append(player)group = Ga.rank(group)# 取出获胜者winners += group[:group_winner]self.individual_list = winners@staticmethoddef rank(group):# 冒泡排序for i in range(1, len(group)):for j in range(0, len(group) - i):if group[j].fitness > group[j + 1].fitness:group[j], group[j + 1] = group[j + 1], group[j]return groupdef next_gen(self):# 交叉new_gen = self.cross()# 变异self.mutate(new_gen)# 选择self.select()# 获得这一代的结果for individual in self.individual_list:if individual.fitness < self.best.fitness:self.best = individualdef train(self, ifplot=False):# 初代种群self.individual_list = [Individual() for _ in range(individual_num)]self.best = self.individual_list[0]# 迭代for i in range(gen_num):self.next_gen()# 连接首尾result = copy_list(self.best.genes)result.append(result[0])self.result_list.append(result)self.fitness_list.append(self.best.fitness)return self.result_list, self.fitness_list

 config.py:我为了运行时调参,将其改为类帮助我不用每次都要到隔壁去修改参数

# -*- coding: utf-8 -*-
import argparseclass ConfigParser:def __init__(self, city_nums=101, pos_dimensions=2, individual_nums=60, gen_nums=1000, mutate_probs=0.25):'''参数调整,默认值可修改:param city_num: 城市数量:param pos_dimension: 坐标维度:param individual_num: 个体数:param gen_num: 迭代轮数:param mutate_prob: 变异概率:return: 参数说明'''self.parser = argparse.ArgumentParser(description='Configuration file')self.arg_lists = []# Datadata_arg = self.add_argument_group('Data')data_arg.add_argument('--city_num', type=int, default=city_nums, help='city num')  # 城市数量data_arg.add_argument('--pos_dimension', type=int, default=pos_dimensions, help='city num')  # 坐标维度data_arg.add_argument('--individual_num', type=int, default=individual_nums, help='individual num')  # 个体数data_arg.add_argument('--gen_num', type=int, default=gen_nums, help='generation num')  # 迭代轮数data_arg.add_argument('--mutate_prob', type=float, default=mutate_probs, help='probability of mutate')  # 变异概率def add_argument_group(self, name):arg = self.parser.add_argument_group(name)self.arg_lists.append(arg)return argdef get_config(self):self.config, self.unparsed = self.parser.parse_known_args()return self.configdef print_config(self):print('\n')print('Data Config:')print('* city num:', self.config.city_num)print('* individual num:', self.config.individual_num)print('* generation num:', self.config.gen_num)print('* probability of mutate:', self.config.mutate_prob)if __name__ == '__main__':Cf = ConfigParser(city_nums=101, gen_nums=10000)config = Cf.get_config()print("路径个数:", config.city_num)print("迭代次数:", config.gen_num)

main.py:我将ga.py里的代码拷到这里来了,所以没有调用ga,py,方便调参 

import numpy as np
import sys
sys.path.append(r'D:\86176\PycharmProjects\pythonProject\Interesting argrism\ga-tsp-main')
from config import ConfigParser
import matplotlib.pyplot as plt
# 解决中文显示问题
plt.rcParams['font.sans-serif'] = ['KaiTi']  # 指定默认字体
plt.rcParams['axes.unicode_minus'] = False  # 解决保存图像是负号'-'显示为方块的问题
from haversine import haversine
import time
import randomCf = ConfigParser(city_nums=101, gen_nums=10000)
config = Cf.get_config()
print("路径个数:", config.city_num)
print("迭代次数:", config.gen_num)
# 各项参数
gene_len = config.city_num
individual_num = config.individual_num
gen_num = config.gen_num
mutate_prob = config.mutate_probdef build_dist_mat(input_list):n = config.city_numdist_mat = np.zeros([n, n])for i in range(n):for j in range(i + 1, n):d = input_list[i, :] - input_list[j, :]# 计算点积dist_mat[i, j] = np.dot(d, d)dist_mat[j, i] = dist_mat[i, j]return dist_matdef dist_ance(sj):n = config.city_numdistance = np.zeros([n, n])for i in range(n):for j in range(i + 1, n):distance[i, j] = haversine(sj[i, :], sj[j, :])distance[j, i] = distance[i, j]return distance#######################################
# 遗传算法主要部分GA
def copy_list(old_arr: [int]):new_arr = []for element in old_arr:new_arr.append(element)return new_arr# 个体类
class Individual:def __init__(self, genes=None):# 随机生成序列if genes is None:genes = [i for i in range(gene_len)]random.shuffle(genes)self.genes = genesself.fitness = self.evaluate_fitness()def evaluate_fitness(self):# 计算个体适应度fitness = 0.0for i in range(gene_len - 1):# 起始城市和目标城市from_idx = self.genes[i]to_idx = self.genes[i + 1]fitness += city_dist_mat[from_idx, to_idx]# 连接首尾fitness += city_dist_mat[self.genes[-1], self.genes[0]]return fitnessclass Ga:def __init__(self, input_):global city_dist_matcity_dist_mat = input_self.best = None  # 每一代的最佳个体self.individual_list = []  # 每一代的个体列表self.result_list = []  # 每一代对应的解self.fitness_list = []  # 每一代对应的适应度def cross(self):new_gen = []random.shuffle(self.individual_list)for i in range(0, individual_num - 1, 2):# 父代基因genes1 = copy_list(self.individual_list[i].genes)genes2 = copy_list(self.individual_list[i + 1].genes)index1 = random.randint(0, gene_len - 2)index2 = random.randint(index1, gene_len - 1)pos1_recorder = {value: idx for idx, value in enumerate(genes1)}pos2_recorder = {value: idx for idx, value in enumerate(genes2)}# 交叉for j in range(index1, index2):value1, value2 = genes1[j], genes2[j]pos1, pos2 = pos1_recorder[value2], pos2_recorder[value1]genes1[j], genes1[pos1] = genes1[pos1], genes1[j]genes2[j], genes2[pos2] = genes2[pos2], genes2[j]pos1_recorder[value1], pos1_recorder[value2] = pos1, jpos2_recorder[value1], pos2_recorder[value2] = j, pos2new_gen.append(Individual(genes1))new_gen.append(Individual(genes2))return new_gendef mutate(self, new_gen):for individual in new_gen:if random.random() < mutate_prob:# 翻转切片old_genes = copy_list(individual.genes)index1 = random.randint(0, gene_len - 2)index2 = random.randint(index1, gene_len - 1)genes_mutate = old_genes[index1:index2]genes_mutate.reverse()individual.genes = old_genes[:index1] + genes_mutate + old_genes[index2:]# 两代合并self.individual_list += new_gendef select(self):# 锦标赛group_num = 10  # 小组数group_size = 10  # 每小组人数group_winner = individual_num // group_num  # 每小组获胜人数winners = []  # 锦标赛结果for i in range(group_num):group = []for j in range(group_size):# 随机组成小组player = random.choice(self.individual_list)player = Individual(player.genes)group.append(player)group = Ga.rank(group)# 取出获胜者winners += group[:group_winner]self.individual_list = winners@staticmethoddef rank(group):# 冒泡排序for i in range(1, len(group)):for j in range(0, len(group) - i):if group[j].fitness > group[j + 1].fitness:group[j], group[j + 1] = group[j + 1], group[j]return groupdef next_gen(self):# 交叉new_gen = self.cross()# 变异self.mutate(new_gen)# 选择self.select()# 获得这一代的结果for individual in self.individual_list:if individual.fitness < self.best.fitness:self.best = individualdef train(self):# 初代种群self.individual_list = [Individual() for _ in range(individual_num)]self.best = self.individual_list[0]# 迭代# plt.figure()# plt.ion()for i in range(gen_num):self.next_gen()# 连接首尾result = copy_list(self.best.genes)result.append(result[0])self.result_list.append(result)self.fitness_list.append(self.best.fitness)# plt.plot(self.fitness_list)# plt.pause(0.01)# plt.title(u"适应度曲线")# plt.legend()return self.result_list, self.fitness_listif __name__ == '__main__':Start = time.time()# 城市坐标# 读取数据city_pos_list = np.loadtxt(r'D:\86176\PycharmProjects\pythonProject\sj.txt', dtype=np.float32)city_pos_list = np.vstack([city_pos_list[:, [2 * i, 2 * i + 1]]for i in range(4)])d0 = np.array([70, 40])city_pos_list = np.vstack([d0, city_pos_list])# 城市距离矩阵city_dist_mat = dist_ance(city_pos_list)# print(city_pos_list)# print(city_dist_mat)# 遗传算法运行ga = Ga(city_dist_mat)result_list, fitness_list = ga.train()result = result_list[-1]idx = result.index(0)result = result[idx:-1]result.extend(result_list[-1][:idx])result.append(0)result_pos_list = city_pos_list[result, :]# fig = plt.figure()# plt.plot(result_pos_list[:, 0], result_pos_list[:, 1], 'o-r')# plt.title(u"路线")# plt.legend()# fig.show()# 画图# plt.figure()# plt.ion()# # plt.plot(fitness_list)# xx = [fitness_list[0]]# for i in range(1, len(fitness_list)):#     xx.append(fitness_list[i])#     plt.plot(xx)#     plt.pause(0.01)# plt.title(u"适应度曲线")# plt.legend()# plt.show()plt.figure()plt.ion()xs = [result_pos_list[0, 0]]ys = [result_pos_list[0, 1]]for i in range(1, len(result_pos_list)):xs.append(result_pos_list[i, 0])ys.append(result_pos_list[i, 1])plt.plot(xs, ys, '-o')plt.pause(0.1)End = time.time()print("用时", End - Start, '秒')print('运行路线为:')for i in result:print(i, end=' ')print("\n最短总距离为:", fitness_list[-1])

2.读入数据

        用的是一个飞机要经过的100个城市坐标(经纬度),所以在做的过程中要考虑经纬度之间距离的直接转化。飞机的起始坐标是(70,40),要经过下面的所有地点并回到起点。

经纬度坐标
经度纬度经度纬度经度纬度经度纬度
53.712115.304651.17580.032246.325328.275330.33136.9348
56.543221.418810.819816.252922.789123.104510.158412.4819
20.10515.45621.94510.205726.495122.122131.48478.964
26.241818.17644.035613.540128.983625.987938.472220.1731
28.269429.001132.1915.869936.486329.72840.971828.1477
8.958624.663516.561823.614310.559715.117850.211110.2944
8.15199.532522.107518.55690.121518.872648.207716.8889
31.949917.63090.77320.465647.413423.778341.86713.5667
43.54743.906153.352426.725630.816513.459527.71335.0706
23.92227.630651.961222.851112.793815.73074.95688.3669
21.505124.090915.254827.21116.2075.144249.24316.7044
17.116820.035434.168822.75719.44023.9211.581214.5677
52.11810.40889.555911.421924.45096.563426.721328.5667
37.584816.847435.66199.933324.46543.16440.77756.9576
14.470313.636819.86615.12243.16164.242818.524514.3598
58.684927.148539.516816.937156.508913.70952.521115.7957
38.438.464851.818123.01598.998323.64450.115623.7816
13.79091.95134.057423.39623.06248.431919.98575.7902
40.880114.297858.828914.522918.66356.743652.842327.288
39.949429.511447.509924.066410.112127.266228.781227.6659
8.083127.67059.155614.130453.79890.219933.6490.398
1.349616.835949.98166.082819.363517.662236.954523.0265
15.73219.569711.511817.388444.039816.263539.713928.4203
6.990923.180438.339219.99524.654319.605736.99824.3992
4.15913.185340.1420.30323.98769.40341.108427.7149

        求最短路径。

3.最终结果

        只需修改运行main.py中的文件就行了

        将结果坐标放入直角坐标中展示

迭代结果:

 

实时迭代结果的展示可能会使得算法在计算时速度会减慢,如果电脑好那就另说了,不建议实时结果展示。

运行路线为:
0 44 66 1 91 81 47 71 13 26 9 83 17 39 78 76 30 96 84 64 63 10 93 69 18 62 61 25 28 33 65 89 85 7 38 77 46 56 27 87 60 48 67 6 24 22 57 80 21 70 36 31 23 12 72 11 52 88 5 95 54 55 20 98 99 43 37 53 4 74 32 3 40 90 15 68 75 59 8 14 49 79 97 50 41 19 29 73 82 86 58 100 51 45 92 42 35 94 34 2 16 0 
最短总距离为: 40546.764132575256


总结

        这是我在之前国赛训练训练时的一个题目,虽然很简单,但是当时是真的觉得很难,记录一下,希望对有需要的同学有帮助,其实我现在是对这个算法理解的也还算深了,因为和它对抗了很久,总是想找一个合适的Python算法没找到,自己写的也不尽人意,这也算是我对自己这一模块结束的标志了吧。


http://chatgpt.dhexx.cn/article/GwfNRZjJ.shtml

相关文章

遗传算法的python实现(手撕python遗传算法)

遗传算法简介 假设有无约束优化问题&#xff1a; z f ( x , y ) zf(x,y) zf(x,y) 如何通过遗传算法求解&#xff1f; 在这里需要将该优化问题与遗传算法中的概念进行对比。 f f f 对应遗传算法的适应度函数。自变量 x , y x,y x,y 对应遗传算法的个体&#xff0c;注意&#…

Python 遗传算法 Genetic Algorithm

粒子群算法常常用于在连续解空间内搜索&#xff0c;而在不连续、离散的空间内常常会出现搜索越界的问题 例如旅行商问题&#xff0c;寻找可以遍历 15 个地点的最短路径&#xff08;当然可以用二进制状态压缩 动态规划解决&#xff09;&#xff0c;以 {0, 1, ..., 14} 表示这些…

python遗传算法之geatpy学习

&#x1f63b;今天我们来学习python中的遗传算法的使用&#xff0c;我们这里使用的是geatpy的包进行学习&#xff0c;本博客主要从geatpy中的各种数据结构一步一步进行学习&#xff0c;请大家耐心看完。 &#x1f424;其实以前也学习过遗传算法&#xff0c;但是主要使用matlab…

遗传算法详解 附python代码实现

遗传算法 遗传算法是用于解决最优化问题的一种搜索算法。从名字来看&#xff0c;遗传算法借用了生物学里达尔文的进化理论&#xff1a;”适者生存&#xff0c;不适者淘汰“&#xff0c;将该理论以算法的形式表现出来就是遗传算法的过程。 问题引入 上面提到遗传算法是用来解…

遗传算法【Python】

遗传算法概念 基本思想&#xff1a; 遗传算法(GA)是一种全局寻优搜索算法&#xff0c;它依据的是大自然生物进化过程中“适者生存”的规律。它首先对问题的可行解进行编码&#xff0c;组成染色体&#xff0c;然后通过模拟自然界的进化过程&#xff0c;对初始种群中的染色体进…

遗传算法python实现

遗传算法python实现 一、问题引入二、遗传算法的步骤1.初始化2.个体评价3.选择运算4.交叉运算5.变异运算6.终止条件判断 三、实现思路1.编码的设计2.适应度函数3.选择函数4.交叉函数5.变异函数6.迭代 四、具体实现1.编码解码函数2.适应度函数3.选择函数4.交叉函数5.变异函数6.选…

遗传算法(Python)

一、遗传算法 1、遗传算法的定义 遗传算法是一种现代优化算法。根据自然界适者生存的法则&#xff0c;种群中优秀个体的基因进行遗传。每个个体的染色体通过选择、交叉和变异等过程产生新的适应度更大的染色体&#xff0c;其中适应度越大的个体越优秀&#xff0c;种群得到优化…

python遗传算法(详解)

学习代码来源于&#xff1a;遗传算法python 一.主要思想 遗传算法是根据达尔文的“适者生存&#xff0c;优胜劣汰”的思想来找到最优解的额&#xff0c;其特点是所找到的解是全局最优解&#xff0c;相对于蚁群算法可能出现的局部最优解还是有优势的。 二.主要名词 个体&…

DH算法、DHE算法、ECDHE算法演进

ECDHE 算法解决了 RSA 算法不具备前向安全的性质 和 DH 算法效率低下的问题。 ECDHE 算法具有前向安全。所以被广泛使用。 由什么演变而来 DH 算法 -- > DHE 算法 -- > ECDHE 算法 DH 算法是非对称加密算法&#xff0c;该算法的核心数学思想是离散对数。 核心数学思…

DH 算法思想 SSH解决内容篡改问题

DH算法用于交换密钥 交换密钥的目的是生成仅双方共享的密钥 交换密钥的基本过程&#xff1a; 双方确定公开的内容用各自的私钥分别对公共内容加密&#xff08;加密本质就是数学运算&#xff09;并发送给对方这时双方使用自己的密钥对收到的内容加密&#xff08;要设计运算保证…

ECDH算法详解

ECDH算法详解 ECDH算法详解DH密钥交换原理结合ECC椭圆曲线算法ECDSA签名算法 参考资料 ECDH算法详解 DH密钥交换原理 进一步解释&#xff1a; 两端&#xff08;Alice 和 Bob&#xff09;想要安全的交换信息并且第三方不能获取到该信息。当然这也是TLS协议中的目的之一&#xf…

DH算法(密钥交换算法)

一 对称加密缺点 密钥传递过程复杂&#xff0c;这是对称加密带来的困扰。 二 DH密钥交换算法特点 构建本地密钥 双方密钥一致 三 DH相关参数 四 DH算法实现过程 1、初始化发送方的密钥&#xff08;KeyPairGenerator、KeyPair、PublicKey&#xff09; 2、初始化接受方的密钥&…

SSL/TLS中的DH算法、DHE算法、 ECDHE算法介绍

❤️SSL/TLS专栏导航页❤️ 文章目录 1. DH算法简介2. DH算法协商流程3. DH算法证明4. SSL/TLS中的DH算法 1. DH算法简介 Diffie-Hellman密钥交换算法是在1976年由这两个人发明的算法。它可以在不安全的网络中&#xff0c;通过交换一些公开的信息协商出共享密钥&#xff0c;使…

一文读懂DH密钥交换算法

DH 算法是 Diffie和Hellman于1976年提出了一种的密钥交换协议。这种加密算法主要用于密钥的交换&#xff0c;可以在非安全信道下为双方创建通信密钥&#xff0c;通讯双方可以使用这个密钥进行消息的加密、解密&#xff0c;并且能够保证通讯的安全。 换而言之&#xff0c;算法希…

密钥协商算法的演变 —— RSA算法 - DH算法 - DHE算法 - ECDHE算法

文章目录 1. RSA算法RSA握手过程RSA秘钥协商算法最大的缺陷 2. DH算法3. DHE算法4. ECDHE算法ECDHE秘钥协商算法的TSL握手&#xff1a; 1. RSA算法 传统的 TLS 握⼿基本都是使⽤ RSA 算法来实现密钥交换的。在 RSA 密钥协商算法中&#xff0c;客户端会⽣成随机密钥&#xff0c…

openswan中DH算法说明

Author :Email : vip_13031075266163.comDate : 2021.01.11Copyright : 未经同意不得转载&#xff01;&#xff01;&#xff01;Version &#xff1a; openswan-2.6.51.5Reference&#xff1a;https://download.openswan.org/openswan/ 目录 1. ope…

DH法理解

旋转关节机器人 四个参数&#xff1a;a&#xff0c;α&#xff0c;d&#xff0c;θ 四个参数实际上是两组&#xff0c;先有a&#xff0c;α&#xff0c;再有d&#xff0c;θ。 a是两个转轴之间的距离&#xff08;Z轴&#xff09;&#xff0c;异面直线公垂线的长度&#xff0c;也…

DH算法及源码解读

【主流的密钥交换方式】 敏感数据信息安全传输需要对敏感信息加密&#xff0c;加密的密钥涉及到传输两端的密钥协商和交换&#xff0c;目前主要两种密钥交换的机制有&#xff1a; 1. 基于非对称密钥的实现&#xff1a;请求方用接收方的公钥加密自己的密钥&#xff0c;接收方用…

DH 加密算法的使用

DH 算法的介绍 上面介绍的 DES,3DES,AES 算法都是对称密码算法&#xff0c;所谓对称&#xff0c;在上面也解释了&#xff0c;就是加密和解密的过程中使用相同的密钥 。而现在将要介绍的是 DH 算法&#xff0c;属于非对称密码算法&#xff0c;根据对称密码的概念&#xff0c;很…

非对称加密 DH算法

DH算法简介 迪菲-赫尔曼密钥交换&#xff08;Diffie–Hellman key exchange&#xff0c;缩写为D-H&#xff09; 是一种安全协议。 它可以让双方在完全没有对方任何预先信息的条件下通过不安全信道创建起一个密钥。 这个密钥可以在后续的通讯中作为对称密钥来加密通讯内容。 迪…