问题描述
我正在研究一个基于代理的模型,其中代理可以有一定的概率采取不同的路线。对于每条路线,有多个路径点(即,p1,p2,...,p_end
)。目前,我将其表示为一个 JSON 文件,例如:
{
"paths": [
{"[p3,p4,p_end]": 0.25},{"[p3,p1,p5,p7,p_end]": 0.1},p8,p10,p_end]": 0.3}
]
}
其中每个字典键是一个路由,它的值是关联的概率。
但是,我有比这更多的路由选项(即 50-100),我想知道是否有更好的方法来表示 Python 的这种数据结构,而不是显式编写所有内容。
对不起,如果这是一个非常基本的问题,并提前致谢:)
解决方法
我认为字典很好在一天结束时。不过,如果您能够获得在任何状态之间移动的概率,那么还有更好的表示方法。
您的问题表述类似于基本的马尔可夫链(如果您不熟悉,它是一个具有转换到不同状态的概率的图)。听起来用带有显示概率的加权边的类似图的结构来表示问题是很自然的。
有了这个,你就可以使用一个基本的图遍历算法来构建一个像上面那样的字典。这样做有很多好处,比如可以使用马尔可夫模型分析技术,还可以通过修改链来更改字典。
路径看起来像这样:
"paths": [
{(1,2): ?},{(1,3): ?},...
]
不过,这只是一个建议。由于查询效率高,字符串到问题的哈希可能是最终目标。
编辑:
刚刚注意到你的后续问题。我拼凑了一个快速功能,您当然可以根据自己的目的进行优化。如果我在某个地方搞砸了,请告诉我(不过我认为这很好)。
对于以下示例,请考虑链:
假设路径被视为边缘列表,可以使用以下过程。
# Very small set of edges.
paths = {
(1,2) : 0.9,(1,3) : 0.1,(2,1) : 0.8,3) : 0.2,}
from collections import defaultdict
# Make a simple dictionary to keep track of out paths
edge_dict = defaultdict(list)
for k,v in paths.items():
edge_dict[k[0]].append((k[1],v))
print(dict(edge_dict))
# > {1: [(2,0.9),(3,0.1)],2: [(1,0.8),0.2)]}
# Recursively construct a hash or probabilities
def dfs_from_state(start,edge_dict):
path_hash = dict()
dfs_from_state_recur(start,path_hash,edge_dict)
return path_hash
def dfs_from_state_recur(state,edge_dict,chain = [],prob = 1):
if state not in edge_dict.keys():
# If it's a terminal state,base case: hash the prob
chain += [(state,)]
chain_str = "->".join([str(c[0]) for c in chain])
path_hash[chain_str] = prob
return
for adj,weight in edge_dict[state]:
# Otherwise,dfs
link = (state,adj)
if link not in chain:
dfs_from_state_recur(
adj,chain+[link],prob*weight
)
# Actually do DFS from every possible starting state
path_hash = dict()
for start in edge_dict.keys():
path_hash.update(dfs_from_state(start,edge_dict))
[print("%12s : %0.4f" % e) for e in path_hash.items()]
# 1->2->1->3 : 0.0720
# 1->2->3 : 0.1800
# 1->3 : 0.1000
# 2->1->2->3 : 0.1440
# 2->1->3 : 0.0800
# 2->3 : 0.2000