需要引入geopy库

pip install geopy 安装即可

import requests
from bs4 import BeautifulSoup
import pandas as pd
import json
import os
from tqdm import tqdm
from collections import defaultdict
import pickle
import itertools
from geopy.distance import geodesic
#爬取郑州地铁数据
def spyder():
#获得郑州的地铁信息
print('正在爬取郑州地铁信息...')
url='http://zz.bendibao.com/ditie/linemap.shtml'
user_agent='Opera/9.80 (Macintosh; Intel Mac OS X 10.6.8; U; en) Presto/2.8.131 Version/11.11'
headers = {'User-Agent': user_agent}
r = requests.get(url, headers=headers)
r.encoding = r.apparent_encoding
soup = BeautifulSoup(r.text, 'lxml')
all_info = soup.find_all('div', class_='line-list')
df=pd.DataFrame(columns=['name','site'])
for info in tqdm(all_info):
title=info.find_all('div',class_='wrap')[0].get_text().split()[0].replace('线路图','')
station_all=info.find_all('a',class_='link')
for station in station_all:
station_name=station.get_text()
longitude,latitude=get_location(station_name,'郑州')
temp={'name':station_name,'site':title,'longitude':longitude,'latitude':latitude}
df =df.append(temp,ignore_index=True)
df.to_excel('./subway.xlsx',index=False)
def get_location(keyword,city):
#获得经纬度
user_agent='Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_8; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50'
headers = {'User-Agent': user_agent}
url='http://restapi.amap.com/v3/place/text?key='+keynum+'&keywords='+keyword+'&types=&city='+city+'&children=1&offset=1&page=1&extensions=all'
data = requests.get(url, headers=headers)
data.encoding='utf-8'
data=json.loads(data.text)
result=data['pois'][0]['location'].split(',')
return result[0],result[1]
def compute_distance(longitude1,latitude1,longitude2,latitude2):
#计算2点之间的距离
user_agent='Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_8; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50'
headers = {'User-Agent': user_agent}
url='http://restapi.amap.com/v3/distance?key='+keynum+'&origins='+str(longitude1)+','+str(latitude1)+'&destination='+str(longitude2)+','+str(latitude2)+'&type=1'
data=requests.get(url,headers=headers)
data.encoding='utf-8'
data=json.loads(data.text)
result=data['results'][0]['distance']
return result
def get_graph():
print('正在创建pickle文件...')
data=pd.read_excel('./subway.xlsx')
#创建点之间的距离
graph=defaultdict(dict)
for i in range(data.shape[0]):
site1=data.iloc[i]['site']
if i<data.shape[0]-1:
site2=data.iloc[i+1]['site']
#如果是共一条线
if site1==site2:
longitude1,latitude1=data.iloc[i]['longitude'],data.iloc[i]['latitude']
longitude2,latitude2=data.iloc[i+1]['longitude'],data.iloc[i+1]['latitude']
name1=data.iloc[i]['name']
name2=data.iloc[i+1]['name']
distance=compute_distance(longitude1,latitude1,longitude2,latitude2)
graph[name1][name2]=distance
graph[name2][name1]=distance
output=open('graph.pkl','wb')
pickle.dump(graph,output) #找到开销最小的节点
def find_lowest_cost_node(costs,processed):
#初始化数据
lowest_cost=float('inf') #初始化最小值为无穷大
lowest_cost_node=None
#遍历所有节点
for node in costs:
#如果该节点没有被处理
if not node in processed:
#如果当前的节点的开销比已经存在的开销小,那么久更新该节点为最小开销的节点
if costs[node]<lowest_cost:
lowest_cost=costs[node]
lowest_cost_node=node
return lowest_cost_node #找到最短路径
def find_shortest_path(start,end,parents):
# print(end)
node=end
# print(parents)
shortest_path=[end]
# print(parents[node])
#最终的根节点为start
while parents[node] !=start:
shortest_path.append(parents[node])
node=parents[node]
shortest_path.append(start)
return shortest_path
#计算图中从start到end的最短路径
def dijkstra(start,end,graph,costs,processed,parents):
#查询到目前开销最小的节点
node=find_lowest_cost_node(costs,processed)
#使用找到的开销最小节点,计算它的邻居是否可以通过它进行更新
#如果所有的节点都在processed里面 就结束
while node is not None:
#获取节点的cost
cost=costs[node] #cost 是从node 到start的距离
#获取节点的邻居
neighbors=graph[node]
#遍历所有的邻居,看是否可以通过它进行更新
for neighbor in neighbors.keys():
#计算邻居到当前节点+当前节点的开销
new_cost=cost+float(neighbors[neighbor])
if neighbor not in costs or new_cost<costs[neighbor]:
costs[neighbor]=new_cost
#经过node到邻居的节点,cost最少
parents[neighbor]=node
#将当前节点标记为已处理
processed.append(node)
#下一步继续找U中最短距离的节点 costs=U,processed=S
node=find_lowest_cost_node(costs,processed) #循环完成 说明所有节点已经处理完
shortest_path=find_shortest_path(start,end,parents)
shortest_path.reverse()
return shortest_path def subway_line(start,end):
file=open('graph.pkl','rb')
graph=pickle.load(file)
#创建点之间的距离
#现在我们有了各个地铁站之间的距离存储在graph
#创建节点的开销表,cost是指从start到该节点的距离
costs={}
parents={}
parents[end]=None
for node in graph[start].keys():
costs[node]=float(graph[start][node])
parents[node]=start
#终点到起始点距离为无穷大
costs[end]=float('inf')
#记录处理过的节点list
processed=[]
# print(parents)
shortest_path=dijkstra(start,end,graph,costs,processed,parents)
return shortest_path def get_nearest_subway(data,longitude1,latitude1):
#找最近的地铁站
longitude1=float(longitude1)
latitude1=float(latitude1)
distance=float('inf')
nearest_subway=None
for i in range(data.shape[0]):
site1=data.iloc[i]['name']
longitude=float(data.iloc[i]['longitude'])
latitude=float(data.iloc[i]['latitude'])
temp=geodesic((latitude1,longitude1), (latitude,longitude)).m
if temp<distance:
distance=temp
nearest_subway=site1
return nearest_subway def main(site1,site2):
if not os.path.exists('./subway.xlsx'):
spyder()
if not os.path.exists('./graph.pkl'):
get_graph()
longitude1,latitude1=get_location(site1,'郑州')
longitude2,latitude2=get_location(site2,'郑州')
data=pd.read_excel('./subway.xlsx')
#求最近的地铁站
start=get_nearest_subway(data,longitude1,latitude1)
end=get_nearest_subway(data,longitude2,latitude2)
shortest_path=subway_line(start,end)
if site1 !=start:
shortest_path.insert(0,site1)
if site2 !=end:
shortest_path.append(site2)
print('路线规划为:','-->'.join(shortest_path))
if __name__ == '__main__':
global keynum
keynum='706594012b3c9c7ce3e46ac2a04057e1' #key
main('郑州大学','中原福塔')

