{1 44}}访问2d数组的每个元素的效率最低的算法

时间:2018-02-23 15:24:27

标签: algorithm graph-algorithm panoramas longest-path

我正在创建全景图像,为此,我使用了一步一步以编程方式移动的相机。这些图像是逐行捕获的。

所以基本上捕获可以被视为某种二维数组:

[ 0, 1, 2, 3 ] # row 1
[ 4, 5, 6, 7 ] # row 2

相机顺序移动数字。

我注意到,如果汽车在摄像机前移动并且跟摄像机的速度相同,那么汽车就会出现在每张照片上,而且全景看起来很奇怪。

所以,我有以下想法:以非连续的顺序移动相机,这样汽车很可能只被捕获一次。然后我想到了如何以相机在每个位置之间移动最多的方式捕捉图像。

我找到了一种单排全景图的方法。基本上它从头开始,向右跳一半,向左中间减去1,然后重复。

以下是示例:

# 1x5 --> [0, 2, 4, 1, 3]          # sequential indices: 0 3 1 4 2
# 1x6 --> [0, 2, 4, 1, 3, 5]       # sequential indices: 0 3 1 4 2 5
# 1x7 --> [0, 2, 4, 6, 1, 3, 5]    # sequential indices: 0 4 1 5 2 6 3
# 1x8 --> [0, 2, 4, 6, 1, 3, 5, 7] # sequential indices: 0 4 1 5 2 6 3 7

要清楚,这意味着对于1x6(0,2,4,1,3,5),相机移动如下:

x----- # pos 1
---x-- # pos 2
-x---- # pos 3
----x- # pos 4
--x--- # pos 5
-----x # pos 6

所以基本上它一直跳跃至少n/2,这看起来是最佳的,因为没有捕获最终成为另一个捕获的邻居,并且捕获之间的距离看起来最大化并且波动很小。

我使用的简化代码如下:

def index_for(n, cols)
  col = n % cols
  if n.even?
    col/2
  else
    (col / 2.0).ceil + (cols / 2.0).ceil - 1
  end
end

# Sequential indices [0, 4, 1, 5, 2, 6, 3]
seq = (0..6).map{ |i| index_for(i, 7) }

# Visualization [0, 2, 4, 6, 1, 3, 5]
(0..6).map{ |i| seq.index(i) }

我尝试让它在几行中工作,几乎到了那里然后放弃了。以下是我的想法的例子:

 # 3x4
 [0,  2, 9, 11]
 [4,  6, 1,  3]
 [8, 10, 5,  7]

 # 2x5
 [0, 2, 5, 7, 9]
 [4, 6, 8, 1, 3]

如果你看数字,我们看到左边通常只是偶数,右边是奇数,但是以模数方式移动。这种奇数的移位对于算法化来说很棘手,因为逻辑会根据行/列的偶数/奇数而略有变化。

目前我忽略了行,只需为每行重新应用相同的算法。这意味着2x5就是这样完成的:

 [0, 2, 4, 1, 3]
 [5, 7, 9, 6, 8]

所以,这是我的问题:

  • 什么是实现我想要的最佳算法,有多行?我读到了https://en.wikipedia.org/wiki/Longest_path_problem,我认为有可能构建一个图表,其中网格的所有节点之间存在路径,每个边缘的权重将是节点之间的距离。这听起来非常复杂,并且不易编码。
  • 申请多行的最简单/最实用的算法是什么?我对“足够好”的解决方案没问题(网格的尺寸应保持在1x3到3x9之间)。我想要基于随机性的解决方案,因为我希望每次捕获全景时捕获始终以相同的顺序发生。

编辑:其他信息:汽车通常移动缓慢(按顺序拍摄的速度),因此跳跃避免重复的好方法。如果汽车完全按照摄像机的速度移动(这发生了),那么在2-3个瓷砖中看到汽车比用7个汽车更好。全景图通常约为180°,但应支持360°。每次图像捕捉之间有一个约3秒的暂停。全景图主要是捕捉巨型建筑工地(建筑物)的建筑,但有时一辆车或一个人走在建筑物前面。我们不关心活动部件,目标是捕捉建筑物,并最大限度地减少人/车照相全景。

2 个答案:

答案 0 :(得分:0)

我不相信最大化相机的行进距离会使汽车只出现一次。可能更有可能在多个非连续帧中看到汽车。这也看起来很奇怪。但它值得测试。

一种简单的测试方法是将2D数组表示为一维数组,进行加扰,然后将其映射回二维。例如,这个2D数组:

[ 1, 2, 3, 4, 5]
[ 6, 7, 8, 9,10]
[11,12,13,14,15]

变为[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]

现在,您可以使用1D算法调整顺序,然后将其映射回二维。

我怀疑,你不是要完全中途,而是要选择一个不是宽度或高度除数的素数。

另一种可能性是使用Fisher-Yates shuffle随机化细胞。这很容易做到,并且在实践中可以很好地完成消除汽车的工作,就像确定性加扰算法一样。

答案 1 :(得分:0)

好的,我发现每行都有更简单的公式:

formula

代码变得微不足道:

def index_for(n, cols)
  (n + cols * (n % 2)) / 2
end

(0..7).map{ |i| index_for(i, 8) }
=> [0, 4, 1, 5, 2, 6, 3, 7]

所以,现在我只想在每行使用它。如果有人想出更好的答案,我会等一会儿。