维特比算法说白了就是动态规划实现最短路径,只要知道“动态规划可以降低复杂度”这一点就能轻松理解维特比算法
维特比算法是一个特殊但应用最广的动态规划算法,利用动态规划,可以解决任何一个图中的最短路径问题。而维特比算法是针对一个特殊的图——篱笆网络的有向图(Lattice )的最短路径问题而提出的。 它之所以重要,是因为凡是使用隐含马尔可夫模型(Hidden Markov Model,HMM)描述的问题都可以用它来解码,包括今天的数字通信、语音识别、机器翻译、拼音转汉字、分词等。——《数学之美》 ps 多处摘录此书,不再赘述。
篱笆网络有向图的特点是同一列节点有多个,并且和上一列节点交错地连接起来。同一列节点代表同一个时间点上不同的状态的并列,大概因为这种一列一列整齐的节点和交错的边很像篱笆而得名。
假设上图每一列分别有n1……nn个节点,如果不使用动态的话,那么计算复杂度就是O(n1*n2……nn)。
而维特比算法的精髓就是,既然知道到第i列所有节点Xi{j=123…}的最短路径,那么到第i+1列节点的最短路径就等于到第i列j个节点的最短路径+第i列j个节点到第i+1列各个节点的距离的最小值。
这是一句大白话,所谓中文伪码。
分析一下复杂度,假设整个篱笆有向图中每一列节点最多有D个(也就是图的宽度为D),并且图一共有N列,那么,每次计算至多计算D*D次(从i列的D个节点中挑一个计算到i+1列D个节点的距离)。至多计算N次。那么复杂度骤减为O(ND2),远远小于穷举O(DN)。
Ⅱ 求助python的最短路径问题
这是一个深州前度优先搜索算法(Deepth First Search, DFS)
算法核心是不断递归,直到找到目标,入队一种可能方案,return返回上一递归,再次尝试以当前点开始计算有没有其他方案,如有则继续递归并入队,如没有则再次return
简单来说就是这样的结构:
def dfs(position, value):
# position 传参位置,value 传参到现在的计算结果
if 到达目标:
判断value是否比最短路径短
return value
else:
for x in position的所有可能下一路径:
if x在路径列表中:
# 不能有重复路径,变成回环
continue
else:
获取路径x的值
改变position
入告迹档队 dfs(new_position, value+x
这个代码用的是袜乱字典存储每个点可到达的点以及路程
然后深度优先搜索
不懂再追问
Ⅲ 如何用python在arcgis中编写程序,求两点的最短路径
你是想学PYTHON编程还是只是想只得到这个PYTHON文件。可以给你提供一条简洁的途径用modelbuilder来实现,将多个SHP文件拖入进去,再把MERGE工具拖进去,双击modelbuilder中的merge工具框设置,再双击output dataset框设置输出。然后将这些shp文件用倒数第二个按钮添加链接的功能将他们一个个与merge工具框链接起来。最后点击model-export-to srcipt-python 就会输出一个python文件,可以用记事本打开查看里面的代码。
Ⅳ 如何使用QGIS里面的python编程求最优路线
题主:
你的问题描述不是很详尽。
比如,你所说的最短路径,是直线还是沿道路的最短路径。如果是后者这个稍微麻烦些,并需要补充路网数据。如是直线距离最短,那么,你所需求的是以最短路径走访完所有农户(以居委会为起点),还是每户至居委会的距离最短(两点间直线距离)。还有就是GIS文件的属性表和你的EXCEL表格的关系...
所以,如你题中所说,建议你现在做的有以下几件事:
①明确要目标到底是什么,就如上面所说的一样;
②对于每一户(包括居委会),你还需获取其坐标(X/Y),这个在GIS软件中易获取;
③将excel数据连接至属性表中。
最后,你这个项目要解决的问题有Dijkstra、Floyd、A*等算法可用。但是具体用哪一种还需根据问题进行优选...
希望对你有所帮助!!!
Ⅳ python 的 networkx 的中有没有 函数 可以直接取出与 某一个点(node)所相连的所有边的个数
path=nx.all_pairs_shortest_path(G) #调用多源最短路径算法,计算图G所有节点间的磨档最短路径
print path[0][2] #输出节点0、2之间的最短路径瞎唤乱序列:链悉 [0, 1, 2]
Ⅵ Python数据分析在数学建模中的应用汇总(持续更新中!)
1、Numpy常用方法使用大全(超详细)
1、Series和DataFrame简单入门
2、Pandas操作CSV文件的读写
3、Pandas处理DataFrame,Series进行作图
1、Matplotlib绘图之属性设置
2、Matplotlib绘制误差条形图、饼图、等高线图、3D柱形图
1、层次分析法(AHP)——算数平均值法、几何平均值法、特征值法(Python实现,超详细注释)
2、Python实现TOPSIS分析法(优劣解距离法)
3、Python实现线性插值和三次样条插值
4、Python实现线性函数的拟合算法
5、Python实现统计描述以及计算皮尔逊相关系数
6、Python实现迪杰斯特拉算法和贝尔曼福特算法求解最短路径
Ⅶ 如何用python实现《多社交网络的影响力最大化问题分析》中的算法
经过一周,现已初步完成,其中多出代码不够美观以及效率不高,还请指点
# _*_ coding:utf-8 _*_
# ==================================================================================
#
# Description: Influence Maximization on Multiple Social Networks
#
# ==================================================================================
import matplotlib.pyplot as plt
import networkx as nx
import heapq
#总图
G = nx.DiGraph()
def load_graph(file):
'''
加载文件为列表格式,并得到G,画出图结构
'''
#将总列表设成全局格式
global gllist
#迭代文件中每个元素
with open(file) as f:
lines = f.readlines()
mylist = [line.strip().split() for line in lines]
gllist = []
#将字符串型转换为整型
for i in mylist:
gllist.append(i[:-2]+map(lambda x: float(x), i[-2:]))
print '初始全局列表:'
print gllist
drawlist=[]
#提取二维列表mylist每行前三个元素,赋给新的列表drawlist
for i in range(len(mylist)):
drawlist.append([])
for j in range(3):
drawlist[i].append(mylist[i][j])
#将列表drawlist加载为有向加权图
G.add_weighted_edges_from(drawlist)
nx.draw(G, with_labels=True, width=1, node_color='y', edge_color='b')
plt.show()
print 'G图中所有节点:',G.nodes()
print 'G图中所有边:',G.edges()
print '\n'
def get_self_node(gllist, target=None):
'''
获取目标节点的自传播节点,返回selflist并包含目标节点
'''
#初始化自传播节点列表
selflist = [target]
#存放已传播节点列表
haslist = []
flag = 0
while (flag != 0):
flag = 0
for target in selflist:
if target not in haslist:
for i in range(len(gllist)):
#判断二维列表中,每行第三个元素是否为1,若为1,则为自传播节点
if ((gllist[i][0] == target)or(gllist[i][1]==target))and(gllist[i][3]==1.0):
if gllist[i][0] == target:
if gllist[i][1] not in haslist:
selflist.append(gllist[i][1])
haslist.append(gllist[i][1])
flag += 1
else:
if gllist[i][0] not in haslist:
selflist.append(gllist[i][0])
haslist.append(gllist[i][0])
flag += 1
#去除重复元素
haslist = set(haslist)
selflist = set(selflist)
#去除重复元素
selflist = set(selflist)
return selflist
def longest_path(gllist,source=None,target=None):
'''
获取起始点到实体的最大路径集合,返回为longestpath列表
'''
longestpath = []
newlist = []
for i in range(len(gllist)):
newlist.append([])
for j in range(3):
newlist[i].append(gllist[i][j])
#构建图结构
G1 = nx.DiGraph()
#添加带权有向边
G1.add_weighted_edges_from(newlist)
#获取目标节点的所有自传播街边,并存入selflist中
selflist = get_self_node(gllist, target)
max_path = 0
val_path = 1
#获取初始节点到目标节点及目标节点的自传播节点的最大路径
for v in selflist:
if v != source:
#遍历两点之间所有路径,并进行比对
for path in nx.all_simple_paths(G1,source=source,target=v):
#判断路径后两个元素是否为相同实体(如:b1->b2)
if is_self_transmit_node(path[-2], v) == 0:
for i in range(0, len(path)-1):
val_path *= G1.get_edge_data(path[i], path[i+1])['weight']
if max_path < val_path:
max_path = val_path
val_path = 1
#若目标节点为起始节点则直接跳出
else: continue ############ 有待商榷 ##############
longestpath.append(max_path)
#返回初始节点到实体的最大路径
return longestpath
def is_self_transmit_node(u, v):
'''
判断目标节点不为起始节点的自传播点
'''
flag = 0
#获得起始节点的所有自传播点
selflist = get_self_node(gllist, v)
for x in selflist:
if u == x:
flag = 1
return flag
def single_strong_infl(longestpath):
'''
计算起始点到实体的传播概率(影响强度),返回影响强度stronginfl
'''
temp = 1
for x in longestpath:
temp *= 1-x
stronginfl = 1-temp
return stronginfl
def all_strong_infl(G):
'''
获得每个节点对实体的影响概率
'''
allstrong = [] #初始化所有节点的加权影响范围列表
gnodes = [] #初始化节点列表
tempnodes = [] #初始化临时节点列表
gnodes = G.nodes()
for u in gnodes:
strong = 0 #存储初始节点对每个实体的影响范围加权,初始化为0
#重置临时节点列表
tempnodes = G.nodes()
for v in tempnodes:
#非自身节点
if u != v:
#判断目标节点不为起始节点的自传播点
if is_self_transmit_node(v, u) == 0:
#获取起始节点到实体间最大加权路径,并存入longestpath
longestpath = longest_path(gllist, u, v)
#去除已遍历目标节点的所有自传播节点
renode = get_self_node(gllist, v)
for x in renode:
if x != v:
tempnodes.remove(x)
#计算起始节点到实体间传播概率(影响强度)
stronginfl = single_strong_infl(longestpath)
strong += stronginfl
#添加单个节点到所有实体的加权影响范围
allstrong.append([u, round(strong, 2)])
#返回每个节点到所有实体的加权影响范围
return allstrong
#output allstrong : [['a1', 2.48], ['a2', 1.6880000000000002], ['b1', 0.7], ['b2', 0], ['c1', 0], ['d2', 0.6]]
def uS_e_uppergain(u, ev, S):
'''
获取节点u在集合S的基础上对实体ev的影响增益, 传入候选节点,上界gain(u|S, ev)
'''
#获取目前实体的所有自传播节点
selflist = get_self_node(gllist, ev)
stronglist = []
#遍历自传遍节点
for v in selflist:
'''
判断节点v是否存在种子集合S中
其中v为单个节点,如v(ev, Gi)
S为种子节点集合,如['a1','a2','b1','b2','c1','d2']
'''
if v in S:
ppSv = 1
else:
longestpath = []
#遍历种子集合
for s in S:
#初始化路径权值与最大路径权值
val_path = 1
max_path = 0
#遍历两点之间所有路径,并进行比对
for path in nx.all_simple_paths(G,source=s,target=v):
#判断路径后两个元素是否为相同实体(如:b1->b2)
if is_self_transmit_node(path[-2], v) == 0:
for i in range(0, len(path)-1):
val_path *= G.get_edge_data(path[i], path[i+1])['weight']
if max_path < val_path:
max_path = val_path
#重置路径权值为1
val_path = 1
#将最大加权路径存入longestpath列表
longestpath.append(max_path)
#得到上界pp(S,v)的影响概率,上界pp(S,v)
ppSv = single_strong_infl(longestpath)
stronglist.append(ppSv)
#得到上界pp(S,ev)的影响概率,上界pp(S,ev)
ppSev = single_strong_infl(stronglist)
#获取pp(u,ev)
ppuev = single_strong_infl(longest_path(gllist, u, ev))
#计算上界gain(u|S,ev)
uSevgain = (1 - ppSev) * ppuev
return uSevgain
def uppergain(u, emu, ems, S):
'''
在已有种子集合S的基础上,求得节点u的影响增益上界,
其中传进参数ems为二维列表,如[['a1',2.48],['a2',1.688]],S则为['a1','a2']
'''
uSgain = 0.0
#遍历emu得到列表形式,得到如['a1',2.48]形式
for ev in emu:
#判断节点是否存在种子集合中
if ev[0] in S:
uSgain += uS_e_uppergain(u, ev[0], S)
else:
uSgain += ev[1]
#返回上界gain(u|S)
return uSgain
def bound_base_imms(G, k):
'''
完全使用影响增益上界的方式选择top-k个种子节点的过程
'''
#初始化emu,H,初始化ems=空集,S=空集
Htemp = []
Htemp = all_strong_infl(G)
H = []
#遍历Htemp=[['a1',2.48],['a2',1.688]],得到如['a1',2.48]形式
for x in Htemp:
#逐个获取二维列表中每一行,形式为['a1',2.48,0]
H.append([x[0],x[1],0])
emu = []
emu = all_strong_infl(G)
ems = []
S = []
for i in range(k):
#提取堆顶元素,tnode的形式为['a1',2.48,0]
tnode = heapq.nlargest(1, H, key=lambda x: x[1])
#将[['b2', 3.1, 0]]格式改为['b2', 3.1, 0]格式
tnode = sum(tnode, [])
while (tnode[2] != i):
gain = 0.0
#获取节点u的影响增益上界
gain = uppergain(tnode, emu, ems, S)
#赋值影响范围
tnode[1] = gain
#修改status
tnode[2] = i
#对堆进行排序
H = heapq.nlargest(len(H), H, key=lambda x: x[1])
#获取堆顶元素
tnode = heapq.nlargest(1, H, key=lambda x: x[1])
tnode = sum(tnode, [])
#添加node到种子集合
S.append([tnode[0]])
#更新ems,添加新节点及节点对每个实体的影响范围加权
ems.append([tnode[0], tnode[1]])
#删除堆顶元素
H.remove(tnode)
print ems
return sum(S, [])
if __name__=='__main__':
#大小为k的种子集合S
k = 60
#加载文件数据,得到图G和初始列表gllist
load_graph('test.txt')
#完全使用影响增益上界值的计算过程函数,打印种子集合S
print '种子集合:',bound_base_imms(G, k)
test.txt
a1 b1 0.2 0
a1 c1 0.8 0
a2 b2 0.4 0
a2 d2 1 0
b1 c1 0.7 0
c2 a2 0.8 0
d2 b2 0.6 0
a1 a2 1 1
a2 a1 0.1 1
....
a1 l1 0.5 0
a1 m1 0.5 0
a1 q1 0.5 0
a1 v1 0.5 0
a1 z1 0.5 0
a1 s1 0.5 0
a1 w1 0.5 0
a1 u1 0.5 0
其中前两列为传播实体,第三列为实体间传播概率,最后一列为0代表同一网络传播,为1代表网络间自传播。
下来要进行优化:
1.采用独立级联模型,设置阈值
2.将最大路径改为最短路径,利用log
Ⅷ Python中networkx中shortest_path使用的是哪一种最短路径方法
不全是。依据传入的参数决定调用哪种算法。
看源码:至少涉及了dijkstra、广乎灶度优先/深度优先算法。
ifsource岁迟扮isNone:
iftargetisNone:
##Findpathsbetweenallpairs.
ifweightisNone:
paths=nx.all_pairs_shortest_path(G)
else:
paths=nx.all_pairs_dijkstra_path(G,weight=weight)
else:
##Findpathsfromallnodesco-accessibletothetarget.
旦桐directed=G.is_directed()
ifdirected:
G.reverse(=False)
ifweightisNone:
paths=nx.single_source_shortest_path(G,target)
else:
paths=nx.single_source_dijkstra_path(G,target,weight=weight)
#.
fortargetinpaths:
paths[target]=list(reversed(paths[target]))
ifdirected:
G.reverse(=False)
else:
iftargetisNone:
##.
ifweightisNone:
paths=nx.single_source_shortest_path(G,source)
else:
paths=nx.single_source_dijkstra_path(G,source,weight=weight)
else:
##Findshortestsource-targetpath.
ifweightisNone:
paths=nx.bidirectional_shortest_path(G,source,target)
else:
paths=nx.dijkstra_path(G,source,target,weight)
Ⅸ 一道算法题,用python初始化一颗二叉树并求解其最短路径的值
二叉树算法,可能按照你的需求不是很多:
下面是我用的一个,不过你可以借鉴一下的:
# -*- coding: cp936 -*-
import os
class Node(object):
"""docstring for Node"""
def __init__(self, v = None, left = None, right=None, parent=None):
self.value = v
self.left = left
self.right = right
self.parent = parent
class BTree(object):
"""docstring for BtTee """
def __init__(self):
self.root = None
self.size = 0
def insert(self, node):
n = self.root
if n == None:
self.root = node
return
while True:
if node.value <= n.value:
if n.left == None:
node.parent = n
n.left = node
break
else:
n = n.left
if node.value > n.value:
if n.right == None:
n.parent = n
n.right = node
break
else:
n = n.right
def find(self, v):
n = self.root # http://yige.org
while True:
if n == None:
return None
if v == n.value:
return n
if v < n.value:
n = n.left
continue
if v > n.value:
n = n.right
def find_successor(node):
'''查找后继结点'''
assert node != None and node.right != None
n = node.right
while n.left != None:
n = n.left
return n
def delete(self, v):
n = self.find(v)
print "delete:",n.value
del_parent = n.parent
if del_parent == None:
self.root = None;
return
if n != None:
if n.left != None and n.right != None:
succ_node = find_successor(n)
parent = succ_node.parent
if succ_node == parent.left:
#if succ_node is left sub tree
parent.left = None
if succ_node == parent.right:
#if succ_node is right sub tree
parent.right = None
if del_parent.left == n:
del_parent.left = succ_node
if del_parent.right == n:
del_parent.right = succ_node
succ_node.parent = n.parent
succ_node.left = n.left
succ_node.right = n.right
del n
elif n.left != None or n.right != None:
if n.left != None:
node = n.left
else:
node = n.right
node.parent = n.parent
if del_parent.left == n:
del_parent.left = node
if del_parent.right == n:
del_parent.right = node
del n
else:
if del_parent.left == n:
del_parent.left = None
if del_parent.right == n:
del_parent.right = None
def tranverse(self):
def pnode(node):
if node == None:
return
if node.left != None:
pnode(node.left)
print node.value
if node.right != None:
pnode(node.right)
pnode(self.root)
def getopts():
import optparse, locale
parser = optparse.OptionParser()
parser.add_option("-i", "--input", dest="input", help=u"help name", metavar="INPUT")
(options, args) = parser.parse_args()
#print options.input
return (options.input)
if __name__ == '__main__':
al = [23, 45, 67, 12, 78,90, 11, 33, 55, 66, 89, 88 ,5,6,7,8,9,0,1,2,678]
bt = BTree()
for x in al :
bt.insert(Node(x))
bt.delete(12)
bt.tranverse()
n = bt.find(12)
if n != None:
print "find valud:",n.value