【问题标题】:Simple Weighted Random Walk with Hysteresis带滞后的简单加权随机游走
【发布时间】:2011-02-06 15:50:07
【问题描述】:

我已经为此编写了一个解决方案,但感觉不太“正确”,所以我想听听其他人的意见。

规则是:

  • 运动在 2D 网格上(方向任意标记为 N、NE、E、SE、S、SW、W、NW)
  • 在给定方向上移动的概率是相对于行进方向的(即 40% 代表前方),并且是加权的:

[14%][40%][14%]
[ 8%][ 4%][ 8%]
[4%][4%][4%]

这意味着极有可能,旅行将沿着当前轨迹继续。中间值代表停止。例如,如果最后一步是 NW,那么绝对概率将为:

[40%][14%][8%]
[14%][4%][4%]
[ 8%][4%][4%]

  • 概率是近似值 - 我玩弄的一件事是在主计算之外设置 5% 的静态概率,这会稍微改变任何其他操作的概率。

我目前的算法如下(简化伪代码):

int[] probabilities = [4,40,14,8,4,4,4,8,14]

if move.previous == null:
    move.previous = STOPPED

if move.previous != STOPPED:
    // Cycle probabilities[1:8] array until indexof(move.previous) = 40%

r = Random % 99

if r < probabilities.sum[0:0]:
    move.current = STOPPED
elif r < probabilities.sum[0:1]:
    move.current = NW
elif r < probabilities.sum[0:2]:
    move.current = NW
...

我真的不喜欢这种方法的原因:
* 它迫使我为数组索引分配特定角色:[0] = 停止,[1] = 北...
* 它迫使我在循环时对阵列的一个子集进行操作(即 STOPPED 始终保持原位)
* 它非常迭代,因此很慢。它必须依次检查每个值,直到找到正确的值。循环阵列最多需要 4 次操作。
* 一个 9 格 if 块(大多数语言不允许动态切换)。
* Stopped 在所有情况下都必须是特殊情况。

我考虑过的事情:
* 循环链表:简化循环(使枢轴始终等于北)但需要维护一组指针,并且仍然涉及为特定索引分配角色。
* 向量:真的不知道如何加权,另外我需要担心大小。
* 矩阵:旋转矩阵不是这样工作的 :)
* 使用著名的随机游走算法:Overkill?尽管考虑了建议。 * 树:只是想到了这个,所以没有真正考虑过它......

所以。有人有什么好主意吗?

【问题讨论】:

  • 有一个点在二维网格上漫无目的地游荡,偶尔停下来,偶尔改变方向,但通常会沿着它选择的方向继续前进。

标签: algorithm


【解决方案1】:

8你有 8 个方向,当你击中某个方向时,你必须“旋转这个矩阵”

但这只是有限域上的模。

由于您只有 100 个整数可供选择概率,您可以将所有整数放入列表中,并将每个整数中的值指向您的方向索引。

您旋转的这个方向(模加法)指向您必须移动的方向。

而且你有一个数组,你必须将其应用到你的移动中。

类似的东西。

                   40 numbers    14 numbers   8 numbers
 int[100] probab={0,0,0,0,0,0,....,1,1,1,.......,2,2,2,...};

然后

                    N      NE    E     SE       STOP   
int[9] next_move={{0,1},{ 1,1},{1,1},{1,-1}...,{0,0}}; //in circle

所以你选择

move=probab[randint(100)]

if(move != 8)//if 8 you got stop
{
   move=(prevous_move+move)%8;
}

move_x=next_move[move][0];
move_y=next_move[move][1];

【讨论】:

  • 这运行得非常出色,而且速度极快——我的普通机器能够在单线程操作中每秒映射一百万个点。
【解决方案2】:

在算法中使用更直接的方向表示,例如 (dx, dy) 对。 这使您只需拥有x += dx; y += dy;就可以移动 (如果您愿意,您仍然可以使用“方向 ENUM”+ 查找表...)

您的下一个问题是找到“概率表”的良好表示。由于r 的范围仅从 1 到 99,因此只做一个哑数组并直接使用 prob_table[r] 可能是可行的。

然后,使用您选择的方法计算这些概率表的 3x3 矩阵。速度慢也没关系,因为你只做一次。

简单地获得下一个方向

prob_table = dir_table[curr_dx][curr_dy];
(curr_dx, curr_dy) = get_next_dir(prob_table, random_number());

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多