效果展示:

基于Dijkstra算法的郑州地铁路径规划的更多相关文章

  1. Dijkstra算法_北京地铁换乘_android实现-附带源码.apk

    Dijkstra算法_北京地铁换乘_android实现   android 2.2+ 源码下载    apk下载 直接上图片 如下: Dijkstra(迪杰斯特拉)算法是典型的最短路径路由算法,用于计 ...

  2. 基于dijkstra算法求地铁站最短路径以及打印出所有的路径

    拓展dijkstra算法,实现利用vector存储多条路径: #include <iostream> #include <vector> #include <stack& ...

  3. [最短路径问题]Dijkstra算法(含还原具体路径)

    前言 在本篇文章中,我将介绍 Dijkstra 算法解决 单源最短路径问题 ,同时还包含了具体路径的还原.以下是我自己的全部学习过程与思考,参考书籍为 <数据结构>(C++语言版) 邓俊辉 ...

  4. AI贪吃蛇前瞻——基于Dijkstra算法的最短路径问题

    在贪吃蛇流程结构优化之后,我又不满足于亲自操刀控制这条蠢蠢的蛇,干脆就让它升级成AI,我来看程序自己玩,哈哈. 一.Dijkstra算法原理 作为一种广为人知的单源最短路径算法,Dijkstra用于求 ...

  5. 山东省第七届ACM竞赛 C题 Proxy (Dijkstra算法,单源路径最短问题)

    题意:给定0-n+1个点,和m条边,让你找到一条从0到n+1的最短路,输出与0相连的结点... 析:很明显么,是Dijkstra算法,不过特殊的是要输出与0相连的边,所以我们倒着搜,也是从n+1找到0 ...

  6. 全局路径规划算法Dijkstra(迪杰斯特拉算法)- matlab

    参考博客链接:https://www.cnblogs.com/kex1n/p/4178782.html Dijkstra是常用的全局路径规划算法,其本质上是一个最短路径寻优算法.算法的详细介绍参考上述 ...

  7. DWA局部路径规划算法论文阅读:The Dynamic Window Approach to Collision Avoidance。

    DWA(动态窗口)算法是用于局部路径规划的算法,已经在ROS中实现,在move_base堆栈中:http://wiki.ros.org/dwa_local_planner DWA算法第一次提出应该是1 ...

  8. move_base的全局路径规划代码研究

    algorithmn parameter code 主要是以下三个函数 计算所有的可行点 怎么计算一个点的可行点 从可行点中计算路径path todo algorithmn 算法的解释 Dijkstr ...

  9. 『算法设计_伪代码』贪心算法_最短路径Dijkstra算法

    Dijkstra算法实际上是一个贪婪算法(Greedy algorithm).因为该算法总是试图优先访问每一步循环中距离起始点最近的下一个结点.Dijkstra算法的过程如下图所示. 初始化 给定图中 ...

  10. 基于谷歌地图的Dijkstra算法水路路径规划

    最终效果图如下: 还是图.邻接表,可以模拟出几个对象=>节点.边.路径.三个类分别如下: Node 节点: using System; using System.Collections.Gene ...

