Skip to content

Commit a8acd39

Browse files
author
lihong
committedAug 25, 2024
提交
0 parents  commit a8acd39

23 files changed

+667
-0
lines changed
 
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
2+
name = ["农夫", "狼", "羊", "菜"]
3+
scheme_count = 0
4+
5+
# 完成过河
6+
def is_done(status):
7+
return status[0] and status[1] and status[2] and status[3]
8+
9+
# 生成下一个过河的所有情况
10+
def create_all_next_status(status):
11+
next_status_list = []
12+
13+
for i in range(0, 4):
14+
if status[0] != status[i]: # 和农夫不同一侧
15+
continue
16+
17+
next_status = [status[0],status[1],status[2],status[3]]
18+
# 农夫和其中一个过河,i 为 0 时候,农夫自己过河。
19+
next_status[0] = not next_status[0]
20+
next_status[i] = next_status[0] # 和农夫一起过河
21+
22+
if is_valid_status(next_status):
23+
next_status_list.append(next_status)
24+
25+
return next_status_list
26+
27+
# 判断是否合法的局面
28+
def is_valid_status(status):
29+
if status[1] == status[2]:
30+
if status[0] != status[1]:
31+
# 狼和羊同侧,没有农夫在场
32+
return False
33+
34+
if status[2] == status[3]:
35+
if status[0] != status[2]:
36+
# 羊和菜同侧,没有农夫在场
37+
return False
38+
39+
return True
40+
41+
def search(history_status):
42+
global scheme_count
43+
current_status = history_status[len(history_status) - 1]
44+
45+
next_status_list = create_all_next_status(current_status)
46+
for next_status in next_status_list:
47+
if next_status in history_status:
48+
# 出现重复的情况
49+
continue
50+
51+
history_status.append(next_status)
52+
53+
if is_done(next_status):
54+
scheme_count += 1
55+
print("方案 " + str(scheme_count) + ":")
56+
print_history_status(history_status)
57+
else:
58+
search(history_status)
59+
60+
history_status.pop()
61+
62+
def readable_status(status, is_across):
63+
result = ""
64+
for i in range(0,4):
65+
if status[i] == is_across:
66+
if len(result) != 0:
67+
result += ","
68+
result += name[i]
69+
70+
return "[" + result + "]"
71+
72+
#打印结果
73+
def print_history_status(history_status):
74+
for status in history_status:
75+
print(readable_status(status, False) + "≈≈≈≈≈≈≈≈≈≈" + readable_status(status, True))
76+
77+
if __name__ == "__main__":
78+
# 初始状态
79+
status = [False, False, False, False]
80+
# 情况队列
81+
history_status = [status]
82+
search(history_status)

‎人工智能导论/基于Q-learning寻宝游戏/.idea/.gitignore

+3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎人工智能导论/基于Q-learning寻宝游戏/.idea/.name

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎人工智能导论/基于Q-learning寻宝游戏/.idea/inspectionProfiles/Project_Default.xml

+12
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎人工智能导论/基于Q-learning寻宝游戏/.idea/inspectionProfiles/profiles_settings.xml

+6
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎人工智能导论/基于Q-learning寻宝游戏/.idea/misc.xml

+4
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎人工智能导论/基于Q-learning寻宝游戏/.idea/modules.xml

+8
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎人工智能导论/基于Q-learning寻宝游戏/.idea/基于Q-learning寻宝游戏.iml

