【问题标题】:Most inefficient algorithm to visit each elements of a 2d array once一次访问二维数组的每个元素的最低效算法
【发布时间】:2018-02-23 15:24:26
【问题描述】:

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

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

[ 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 秒的暂停。全景图主要是拍摄巨型建筑工地(建筑物)的建筑,但有时有汽车或人在建筑物前行走。我们不关心移动部件,目标是捕捉建筑物并尽量减少对全景进行照片轰炸的人/车。

【问题讨论】:

  • 你写然后我想如何以相机在每个位置之间移动最多的方式捕获图像。 7步,你移动0-2-6 -1-3-5。差异是 2-4-5-2-2,因此最大差异是 5,而最小差异是 2。难道不能用较低的差异来处理较高的差异,最大差异(差异)为 1 ? 2-4-5-2-2 → 3-4-4-2-2 → 3-3-4-3-2 → 3-3-3-3-3?那么“0-3-6-2-5-1-4”呢?差异:3-3-4-3-4-3?这里的一个问题是,对于 360° 全景,图片 0 和 6(=last) 是相邻的,因此 diff 0-6 将是 1,而不是 6,而 d(4) 将是 1. ...跨度>
  • 对于实际使用,我怀疑这只会偶然发生。速度更快的汽车仍会被多次捕获,或者距离更远的汽车。汽车,朝相反的方向行驶?如果在一张图像中没有将汽车作为一个整体捕获,那么 ½ 辆或 1/4 辆汽车看起来会很奇怪。 :)。但是算法问题仍然很有趣。我们谈论360°吗?全景图通常只有很宽,但不是一个完整的转弯。
  • 我的另一个问题是关于 2 行或更多行。是不是要在 y 轴上捕捉更多的视图,就像以前在 x 轴上一样?你不试着把公共汽车的顶部和底部放在一起吗?你不想捕捉起飞的火箭吗?或者图片只是一个虚构的例子?行的连接有什么考虑?第一行中的每个元素到第二行中对应元素的距离,而每个元素都必须坚持其行?
  • @userunknown:我编辑了问题以回答您的问题。关于差异问题,您看错了动作。 0-2-4-1-3-5 表示从 0(索引 0)开始,然后到 1(索引 3),然后到 2(索引 1),然后到 3(索引 4)...
  • 这没有意义,不是吗? 0-2 从 0 开始,到目前为止还可以。然后转到2,但是2既不是索引,也不是索引2处的值,因为一开始,值和索引是相同的,这是解释某事的合理选择。或者'2'是什么意思。您可以将图片命名为 abcdef,以避免对索引和值的刺激。您的意思是 024135 代表索引 031425 或 adbecf,但我没有看到映射。我错过了什么?

标签: algorithm graph-algorithm panoramas longest-path


【解决方案1】:

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

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

[ 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]

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

我怀疑,与其选择正好一半,不如选择一个不是宽度或高度除数的素数。

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

【讨论】:

  • 只有在考虑行/列时才使用 1D,否则“远距离”索引可能是邻居。我不喜欢随机解决方案,因为我希望在重新拍摄全景图时始终以相同的顺序进行拍摄,以最大限度地减少运动问题。
  • 我在问题中添加了附加信息,说明为什么相机距离可能会解决我的问题。
【解决方案2】:

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

代码变得微不足道:

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]

所以,现在我只对每一行使用它。我会等待一段时间,以防有人对我的问题提出更好的答案。

【讨论】:

    猜你喜欢
    • 2021-03-04
    • 1970-01-01
    • 2011-10-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多