随机推荐

  1. 記錄一下oracle数据库系统的comment數據字典(轉載)

    一.comment是oracle数据库系统的关键字,所以不能用来命名表明或字段名 二.comment关键字用于对表,字段添加注释,有利于用户对表结构以及数据库对象含义的理解. 三.用户可以通过数据字典 ...

  2. 解决 django channel: zadd() got an unexpected keyword argument 'daphne.response.HzSXMUhzYL!QSfUgrDObf'

    在stackoverflow上找到答案 If you are using Redis version 3.0 or above, it will not work with channels vers ...

  3. oracle 高级队列

    转载:http://www.idevelopment.info/data/Oracle/DBA_tips/Advanced_Queuing/AQ_2.shtml Overview This artic ...

  4. Python学习笔记组织文件之将一个文件夹备份到一个zip文件

    随笔记录方便自己和同路人查阅. #------------------------------------------------我是可耻的分割线--------------------------- ...

  5. HDLbits——Lfsr5

    Build this LFSR. The reset should reset the LFSR to 1 module top_module( input clk, input reset, // ...

  6. Rsync已过时?替代文件同步软件了解一下

    随着企业结构分散化的不断扩大,企业内部和企业间的信息互动更加频繁.越来越多的企业要求内部各种业务数据在服务器.数据中心甚至云上能够有实时的同步留存.所以,企业需要文件同步软件,通过在两个或更多设备之间 ...

  7. vue 报错Uncaught (in promise) cancel

    解决:.catch()不能省略(因为取消操作时,无法捕获) .then(res => {...}) .catch(()=>{});(then之后把catch加上)

  8. iOS开发 网络学习(4)HTTPS

    一.HTTPS简介 HTTPS : Hyper Text Transfer Protocol over Secure Socket Layer,是以安全为目标的HTTP通道,简单讲是HTTP的安全版. ...

  9. iOS开发之定时器和tableview滑动阻塞问题

    NSTimer *timer = [[NSTimer alloc]initWithFireDate:[NSDate distantPast] interval:1 target:self select ...

  10. python import导入失败 相对路径 绝对路径

    首先我们有这样一个目录结构 经过我无数次的调试,我发现从test3调用spider以及downloadss文件可以直接import调用 但是从外部的app.py文件调用,spider.py文件死活调用 ...