+8
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,227 @@
1+
import pandas as pd
2+
import numpy as np
3+
import time
4+
import tkinter as tk
5+
6+
UNIT = 40 # 像素
7+
ENV_H = 8 # 格子高度
8+
ENV_W = 8 # 格子宽度
9+
10+
11+
class env(tk.Tk, object):
12+
def __init__(self):
13+
super(env, self).__init__()
14+
self.action_space = ['u', 'd', 'l', 'r'] #上下左右四个动作
15+
self.n_actions = len(self.action_space)
16+
self.title('寻宝游戏')
17+
self.geometry('{0}x{1}'.format(ENV_H * UNIT, ENV_H * UNIT)) #设置窗口的大小
18+
self._build_ENV()
19+
20+
def _build_ENV(self):
21+
# 创建游戏画布
22+
self.canvas = tk.Canvas(self, bg='white',
23+
height=ENV_H * UNIT,
24+
width=ENV_W * UNIT)
25+
26+
# 绘制网格
27+
for c in range(0, ENV_W * UNIT, UNIT):
28+
x0, y0, x1, y1 = c, 0, c, ENV_H * UNIT
29+
self.canvas.create_line(x0, y0, x1, y1)
30+
for r in range(0, ENV_H * UNIT, UNIT):
31+
x0, y0, x1, y1 = 0, r, ENV_W * UNIT, r
32+
self.canvas.create_line(x0, y0, x1, y1)
33+
34+
# create origin
35+
origin = np.array([20, 20])
36+
37+
# 创建陷阱
38+
hell1_center = origin + np.array([UNIT * 2, UNIT])
39+
self.hell1 = self.canvas.create_rectangle(
40+
hell1_center[0] - 15, hell1_center[1] - 15,
41+
hell1_center[0] + 15, hell1_center[1] + 15,
42+
fill='black')
43+
# 创建陷阱
44+
hell2_center = origin + np.array([UNIT, UNIT * 2])
45+
self.hell2 = self.canvas.create_rectangle(
46+
hell2_center[0] - 15, hell2_center[1] - 15,
47+
hell2_center[0] + 15, hell2_center[1] + 15,
48+
fill='black')
49+
50+
# 创建陷阱
51+
hell3_center = origin + np.array([UNIT * 2, UNIT * 6])
52+
self.hell3 = self.canvas.create_rectangle(
53+
hell3_center[0] - 15, hell3_center[1] - 15,
54+
hell3_center[0] + 15, hell3_center[1] + 15,
55+
fill='black')
56+
57+
# 创建陷阱
58+
hell4_center = origin + np.array([UNIT * 6, UNIT * 2])
59+
self.hell4 = self.canvas.create_rectangle(
60+
hell4_center[0] - 15, hell4_center[1] - 15,
61+
hell4_center[0] + 15, hell4_center[1] + 15,
62+
fill='black')
63+
64+
# 创建陷阱
65+
hell5_center = origin + np.array([UNIT * 4, UNIT * 4])
66+
self.hell5 = self.canvas.create_rectangle(
67+
hell5_center[0] - 15, hell5_center[1] - 15,
68+
hell5_center[0] + 15, hell5_center[1] + 15,
69+
fill='black')
70+
71+
# 创建陷阱
72+
hell6_center = origin + np.array([UNIT * 4, UNIT * 1])
73+
self.hell6 = self.canvas.create_rectangle(
74+
hell6_center[0] - 15, hell6_center[1] - 15,
75+
hell6_center[0] + 15, hell6_center[1] + 15,
76+
fill='black')
77+
78+
# 创建陷阱
79+
hell7_center = origin + np.array([UNIT * 1, UNIT * 3])
80+
self.hell7 = self.canvas.create_rectangle(
81+
hell7_center[0] - 15, hell7_center[1] - 15,
82+
hell7_center[0] + 15, hell7_center[1] + 15,
83+
fill='black')
84+
85+
# 创建陷阱
86+
hell8_center = origin + np.array([UNIT * 2, UNIT * 4])
87+
self.hell8 = self.canvas.create_rectangle(
88+
hell8_center[0] - 15, hell8_center[1] - 15,
89+
hell8_center[0] + 15, hell8_center[1] + 15,
90+
fill='black')
91+
92+
# 创建陷阱
93+
hell9_center = origin + np.array([UNIT * 3, UNIT * 2])
94+
self.hell9 = self.canvas.create_rectangle(
95+
hell9_center[0] - 15, hell9_center[1] - 15,
96+
hell9_center[0] + 15, hell9_center[1] + 15,
97+
fill='black')
98+
99+
# 创建宝藏
100+
oval_center = origin + UNIT * 3
101+
self.oval = self.canvas.create_oval(
102+
oval_center[0] - 15, oval_center[1] - 15,
103+
oval_center[0] + 15, oval_center[1] + 15,
104+
fill='yellow')
105+
106+
# 创建寻宝人
107+
self.rect = self.canvas.create_rectangle(
108+
origin[0] - 15, origin[1] - 15,
109+
origin[0] + 15, origin[1] + 15,
110+
fill='red')
111+
112+
# 显示画布
113+
self.canvas.pack()
114+
115+
def reset(self):
116+
self.update()
117+
time.sleep(0.5)
118+
self.canvas.delete(self.rect)
119+
origin = np.array([20, 20])
120+
self.rect = self.canvas.create_rectangle(
121+
origin[0] - 15, origin[1] - 15,
122+
origin[0] + 15, origin[1] + 15,
123+
fill='red')
124+
# 返回观察结果
125+
return self.canvas.coords(self.rect)
126+
127+
def step(self, action):
128+
s = self.canvas.coords(self.rect) #获取当前寻宝人位置
129+
base_action = np.array([0, 0])
130+
if action == 0: # 上
131+
if s[1] > UNIT:
132+
base_action[1] -= UNIT
133+
elif action == 1: # 下
134+
if s[1] < (ENV_H - 1) * UNIT:
135+
base_action[1] += UNIT
136+
elif action == 2: # 右
137+
if s[0] < (ENV_W - 1) * UNIT:
138+
base_action[0] += UNIT
139+
elif action == 3: # 左
140+
if s[0] > UNIT:
141+
base_action[0] -= UNIT
142+
143+
self.canvas.move(self.rect, base_action[0], base_action[1]) # 移动寻宝人
144+
145+
s_ = self.canvas.coords(self.rect) # 获取新位置
146+
147+
# 奖励函数
148+
if s_ == self.canvas.coords(self.oval):
149+
reward = 1
150+
done = True
151+
s_ = 'terminal'
152+
elif s_ in [self.canvas.coords(self.hell1), self.canvas.coords(self.hell2), self.canvas.coords(self.hell3),
153+
self.canvas.coords(self.hell4), self.canvas.coords(self.hell5), self.canvas.coords(self.hell6),
154+
self.canvas.coords(self.hell7),
155+
self.canvas.coords(self.hell8), self.canvas.coords(self.hell9)]:
156+
reward = -1
157+
done = True
158+
s_ = 'terminal'
159+
else:
160+
reward = 0
161+
done = False
162+
163+
return s_, reward, done
164+
165+
def render(self):
166+
time.sleep(0.1)
167+
self.update() #强制画布重绘
168+
169+
170+
class QLearningTable:
171+
def __init__(self, actions, learning_rate=0.01, reward_decay=0.9, e_greedy=0.9):
172+
self.actions = actions
173+
self.lr = learning_rate
174+
self.gamma = reward_decay
175+
self.epsilon = e_greedy
176+
self.q_table = pd.DataFrame(columns=self.actions, dtype=np.float64) #存储每个状态-动作对的 Q 值的数据帧
177+
178+
def choose_action(self, observation):
179+
self.check_state_exist(observation)
180+
if np.random.uniform() < self.epsilon:
181+
#根据Q表选择最大的Q值对应的动作
182+
state_action = self.q_table.loc[observation, :]
183+
action = np.random.choice(state_action[state_action == np.max(state_action)].index)
184+
else:
185+
#随机选择一个动作
186+
action = np.random.choice(self.actions)
187+
return action
188+
189+
def learn(self, s, a, r, s_):
190+
self.check_state_exist(s_)
191+
q_predict = self.q_table.loc[s, a]
192+
if s_ != 'terminal':
193+
#结合当前奖励和未来预期的奖励
194+
q_target = r + self.gamma * self.q_table.loc[s_, :].max()
195+
else:
196+
q_target = r
197+
self.q_table.loc[s, a] += self.lr * (q_target - q_predict)
198+
199+
200+
def check_state_exist(self, state): #检查状态 state 是否存在于 Q 表中
201+
if state not in self.q_table.index:
202+
self.q_table = self.q_table._append(
203+
pd.Series([0] * len(self.actions), index=self.q_table.columns, name=state))
204+
205+
206+
def update():
207+
for episode in range(150):
208+
observation = env.reset()
209+
print(episode)
210+
while True:
211+
env.render()
212+
action = RL.choose_action(str(observation))
213+
observation_, reward, done = env.step(action)
214+
RL.learn(str(observation), action, reward, str(observation_))
215+
observation = observation_
216+
if done:
217+
break
218+
print('game over')
219+
env.destroy()
220+
221+
222+
if __name__ == '__main__':
223+
env = env()
224+
RL = QLearningTable(actions=list(range(env.n_actions)))
225+
226+
env.after(100, update)
227+
env.mainloop()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,316 @@
1+
import numpy as np
2+
import copy
3+
import matplotlib.pyplot as plt
4+
import random
5+
6+
#准备好距离矩阵
7+
city_num = 5
8+
city_dist_mat = np.zeros([city_num, city_num])
9+
city_dist_mat[0][1] = city_dist_mat[1][0] = 11
10+
city_dist_mat[0][2] = city_dist_mat[2][0] = 22
11+
city_dist_mat[0][3] = city_dist_mat[3][0] = 33
12+
city_dist_mat[0][4] = city_dist_mat[4][0] = 44
13+
city_dist_mat[1][2] = city_dist_mat[2][1] = 55
14+
city_dist_mat[1][3] = city_dist_mat[3][1] = 66
15+
city_dist_mat[1][4] = city_dist_mat[4][1] = 77
16+
city_dist_mat[2][3] = city_dist_mat[3][2] = 88
17+
city_dist_mat[2][4] = city_dist_mat[4][2] = 99
18+
city_dist_mat[3][4] = city_dist_mat[4][3] = 100
19+
20+
21+
# 定义全局变量,用于记录个体数量和距离列表
22+
num_person_idx = 0 # 个体索引
23+
num_person = 0 # 个体数量
24+
dis_list = [] # 距离列表
25+
26+
class Individual:
27+
def __init__(self, genes=None):
28+
global num_person
29+
global dis_list
30+
global num_person_idx
31+
num_person_idx += 1
32+
# 每训练20次增加一个个体数量
33+
if num_person_idx % 20 == 0:
34+
num_person += 1
35+
36+
self.genes = genes
37+
38+
# 初始化基因
39+
if self.genes == None:
40+
genes = [0] * 5 # 城市数量
41+
temp = [0] * 4
42+
temp = [i for i in range(1, city_num)] # 城市编号
43+
random.shuffle(temp) # 打乱城市顺序
44+
genes[1:] = temp
45+
genes[0] = 0
46+
self.genes = genes
47+
self.fitness = self.evaluate_fitness() # 计算适应度
48+
else:
49+
self.fitness = float(self.evaluate_fitness())
50+
51+
# 计算个体的适应度
52+
def evaluate_fitness(self):
53+
dis = 0
54+
# 计算路径长度
55+
for i in range(city_num - 1):
56+
dis += city_dist_mat[self.genes[i]][self.genes[i+1]]
57+
if i == city_num - 2:
58+
dis += city_dist_mat[self.genes[i + 1]][0] # 回到起点
59+
# 每20个个体记录一次距离
60+
if num_person_idx % 20 == 0:
61+
dis_list.append(dis)
62+
# 适应度为距离的倒数
63+
return 1 / dis
64+
65+
# 复制列表函数
66+
def copy_list(old):
67+
new = []
68+
for element in old:
69+
new.append(element)
70+
return new
71+
72+
# 按适应度排序函数
73+
def sort_win_num(group):
74+
for i in range(len(group)):
75+
for j in range(len(group) - i - 1):
76+
if group[j].fitness < group[j+1].fitness:
77+
temp = group[j]
78+
group[j] = group[j+1]
79+
group[j+1] = temp
80+
return group
81+
#定义Ga类
82+
#3~5,交叉、变异、更新种群,全部在Ga类中实现
83+
class Ga:
84+
#input_为城市间的距离矩阵
85+
def __init__(self, input_):
86+
#声明全局变量
87+
global city_dist_mat
88+
city_dist_mat = input_
89+
#当代的最佳个体
90+
self.best = Individual(None)
91+
#种群
92+
self.individual_list = []
93+
#每一代的最佳个体
94+
self.result_list = []
95+
#每一代个体对应的最佳适应度
96+
self.fitness_list = []
97+
98+
99+
# 交叉操作,采用交叉变异方法
100+
def cross(self):
101+
new_gen = [] # 用于存放新一代的个体
102+
num_cross = 3 # 交叉时选择的城市数量
103+
104+
# 对每两个相邻的个体进行交叉
105+
for i in range(0, len(self.individual_list) - 1, 2):
106+
parent_gen1 = copy_list(self.individual_list[i].genes) # 父代1的基因
107+
parent_gen2 = copy_list(self.individual_list[i+1].genes) # 父代2的基因
108+
index1_1 = 0
109+
index1_2 = 0
110+
index2_1 = 0
111+
index2_2 = 0
112+
index_list = [0] * 3 # 存放交叉的起始索引的列表
113+
114+
# 随机选择交叉的起始索引
115+
for i in range(city_num - 3): # 这里应该是range(city_num - num_cross),即0,1
116+
index_list[i] = i + 1
117+
index1_1 = random.choice(index_list)
118+
index1_2 = index1_1 + 2
119+
index2_1 = random.choice(index_list)
120+
index2_2 = index2_1 + 2
121+
122+
# 获取交叉段的城市列表
123+
choice_list1 = parent_gen1[index1_1:index1_2 + 1]
124+
choice_list2 = parent_gen2[index2_1:index2_2 + 1]
125+
126+
# 初始化两个子代的基因列表
127+
son_gen1 = [0] * city_num
128+
son_gen2 = [0] * city_num
129+
130+
# 将交叉段复制到子代中
131+
son_gen1[index1_1: index1_2 + 1] = choice_list1
132+
son_gen2[index2_1: index2_2 + 1] = choice_list2
133+
134+
temp1 = choice_list1 # 临时保存交叉段的城市列表
135+
temp2 = choice_list2
136+
137+
# 处理未被交叉的城市
138+
if index1_1 == 0:
139+
pass
140+
else:
141+
for i in range(index1_1):
142+
for j in range(city_num):
143+
if parent_gen2[j] not in choice_list1:
144+
son_gen1[i] = parent_gen2[j]
145+
choice_list1.append(parent_gen2[j])
146+
break
147+
148+
choice_list1 = temp1
149+
150+
if index1_2 == city_num - 1:
151+
pass
152+
else:
153+
for i in range(index1_2 + 1, city_num):
154+
for j in range(city_num):
155+
if parent_gen2[j] not in choice_list1:
156+
son_gen1[i] = parent_gen2[j]
157+
choice_list1.append(parent_gen2[j])
158+
break
159+
160+
# 处理子代2中未被交叉的城市,同理
161+
if index2_1 == 0:
162+
pass
163+
else:
164+
for i in range(index2_1):
165+
for j in range(city_num):
166+
if parent_gen1[j] not in choice_list2:
167+
son_gen2[i] = parent_gen1[j]
168+
choice_list2.append(parent_gen1[j])
169+
break
170+
171+
choice_list2 = temp2
172+
173+
if index2_2 == city_num - 1:
174+
pass
175+
else:
176+
for i in range(index2_2 + 1, city_num):
177+
for j in range(city_num):
178+
if parent_gen1[j] not in choice_list2:
179+
son_gen2[i] = parent_gen1[j]
180+
choice_list2.append(parent_gen1[j])
181+
break
182+
183+
# 将新生成的子代加入新一代的列表中
184+
new_gen.append(Individual(son_gen1))
185+
new_gen.append(Individual(son_gen2))
186+
187+
return new_gen
188+
#变异
189+
def mutate(self, new_gen):
190+
mutate_p = 0.02 # 变异概率,待调参数
191+
index_list = [0] * (city_num - 1) # 初始化索引列表
192+
index_1 = 1 # 变异位置索引1
193+
index_2 = 1 # 变异位置索引2
194+
195+
# 初始化索引列表,表示基因中除了起点之外的位置
196+
for i in range(city_num - 1):
197+
index_list[i] = i + 1
198+
199+
# 对于新生成的个体群中的每个个体
200+
for individual in new_gen:
201+
# 根据变异概率决定是否进行变异
202+
if random.random() < mutate_p:
203+
# 随机选择两个不同的位置进行交换
204+
index_1 = random.choice(index_list)
205+
index_2 = random.choice(index_list)
206+
while index_1 == index_2: # 确保选择的两个位置不相同
207+
index_2 = random.choice(index_list)
208+
209+
# 交换选定位置上的基因值
210+
temp = individual.genes[index_1]
211+
individual.genes[index_1] = individual.genes[index_2]
212+
individual.genes[index_2] = temp
213+
214+
# 变异结束,将新生成的个体与老一代进行合并
215+
self.individual_list += new_gen
216+
#选择
217+
def select(self):
218+
#在此选用轮盘赌算法
219+
#考虑到5的阶乘是120,所以可供选择的个体基数应该适当大一些,
220+
#在此每次从种群中选择6个,进行轮盘赌,初始化60个个体,同时适当调高变异的概率
221+
select_num = 6
222+
select_list = []
223+
for i in range(select_num):
224+
225+
gambler = random.choice(self.individual_list)
226+
gambler = Individual(gambler.genes)
227+
select_list.append(gambler)
228+
#求出这些fitness之和
229+
sum = 0
230+
for i in range(select_num):
231+
sum += select_list[i].fitness
232+
sum_m = [0]*select_num
233+
#实现概率累加
234+
for i in range(select_num):
235+
for j in range(i+1):
236+
sum_m[i] += select_list[j].fitness
237+
sum_m[i] /= sum
238+
new_select_list = []
239+
p_num = 0#随机数
240+
for i in range(select_num):
241+
p_num = random.uniform(0,1)
242+
if p_num>0 and p_num < sum_m[0]:
243+
new_select_list.append(select_list[0])
244+
elif p_num>= sum_m[0] and p_num < sum_m[1]:
245+
new_select_list.append(select_list[1])
246+
elif p_num >= sum_m[1] and p_num < sum_m[2]:
247+
new_select_list.append(select_list[2])
248+
elif p_num >= sum_m[2] and p_num < sum_m[3]:
249+
new_select_list.append(select_list[3])
250+
elif p_num >= sum_m[3] and p_num < sum_m[4]:
251+
new_select_list.append(select_list[4])
252+
elif p_num >= sum_m[4] and p_num < sum_m[5]:
253+
new_select_list.append(select_list[5])
254+
else:
255+
pass
256+
#将新生成的一代替代父代种群
257+
self.individual_list = new_select_list
258+
#更新种群
259+
def next_gen(self):
260+
#交叉
261+
new_gene = self.cross()
262+
#变异
263+
self.mutate(new_gene)
264+
#选择
265+
self.select()
266+
#获得这一代的最佳个体
267+
for individual in self.individual_list:
268+
if individual.fitness > self.best.fitness:
269+
self.best = individual
270+
271+
272+
def train(self):
273+
#随机出初代种群#
274+
individual_num = 60
275+
self.individual_list = [Individual() for _ in range(individual_num)]
276+
#迭代
277+
gen_num = 100
278+
for i in range(gen_num):
279+
#从当代种群中交叉、变异、选择出适应度最佳的个体,获得子代产生新的种群
280+
self.next_gen()
281+
#连接首位
282+
result = copy.deepcopy(self.best.genes)
283+
result.append(result[0])
284+
self.result_list.append(result)
285+
self.fitness_list.append(self.best.fitness)
286+
print(self.result_list[-1])
287+
print('距离总和是:', 1/self.fitness_list[-1])
288+
289+
290+
def draw(self):
291+
# 创建x轴坐标,即迭代次数
292+
x_list = [i for i in range(num_person)]
293+
# 获取每一代最佳路径的长度列表作为y轴坐标
294+
y_list = dis_list
295+
# 设置图表大小
296+
plt.rcParams['figure.figsize'] = (60, 45)
297+
# 绘制折线图
298+
plt.plot(x_list, y_list, color='g')
299+
# 设置x轴标签
300+
plt.xlabel('Cycles', size=50)
301+
# 设置y轴标签
302+
plt.ylabel('Route', size=50)
303+
# 设置x轴刻度
304+
x = np.arange(0, 80, 5)
305+
plt.xticks(x)
306+
y = np.arange(0, 1000, 20)
307+
plt.yticks(y)
308+
# 设置图表标题
309+
plt.title('Trends in distance changes', size=50)
310+
# 设置刻度标签大小
311+
plt.tick_params(labelsize=30)
312+
plt.show()
313+
314+
route = Ga(city_dist_mat) # 初始化遗传算法对象
315+
route.train() # 训练遗传算法获取最优路径
316+
route.draw() # 绘制路径长度变化趋势图
145 KB
Binary file not shown.
44.7 KB
Binary file not shown.
175 KB
Binary file not shown.
117 KB
Binary file not shown.
151 KB
Binary file not shown.
181 KB
Binary file not shown.
149 KB
Binary file not shown.
125 KB
Binary file not shown.
134 KB
Binary file not shown.
Binary file not shown.
120 KB
Binary file not shown.
111 KB
Binary file not shown.
Binary file not shown.

0 commit comments

Comments
 (0)
Please sign in to comment.