您的位置:首页 > 编程语言 > Python开发

Python pandas 实现图论算法 使用堆加速prim算法 dijkstra floyd

2016-12-09 12:24 591 查看
gitub地址

prim 最小生成树

dijkstra算法 单源最短路

floyd算法 全源最短路

gitub地址

prim 最小生成树

def prim_heap(graph):
r"""
time complexity O(E * log2 E)
using heap to optimtiz algorithm
Parameters:
dataframe
Returns
--------
: a list of MST
list,[()]
"""
n = len(graph )
# vertexes = [u"北门"]
vertexes = [graph.index[0]]

edges = {}
total_v = set(graph.index) #{}

def get_heap(unicode_v):
"""return: (weight, target_poi, from_poi)
"""
return [ (w, v, unicode_v)
for w,v in zip(graph[unicode_v], graph[unicode_v].index)
if 0 < w < utils.INF and v != unicode_v]

heap = get_heap(list(vertexes)[0])
heapq.heapify(heap)
# print heapq.nlargest(1, heap, key = lambda x:x[1])
edge_list = []
while len(vertexes) != n:
# get min weight edge in graph in <u,v>, u in vertexes and v is not
# next_w_v = heapq.nsmallest(1, heap, key = lambda x:x[1]) #[(w,v)]
next_w_v = heapq.heappop(heap) #pop it. the min edge use once only
if next_w_v[1] in vertexes:
continue
vertexes.append(next_w_v[1])
edge_list.append( (next_w_v[2], next_w_v[1]) )
for w,v,f in get_heap(next_w_v[1]):
if v not in vertexes:
heapq.heappush(heap, (w,v,f) )
return edge_list


dijkstra算法 单源最短路

def dijkstra(graph, start = None, end = None):
r"""get 1 point to others points' shortest path
time complexity O(n^2)
Parameters:
-----------
DataFrame, str(unicode), str(unicode)
Returns:
---------------
distance from start to every point; the path from start point to others
dist = {
pointName:[ distance = graph[start] (dataframe), isVisted = 0, path = [] ]
}
or
distance:number, path:list []
reference
----------
.. [1] tutorial http://stackoverflow.com/questions/22897209/dijkstras-algorithm-in-python .. [2] http://www.cnblogs.com/biyeymyhjob/archive/2012/07/31/2615833.html """

# dist:distance from start point to others
# dist = {
#   pointName:( distance = graph[start] (dataframe), isVisted = 0, path = [] )
# }
# print(graph.columns.values)
if (start not in graph.columns.values) or (end not in graph.columns.values):
print("wrong input: plz input a start point exist in current graph")
return None, None
if start == None :
print("wrong input: plz input a start point. use random by default")
start = graph.columns.values[0]
dis = zip(graph[start].index, graph[start])
dist = {
k:[v, 0, []]
for k,v in dis
}
for i in range(len(graph.index) - 1):
mindis = utils.INF
add_point = ""
for k,v in dist.items():
if v[1] == 0 and v[0] < mindis and v[0] > 0:
mindis = v[0]
add_point = k
dist[add_point][1] = 1 # mark as visited
for column_df_index in graph[add_point].index:

if (graph.at[add_point, column_df_index] < utils.INF) and (dist[column_df_index][1] == 0):
# print( (str(graph.at[add_point, column_df_index] + dist[add_point][0]) ) + "\t" + str(dist[column_df_index][0]))
if dist[column_df_index][0] > graph.at[add_point, column_df_index] + dist[add_point][0]:
dist[column_df_index][0] =  graph.at[add_point, column_df_index] + dist[add_point][0]
dist[column_df_index][2].extend(dist[add_point][2])
dist[column_df_index][2].append(add_point)
# print(len(dist[column_df_index][2]))

path = []
for k,v in dist.items():
temp_str = []
temp_str.extend([x for x in v[2]])
temp_str.extend([v[0], k])
path.append(temp_str)

if end == None:
return dist, path
else:
return dist[end][0], dist[end][2]


floyd算法 全源最短路

def floyd(graph):
r"""
let all points' edges to simplified
Floyd-Warshall algorithm O(n^3)
Parameters
------
graph: pd.dataframe
Returns
-------
result:pd.dataframe
"""
result = graph.copy()
points_list = result.index.tolist()
point_dict = dict(zip([i for i in range(len(points_list))], points_list))

result_matrix = result.as_matrix()

for k in range(len(result_matrix)):
for i in range(len(result_matrix)):
for j in range(len(result_matrix)):
if(result_matrix[i][k] < utils.INF and result_matrix[k][j] < utils.INF and result_matrix[i][j] > result_matrix[i][k] + result_matrix[k][j]):
# for digraph
result.set_value(point_dict[i], point_dict[j], result_matrix[i][k] + result_matrix[k][j])
result.set_value(point_dict[j], point_dict[i], result_matrix[i][k] + result_matrix[k][j])

result_matrix[i][j] = result_matrix[i][k] + result_matrix[k][j]
return result
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息