【问题标题】:Weighted Random Graph Traversal in PythonPython中的加权随机图遍历
【发布时间】:2015-08-31 08:18:21
【问题描述】:

基本上,我想随机移动一个 300 x 250 的区域。然而,在点 18750 和 9300 有一些感兴趣的区域(你可以通过做 y = 0 while(num > x): num = num - x y += 1 你会得到坐标)。无论如何,所以如果起点是(0,0),我希望能够在该区域内随机移动,但在两个给定点的一般区域内移动。也许一个有更强的拉力,因此即使节点遍历导致更弱的节点,它也会在足够的时间后到达拉力更强的节点。

到目前为止,我有这个是为了创建我的图表并创建我的顶点和边。它给了我一个 300x250 的空间,每个节点垂直和水平连接。 `

from igraph import *
g = Graph()
x = 300
y = 250
g.add_vertices(x*y)
li = []

for i in range(x-1):
    for j in range(y):
        li.append((i+j*x, i+1+j*x))
for i in range(x):
    for j in range(y-1):
        li.append((i+j*x, i+x+j*x))

g.add_edges(li)

gravity_points = [18750, 9300]
final_point = 24900

` 我该怎么办?我想让移动节点必须在每个静止节点上做出选择,但它在任何方向上移动的概率完全取决于重力点的权重。所以它可能有 10% 的机会向左走,有 10% 的机会向右走,有 50% 的机会向下走,还有 30% 的机会向上走。类似的东西。概率不必随着接近度而改变,而是随着重力点所在的方向而改变。

欢迎任何帮助!提前谢谢你。

【问题讨论】:

  • “方向”是什么意思?你的意思是,好像这些点在平面上?那么每次你朝着正确的方向移动时,你会减少曼哈顿距离吗?您是在问如何进行移动(即如何表示移动节点并更改其 x 和 y),还是在问如何对选择进行加权?
  • 当我说“方向”时,我的意思差不多。南北西东。想象一下它在您所说的飞机上,并且每个正确的方向都会减少距离。我对@strubbly 的要求是我如何权衡选择并根据我拥有的图表做出决定,或者如果您有其他建议,我也很乐意接受!
  • 老实说,我真的不知道你在哪个部分遇到了麻烦。您有四个选择,并且您想根据加权概率进行选择。如果你知道权重,这可以在 Python 中使用随机函数轻松完成。尽管您没有指定要使用的方案,但设置权重应该很简单。可以通过比较移动节点和重力点的 x 和 y 坐标来了解应该加权的方向。还需要什么?
  • 我想我很难想出一种遍历它的方法。让旅行节点在旅行每个节点后做出“加权随机”决策。 @strubbly

标签: python random graph traversal weighted


【解决方案1】:

不确定,但也许您的问题不是找到算法,而是如何在这种情况下使用igraph。这很棘手,因为它似乎没有向这个要求添加任何东西。我将从描述算法开始:希望这会帮助您收紧您的问题,直到我们得到答案。

随机遍历将如下所示,在伪代码中:

traveller_node = start_node  # Chosen somehow

while not stopping_condition(traveller_node):
    possible_successors = traveller_node.successors()
    traveller_node = random_choice_from(possible_successors)    

在这种情况下,最简单的方法是用 x,y 坐标来表示每个节点,包括旅行者节点。后继函数不需要依赖于图形,因为通常有四个选项,除了矩形的边缘。那么我们可以直接把你的问题写出来:

traveller_x,traveller_y = 10,10  # Or whatever you want

while not at_gravity_points(traveller_x,traveller_y):
    directions = ["left","right","up","down"]
    if traveller_x == 0:
        directions.remove("left")
    if traveller_x == x:
        directions.remove("right")
    if traveller_y == 0:
        directions.remove("down")
    if traveller_y == y:
        directions.remove("up")

    to_gravity_point_1 = []
    if traveller_x < gravity_point_1_x:
        to_gravity_point_1.append("right")
    elif traveller_x > gravity_point_1_x:
        to_gravity_point_1.append("left")
    if traveller_y < gravity_point_1_y:
        to_gravity_point_1.append("up")
    elif traveller_y > gravity_point_1_y:
        to_gravity_point_1.append("down")

    # ... do the same to construct to_gravity_point_2
    # then use these two lists to construct your weighting scheme
    # then use random.random() to choose a direction from directions
    # according to that weighting.

    if direction == "left":
        traveller_x -= 1
    elif direction == "right":
        traveller_x += 1
    elif direction == "up":
        traveller_y += 1
    elif direction == "down":
        traveller_y -= 1

这一切都如此简单,以至于我认为这不是您要问的。那么,也许您的问题是如何使用igraph 的功能做到这一点?在这种情况下,我的首选答案是“为什么?”

但是,为了努力,你可以做这样的事情。首先用权重增加你的图表。通过迭代所有顶点来做到这一点,并且对于每个顶点,将它们的 x 和 y 与重力点的 x 和 y 进行比较。使用这些比较来为其传出边构造权重,并使用 igraph 中的加权图功能存储它们。

然后将 traveler 节点定义为 igraph.Vertex

然后反复:

在该顶点上使用 igraph 后继函数来查找可能的后继。使用 igraph 权重查找来查找权重。使用random.random() 根据权重在它们之间进行选择。将 traveler 节点更改为选择的后继节点。

在算法方面,这里唯一的区别是我们预先计算权重而不是按需计算。

【讨论】:

  • 这绝对是我想要的。我肯定用这个和 igraph 做了一个不必要的方法。我想也许如果我想实现边缘权重等等,它可能会更好,但目前这绝对是我设想的方式。谢谢!!
猜你喜欢
  • 1970-01-01
  • 2017-04-26
  • 2016-10-30
  • 2014-02-14
  • 2012-10-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多