# 导入相关的包
# -- coding: utf-8 --**
import requests #HTTP请求
import time
import re
import json # 用于解析Json
import pandas as pd # 用于处理数据(数据分析相关的同学必须会的包)
import pandas
import csv
import re
import time
import json
from urllib.request import urlopen
import urllib
import random
import copy
import sys
import tkinter # //GUI模块
import threading
from functools import reduce
from geopy.distance import geodesic
import numpy as np
'''https://blog.csdn.net/Fuel_Ming/article/details/117193433'''
'https://blog.csdn.net/Fuel_Ming/article/details/117193433'
开发简易文档:
需求:
给定指定地点,获取最短路径问题 ,也就是解决现实生活中的旅行商问题
实现步骤:
1.调用百度api,获取各个地点的经纬度(关于百度api的使用请查阅最后的引用文献)
2.将各个地点经纬度换算为distance 单位: km 并获得cost loss ,默认为对应的最佳公交地铁时间花费,
3.采用蚁群算法获取最短路径
以下为程序生成的实际显示
df = pd.DataFrame(['广东工业大学(大学城校区)','广州市鲁迅纪念馆','广州天河宜家',
'广州五仙观',
'广州Lavie拉维电影公馆',
'广州近代史博物馆',
'广州余荫山房 番禺区',
])
df.columns = ['location']
ak = 'pOSMq456AFQuZyYfTlCBGcB8GG2VakRm'
def get_result(x,ak):
"""
:param x: 传入一个字符串类型的地点
:return: ([坐标],类别,置信度)
"""
Post_url = "https://api.map.baidu.com/geocoding/v3/?address=" + x + f"&output=json&ak={ak}&callback=showLocation"
Post_data = {
'address' : x
}
se = requests.session()
Text = se.post(Post_url, data=Post_data).text.replace("'", '"').replace('/ ', '/')[27:-1]
jsonValue = json.loads(Text) # 转化为Json对象
if ("result" in jsonValue):
return (jsonValue['result']['location']['lng'],jsonValue['result']['location']['lat']),jsonValue['result']['level'],jsonValue['result']['confidence']
else: return ''
result = {
'name' :df['location'].values,
'position' : [],
'category' : [],
'confidence' : []
}
for value in df.values:
tmp = get_result(value[0],ak)
if tmp != '':
result['position'].append(tmp[0])
result['category'].append(tmp[1])
result['confidence'].append(tmp[2])
result
{'name': array(['广东工业大学(大学城校区)', '广州市鲁迅纪念馆', '广州天河宜家', '广州五仙观', '广州Lavie拉维电影公馆',
'广州近代史博物馆', '广州余荫山房 番禺区'], dtype=object),
'position': [(113.39959744237572, 23.045704807207507),
(113.2841059860486, 23.13014496993394),
(113.42238287179822, 23.111107776003106),
(113.26630839796859, 23.126907167141244),
(113.32622196190339, 23.101572988503353),
(113.28977420398412, 23.13464065626514),
(113.4019110989934, 23.017728378073617)],
'category': ['教育', '旅游景点', '餐饮', '旅游景点', '休闲娱乐', '旅游景点', '旅游景点'],
'confidence': [70, 50, 80, 50, 70, 50, 50]}
recoder = pd.DataFrame(result)
recoder
name | position | category | confidence | |
---|---|---|---|---|
0 | 广东工业大学(大学城校区) | (113.39959744237572, 23.045704807207507) | 教育 | 70 |
1 | 广州市鲁迅纪念馆 | (113.2841059860486, 23.13014496993394) | 旅游景点 | 50 |
2 | 广州天河宜家 | (113.42238287179822, 23.111107776003106) | 餐饮 | 80 |
3 | 广州五仙观 | (113.26630839796859, 23.126907167141244) | 旅游景点 | 50 |
4 | 广州Lavie拉维电影公馆 | (113.32622196190339, 23.101572988503353) | 休闲娱乐 | 70 |
5 | 广州近代史博物馆 | (113.28977420398412, 23.13464065626514) | 旅游景点 | 50 |
6 | 广州余荫山房 番禺区 | (113.4019110989934, 23.017728378073617) | 旅游景点 | 50 |
names=['序号','起点纬度','起点经度','终点纬度','终点经度']
dataList = [] # 储存获取的路线数据
akn=0 # 使用第几个ak
for i , name1 in enumerate(recoder['name']):
for j ,name2 in enumerate(recoder['name']):
if name1 == name2:
dataList.append([0,0,0,0,0,0,0])
continue
out_lat = recoder.at[i,'position'][1]
out_lng = recoder.at[i,'position'][0]
des_lat = recoder.at[j, 'position'][1]
des_lng = recoder.at[j, 'position'][0]
"""
# 获取驾车路径:常规路线规划(不考虑路况)
以下是可选参数
# tactics =10不走高速;=11常规路线;=12距离较短;=13距离较短
"""
url_drive = r"http://api.map.baidu.com/routematrix/v2/driving?output=json&origins={0},{1}&destinations={2},{3}&{4}&tactics=11&ak={4}".format(out_lat,out_lng,des_lat,des_lng,ak)
result_drive = json.loads(urlopen(url_drive).read()) # json转dict
status_drive = result_drive['status']
if status_drive == 0: # 状态码为0:无异常
distance_drive = round(result_drive['result'][0]['distance']['value'] / 1000,3) # 里程(k米)
timesec_drive = round(result_drive['result'][0]['duration']['value'] /60,2) # 耗时(分钟)
elif status_drive == 302 or status_drive == 210 or status_drive == 201: # 302:额度不足;210:IP验证未通过
distance_drive = timesec_drive = 'AK错误'
else:
distance_drive = timesec_drive = '请求错误'
"""
### 以下是乘车规划
可选参数
tac_bus = r'&tactics_incity=0'
# 市内公交换乘策略 可选,默认为0 0推荐;1少换乘;2少步行;3不坐地铁;4时间短;5地铁优先
city_bus = r'&tactics_intercity=0'
# 跨城公交换乘策略 可选,默认为0 0时间短;1出发早;2价格低;
city_type = r'&trans_type_intercity=0'
# 跨城交通方式策略 可选,默认为0 0火车优先;1飞机优先;2大巴优先;
"""
url_bus = r'http://api.map.baidu.com/direction/v2/transit?output=json&origin={0},{1}&destination={2},{3}&{4}&ak={4}'.format(out_lat,out_lng,des_lat,des_lng,ak)
result_bus = json.loads(urlopen(url_bus).read())
status_bus = result_bus['status']
if status_bus == 0:
rsls = result_bus['result']['routes']
if rsls == []: # 无方案时状态也为0,但只返回一个空list
distance_bus = timesec_bus = cost_bus = '无公交方案'
else:
distance_bus = round(result_bus['result']['routes'][0]['distance'] / 1000,3) # 乘车路线距离总长(km)
timesec_bus = round(result_bus['result']['routes'][0]['duration'] / 60,2) # 乘车时间(分钟)
cost_bus = result_bus['result']['routes'][0]['price'] # 乘车费用(元)
elif status_bus == 302 or status_bus == 210 or status_bus == 201:
distance_bus = timesec_bus = cost_bus = 'AK错误'
elif status_bus == 1001:
distance_bus = timesec_bus = cost_bus = '无公交方案'
else: # 其他类型状态码(服务器错误)
distance_bus = timesec_bus = cost_bus = '请求错误'
dataList.append([status_drive,distance_drive,timesec_drive,status_bus,distance_bus,timesec_bus,cost_bus])
计算两个坐标轴点的距离
例如:
from geopy.distance import geodesic
distance = geodesic((39.995304, 116.308264), (40.003304, 116.326759)).km
round(distance,2) 保留两位小数
dataList = np.array(dataList).reshape(len(recoder),len(recoder),-1)
'''【驾车状态, 自驾距离km,花费时间(分钟),推荐的公交状态,公交地铁距离 km,花费时间(分钟),金钱(元)'''
dataList_name = ['status_drive','distance_drive','timesec_drive','status_bus','distance_bus','timesec_bus','cost_bus']
dataList
array([[[ 0. , 0. , 0. , 0. , 0. , 0. , 0. ],
[ 0. , 27.548, 40.15 , 0. , 23.899, 67.03 , 6. ],
[ 0. , 18.95 , 32.88 , 0. , 13.49 , 37.17 , 5. ],
[ 0. , 27.542, 44.32 , 0. , 23.796, 72.62 , 6. ],
[ 0. , 19.801, 34.47 , 0. , 15.236, 42.08 , 5. ],
[ 0. , 26.529, 43.72 , 0. , 22.802, 64.42 , 6. ],
[ 0. , 15.492, 31.33 , 0. , 11.445, 52.15 , 5. ]],
[[ 0. , 26.815, 39.47 , 0. , 23.901, 68.03 , 6. ],
[ 0. , 0. , 0. , 0. , 0. , 0. , 0. ],
[ 0. , 15.521, 24.8 , 0. , 18.993, 50.32 , 5. ],
[ 0. , 2.164, 8.27 , 0. , 2.503, 23.43 , 3. ],
[ 0. , 9.285, 17.82 , 0. , 8.915, 39.63 , 2. ],
[ 0. , 1.229, 4.17 , 0. , 2.308, 22.25 , 2. ],
[ 0. , 33.633, 46.63 , 0. , 27.912, 122.25 , -1. ]],
[[ 0. , 17.501, 33.45 , 0. , 13.492, 38.17 , 5. ],
[ 0. , 16.072, 34.05 , 0. , 16.606, 44.97 , 5. ],
[ 0. , 0. , 0. , 0. , 0. , 0. , 0. ],
[ 0. , 17.769, 39.62 , 0. , 19.003, 54.43 , 5. ],
[ 0. , 14.477, 33.3 , 0. , 13.277, 30.68 , 4. ],
[ 0. , 15.053, 35.4 , 0. , 15.509, 42.35 , 5. ],
[ 0. , 24.319, 40.85 , 0. , 21.462, 70.03 , 8. ]],
[[ 0. , 28.996, 43.4 , 0. , 23.795, 73.62 , 6. ],
[ 0. , 2.776, 11.35 , 0. , 2.516, 23.1 , 1. ],
[ 0. , 17.702, 28.93 , 0. , 19.003, 54.43 , 5. ],
[ 0. , 0. , 0. , 0. , 0. , 0. , 0. ],
[ 0. , 11.466, 21.7 , 0. , 8.515, 45.77 , 2. ],
[ 0. , 3.06 , 12.75 , 0. , 3.582, 35.27 , 2. ],
[ 0. , 35.814, 51.15 , 0. , 41.005, 141.15 , 8. ]],
[[ 0. , 18.501, 34.62 , 0. , 15.235, 43.08 , 5. ],
[ 0. , 9.576, 25.33 , 0. , 10.04 , 47.1 , 2. ],
[ 0. , 13.024, 27.88 , 0. , 13.276, 30.68 , 4. ],
[ 0. , 10.918, 30.15 , 0. , 10.872, 54.63 , 2. ],
[ 0. , 0. , 0. , 0. , 0. , 0. , 0. ],
[ 0. , 9.687, 25.7 , 0. , 8.773, 29.92 , 3. ],
[ 0. , 25.319, 42.9 , 0. , 22.579, 69.72 , 6. ]],
[[ 0. , 25.766, 35.6 , 0. , 22.805, 65.42 , 6. ],
[ 0. , 1.591, 4.68 , 0. , 1.549, 23.33 , 2. ],
[ 0. , 14.472, 21.5 , 0. , 14.753, 60. , -1. ],
[ 0. , 3.614, 11.85 , 0. , 3.785, 34.93 , 2. ],
[ 0. , 8.236, 14.63 , 0. , 8.775, 30.92 , 3. ],
[ 0. , 0. , 0. , 0. , 0. , 0. , 0. ],
[ 0. , 32.584, 42.62 , 0. , 42.179, 157.82 , 8. ]],
[[ 0. , 18.927, 31.95 , 0. , 8.338, 53.65 , 4. ],
[ 0. , 30.291, 44.87 , 0. , 28.957, 123.95 , -1. ],
[ 0. , 21.689, 33.18 , 0. , 21.858, 68.93 , -1. ],
[ 0. , 26.861, 49.48 , 0. , 28.142, 112.42 , -1. ],
[ 0. , 22.922, 40.9 , 0. , 22.14 , 111.58 , 6. ],
[ 0. , 29.272, 47.62 , 0. , 29.316, 129.08 , -1. ],
[ 0. , 0. , 0. , 0. , 0. , 0. , 0. ]]])
# '''计算每两个城市间的distance 得到邻接矩阵'''
# from geopy.distance import geodesic
# adj_matrix = []
# for i , name1 in enumerate(recoder['name']):
# for j ,name2 in enumerate(recoder['name']):
# if name1 == name2:
# distance = np.inf
# adj_matrix.append(distance)
# else:
# distance = geodesic((recoder['position'][i][1],recoder['position'][i][0]),
# (recoder['position'][j][1],recoder['position'][j][0])).km # 转换为国外的维度和经度
#
# distance = round(distance,2) # 保留2位有效
# adj_matrix.append(distance)
# adj_matrix = np.array(adj_matrix).reshape(len(recoder),len(recoder))
#
#
# new_data = pd.DataFrame(adj_matrix)
# new_data.columns = recoder['name']
# new_data.insert(loc =0 ,column=' ',value=recoder['name'])
# new_data.to_excel('test.xlsx')
# new_data
将经纬度映射到 0-1 空间然后映射到画布空间
width,height
recoder
name | position | category | confidence | |
---|---|---|---|---|
0 | 广东工业大学(大学城校区) | (113.39959744237572, 23.045704807207507) | 教育 | 70 |
1 | 广州市鲁迅纪念馆 | (113.2841059860486, 23.13014496993394) | 旅游景点 | 50 |
2 | 广州天河宜家 | (113.42238287179822, 23.111107776003106) | 餐饮 | 80 |
3 | 广州五仙观 | (113.26630839796859, 23.126907167141244) | 旅游景点 | 50 |
4 | 广州Lavie拉维电影公馆 | (113.32622196190339, 23.101572988503353) | 休闲娱乐 | 70 |
5 | 广州近代史博物馆 | (113.28977420398412, 23.13464065626514) | 旅游景点 | 50 |
6 | 广州余荫山房 番禺区 | (113.4019110989934, 23.017728378073617) | 旅游景点 | 50 |
from pyecharts.charts import Geo
from pyecharts import options
from pyecharts.globals import GeoType
g = Geo().add_schema(maptype="广州")
for i in range(len(result['name'])):
g.add_coordinate(result['name'][i], result['position'][i][0], result['position'][i][1])
data_pair = [(result['name'][i],1)]
g.add('',data_pair, type_=GeoType.EFFECT_SCATTER, symbol_size=20)
g.set_series_opts(label_opts=options.LabelOpts(is_show=False))
g.set_global_opts(title_opts=options.TitleOpts(title="pyecharts地图标点测试"))
g.render_notebook()
'''
ALPHA:信息启发因子,值越大,则蚂蚁选择之前走过的路径可能性就越大
,值越小,则蚁群搜索范围就会减少,容易陷入局部最优
BETA:Beta值越大,蚁群越就容易选择局部较短路径,这时算法收敛速度会
加快,但是随机性不高,容易得到局部的相对最优
'''
(ALPHA, BETA, RHO, Q) = (1.0, 2.0, 0.5, 100.0)
# 城市数,蚁群
(city_num, ant_num) = (len(recoder),len(recoder))
'''可以优化的一点,分布采用真实分布,实现步骤,归一化,映射到0-1空间,再将经纬度,映射到画布空间的相对位置'''
abstract_position = []
for i ,value in enumerate(recoder['position']):
value = list(value)
abstract_position.append(value)
abstract_position = np.array(abstract_position)
# 归一化映射位置关系
abstract_position[:, 0] = (abstract_position[:, 0] - np.min(abstract_position[:, 0]))/(np.max(abstract_position[:, 0]) - np.min(abstract_position[:,
0])) * 500 + 200
abstract_position[:, 1] = 1000 - (abstract_position[:, 1] - np.min(abstract_position[:, 1]))/(np.max(abstract_position[:, 1]) - np.min(abstract_position[:,
1])) * 500 - 200 # + bias 偏置
abstract_position = np.ceil(abstract_position)
distance_x = [x[0] for x in abstract_position]
distance_y = [y[1] for y in abstract_position]
# 城市距离和信息素
distance_graph = [[0.0 for col in range(city_num)] for raw in range(city_num)]
pheromone_graph = [[1.0 for col in range(city_num)] for raw in range(city_num)]
# ----------- 蚂蚁 -----------
class Ant(object):
# 初始化
def __init__(self, ID):
self.ID = ID # ID
self.__clean_data() # 随机初始化出生点
# 初始数据
def __clean_data(self):
self.path = [] # 当前蚂蚁的路径
self.total_distance = 0.0 # 当前路径的总距离
self.move_count = 0 # 移动次数
self.current_city = -1 # 当前停留的城市
self.open_table_city = [True for i in range(city_num)] # 探索城市的状态
city_index = random.randint(0, city_num - 1) # 随机初始出生点
self.current_city = city_index
self.path.append(city_index)
self.open_table_city[city_index] = False
self.move_count = 1
# 选择下一个城市
def __choice_next_city(self):
next_city = -1
select_citys_prob = [0.0 for i in range(city_num)] # 存储去下个城市的概率
total_prob = 0.0
# 获取去下一个城市的概率
for i in range(city_num):
if self.open_table_city[i]:
try:
# 计算概率:与信息素浓度成正比,与距离成反比
select_citys_prob[i] = pow(pheromone_graph[self.current_city][i], ALPHA) * pow(
(1.0 / distance_graph[self.current_city][i]), BETA)
total_prob += select_citys_prob[i]
except ZeroDivisionError as e:
print('Ant ID: {ID}, current city: {current}, target city: {target}'.format(ID=self.ID,
current=self.current_city,
target=i))
sys.exit(1)
# 轮盘选择城市
if total_prob > 0.0:
# 产生一个随机概率,0.0-total_prob
temp_prob = random.uniform(0.0, total_prob)
for i in range(city_num):
if self.open_table_city[i]:
# 轮次相减
temp_prob -= select_citys_prob[i]
if temp_prob < 0.0:
next_city = i
break
# 未从概率产生,顺序选择一个未访问城市
# if next_city == -1:
# for i in range(city_num):
# if self.open_table_city[i]:
# next_city = i
# break
if (next_city == -1):
next_city = random.randint(0, city_num - 1)
while ((self.open_table_city[next_city]) == False): # if==False,说明已经遍历过了
next_city = random.randint(0, city_num - 1)
# 返回下一个城市序号
return next_city
# 计算路径总距离
def __cal_total_distance(self):
temp_distance = 0.0
for i in range(1, city_num):
start, end = self.path[i], self.path[i - 1]
temp_distance += distance_graph[start][end]
# 回路
end = self.path[0]
temp_distance += distance_graph[start][end]
self.total_distance = temp_distance
# 移动操作
def __move(self, next_city):
self.path.append(next_city)
self.open_table_city[next_city] = False
self.total_distance += distance_graph[self.current_city][next_city]
self.current_city = next_city
self.move_count += 1
# 搜索路径
def search_path(self):
# 初始化数据
self.__clean_data()
# 搜素路径,遍历完所有城市为止
while self.move_count < city_num:
# 移动到下一个城市
next_city = self.__choice_next_city()
self.__move(next_city)
# 计算路径总长度
self.__cal_total_distance()
# ----------- TSP问题 -----------
class TSP(object):
def __init__(self, root, width=1000, height=1000, n=city_num):
# 创建画布
self.root = root
self.width = width
self.height = height
# 城市数目初始化为city_num
self.n = n
# tkinter.Canvas
self.canvas = tkinter.Canvas(
root,
width=self.width,
height=self.height,
bg="#EBEBEB", # 背景白色
xscrollincrement=1,
yscrollincrement=1
)
self.canvas.pack(expand=tkinter.YES, fill=tkinter.BOTH)
self.title("TSP蚁群算法(n:初始化 e:开始搜索 s:停止搜索 q:退出程序)")
self.__r = 5
self.__lock = threading.RLock() # 线程锁
self.__bindEvents()
self.new()
# 计算地点之间的距离,也就是花费, 这里的度量默认采用了 地铁公交车的时间花费
'''['status_drive','distance_drive','timesec_drive','status_bus','distance_bus','timesec_bus','cost_bus']'''
for i,value0 in enumerate(dataList):
for j,value1 in enumerate(value0):
distance = value1[5]
distance_graph[i][j] = distance
# 按键响应程序
def __bindEvents(self):
self.root.bind("q", self.quite) # 退出程序
self.root.bind("n", self.new) # 初始化
self.root.bind("e", self.search_path) # 开始搜索
self.root.bind("s", self.stop) # 停止搜索
# 更改标题
def title(self, s):
self.root.title(s)
# 初始化
def new(self, evt=None):
# 停止线程
self.__lock.acquire()
self.__running = False
self.__lock.release()
self.clear() # 清除信息
self.nodes = [] # 节点坐标
self.nodes2 = [] # 节点对象
# 初始化城市节点
for i in range(self.n):
# 在画布上标定虚拟坐标
x = distance_x[i]
y = distance_y[i]
self.nodes.append((x, y))
# 生成节点椭圆,半径为self.__r
node = self.canvas.create_oval(x - self.__r,
y - self.__r, x + self.__r, y + self.__r,
fill="#ff0000", # 填充红色
outline="#000000", # 轮廓白色
tags="node",
)
self.nodes2.append(node)
# 显示坐标
self.canvas.create_text(x, y - 10, # 使用create_text方法在坐标(302,77)处绘制文字
text=f"{recoder['name'][i]}", # 所绘制文字的内容
fill='black' # 所绘制文字的颜色为灰色
)
# 顺序连接城市
# self.line(range(city_num))
# 初始城市之间的距离和信息素
for i in range(city_num):
for j in range(city_num):
pheromone_graph[i][j] = 1.0
self.ants = [Ant(ID) for ID in range(ant_num)] # 初始蚁群
self.best_ant = Ant(-1) # 初始最优解
self.best_ant.total_distance = 1 << 31 # 初始最大距离
self.iter = 1 # 初始化迭代次数
# 将节点按order顺序连线
def line(self, order):
# 删除原线
self.canvas.delete("line")
def line2(i1, i2):
p1, p2 = self.nodes[i1], self.nodes[i2]
self.canvas.create_line(p1, p2, fill="#000000",tags="line")
# # 显示线路花费时间
# x = int((p1[0]+p2[0])/2)
# y = int((p1[1]+p2[1])/2)
#
# self.canvas.create_text(x, y - 10, # 使用create_text方法在坐标(302,77)处绘制文字
# text=f"{}", # 所绘制文字的内容
# fill='black' # 所绘制文字的颜色为灰色
# )
return i2
# order[-1]为初始值
reduce(line2, order, order[-1])
# 清除画布
def clear(self):
for item in self.canvas.find_all():
self.canvas.delete(item)
# 退出程序
def quite(self, evt):
self.__lock.acquire()
self.__running = False
self.__lock.release()
self.root.destroy()
print(u"\n程序已退出...")
sys.exit()
# 停止搜索
def stop(self, evt):
self.__lock.acquire()
self.__running = False
self.__lock.release()
# 开始搜索
def search_path(self, evt=None):
# 开启线程
self.__lock.acquire()
self.__running = True
self.__lock.release()
while self.__running:
# 遍历每一只蚂蚁
for ant in self.ants:
# 搜索一条路径
ant.search_path()
# 与当前最优蚂蚁比较
if ant.total_distance < self.best_ant.total_distance:
# 更新最优解
self.best_ant = copy.deepcopy(ant)
# 更新信息素
self.__update_pheromone_gragh()
print(u"迭代次数:", self.iter, f"最佳{dataList_name[5]} (hours)", round(self.best_ant.total_distance / 60,2))
# 连线
self.line(self.best_ant.path)
# 设置标题
self.title("TSP蚁群算法(n:随机初始 e:开始搜索 s:停止搜索 q:退出程序) 迭代次数: %d" % self.iter)
# 更新画布
self.canvas.update()
self.iter += 1
# 更新信息素
def __update_pheromone_gragh(self):
# 获取每只蚂蚁在其路径上留下的信息素
temp_pheromone = [[0.0 for col in range(city_num)] for raw in range(city_num)]
for ant in self.ants:
for i in range(1, city_num):
start, end = ant.path[i - 1], ant.path[i]
# 在路径上的每两个相邻城市间留下信息素,与路径总距离反比
temp_pheromone[start][end] += Q / ant.total_distance
temp_pheromone[end][start] = temp_pheromone[start][end]
# 更新所有城市之间的信息素,旧信息素衰减加上新迭代信息素
for i in range(city_num):
for j in range(city_num):
pheromone_graph[i][j] = pheromone_graph[i][j] * RHO + temp_pheromone[i][j]
# 主循环
def mainloop(self):
self.root.mainloop()
print(u"""
--------------------------------------------------------
蚁群算法解决TPS问题程序
程序中按提示键盘继续操作
--------------------------------------------------------
""")
TSP(tkinter.Tk()).mainloop()
--------------------------------------------------------
蚁群算法解决TPS问题程序
程序中按提示键盘继续操作
--------------------------------------------------------
迭代次数: 1 最佳timesec_bus (hours) 5.04
迭代次数: 2 最佳timesec_bus (hours) 5.04
迭代次数: 3 最佳timesec_bus (hours) 4.94
迭代次数: 4 最佳timesec_bus (hours) 4.94
迭代次数: 5 最佳timesec_bus (hours) 4.94
迭代次数: 6 最佳timesec_bus (hours) 4.94
迭代次数: 7 最佳timesec_bus (hours) 4.94
迭代次数: 8 最佳timesec_bus (hours) 4.94
迭代次数: 9 最佳timesec_bus (hours) 4.94
迭代次数: 10 最佳timesec_bus (hours) 4.85
迭代次数: 11 最佳timesec_bus (hours) 4.85
迭代次数: 12 最佳timesec_bus (hours) 4.85
迭代次数: 13 最佳timesec_bus (hours) 4.85
迭代次数: 14 最佳timesec_bus (hours) 4.85
迭代次数: 15 最佳timesec_bus (hours) 4.85
迭代次数: 16 最佳timesec_bus (hours) 4.85
迭代次数: 17 最佳timesec_bus (hours) 4.85
迭代次数: 18 最佳timesec_bus (hours) 4.85
迭代次数: 19 最佳timesec_bus (hours) 4.84
迭代次数: 20 最佳timesec_bus (hours) 4.84
迭代次数: 21 最佳timesec_bus (hours) 4.84
迭代次数: 22 最佳timesec_bus (hours) 4.84
迭代次数: 23 最佳timesec_bus (hours) 4.84
迭代次数: 24 最佳timesec_bus (hours) 4.84
迭代次数: 25 最佳timesec_bus (hours) 4.84
迭代次数: 26 最佳timesec_bus (hours) 4.84
迭代次数: 27 最佳timesec_bus (hours) 4.84
迭代次数: 28 最佳timesec_bus (hours) 4.84
迭代次数: 29 最佳timesec_bus (hours) 4.84
迭代次数: 30 最佳timesec_bus (hours) 4.84
迭代次数: 31 最佳timesec_bus (hours) 4.84
迭代次数: 32 最佳timesec_bus (hours) 4.84
迭代次数: 33 最佳timesec_bus (hours) 4.84
迭代次数: 34 最佳timesec_bus (hours) 4.84
迭代次数: 35 最佳timesec_bus (hours) 4.84
迭代次数: 36 最佳timesec_bus (hours) 4.84
迭代次数: 37 最佳timesec_bus (hours) 4.84
迭代次数: 38 最佳timesec_bus (hours) 4.84
迭代次数: 39 最佳timesec_bus (hours) 4.84
迭代次数: 40 最佳timesec_bus (hours) 4.84
迭代次数: 41 最佳timesec_bus (hours) 4.84
迭代次数: 42 最佳timesec_bus (hours) 4.83
迭代次数: 43 最佳timesec_bus (hours) 4.83
迭代次数: 44 最佳timesec_bus (hours) 4.83
迭代次数: 45 最佳timesec_bus (hours) 4.83
迭代次数: 46 最佳timesec_bus (hours) 4.83
迭代次数: 47 最佳timesec_bus (hours) 4.83
迭代次数: 48 最佳timesec_bus (hours) 4.83
迭代次数: 49 最佳timesec_bus (hours) 4.83
迭代次数: 50 最佳timesec_bus (hours) 4.83
迭代次数: 51 最佳timesec_bus (hours) 4.83
迭代次数: 52 最佳timesec_bus (hours) 4.83
迭代次数: 53 最佳timesec_bus (hours) 4.83
迭代次数: 54 最佳timesec_bus (hours) 4.83
迭代次数: 55 最佳timesec_bus (hours) 4.83
迭代次数: 56 最佳timesec_bus (hours) 4.83
迭代次数: 57 最佳timesec_bus (hours) 4.83
迭代次数: 58 最佳timesec_bus (hours) 4.83
迭代次数: 59 最佳timesec_bus (hours) 4.83
迭代次数: 60 最佳timesec_bus (hours) 4.83
迭代次数: 61 最佳timesec_bus (hours) 4.83
迭代次数: 62 最佳timesec_bus (hours) 4.83
引用文献
CSDN 百度api获取个人ak
蚁群算法的实现