2D数组中元素之间的距离

时间:2013-11-10 19:47:39

标签: arrays algorithm 2d distance

如何确定2D阵列中1之间的距离。例如,我们有一个像这样的2D数组:

0 0 0 0
0 0 0 1
1 0 0 0
1 0 0 0

算法必须输出每个元素到最近的距离1.如下所示:

2 3 2 1
1 2 1 0
0 1 2 1
0 1 2 2

我该如何解决?

6 个答案:

答案 0 :(得分:4)

您可以迭代矩阵并找到所有1(x1,y1)的坐标。然后对于单元格中的每个位置(x2,y2),对于列表中的所有(x1,y1),找到最小值| x2 - x1 | + | y2 - y1 | (曼哈顿距离,因为它是一个网格)。

答案 1 :(得分:1)

我喜欢这个问题,所以我在线创建了一个页面,您可以尝试解决它: http://www.learneroo.com/courses/29/nodes/221

解决方案代码如下,基于@ manu-fatto的回答。方法minArray遍历整个双数组几次,并且每次通过选择其附近的最小值并添加1来更新每个单元格到附近1的最小距离。

import java.util.*;

class DistanceZ {   

static void minArray(int[][] square){
    int w = square.length;

    for(int times = 0; times<w; times++){
        for(int i =0; i<w; i++){
            for(int j=0;j<w;j++){
                square[i][j] = minCell(square, i, j);
            }
        }
    }       
    printArray(square);     
}

此方法将根据当前单元格及其4个邻居计算最小距离:

static int minCell(int[][] square, int i, int j){
    //get the minimum of current cell and adjacent cells + 1.       
}

接下来的两种方法是输入/输出(参见完整代码的链接):

private static void printArray(int[][] square) {
    //print the Array
}

public static void main(String[] args) {
    //get input into arrays
}
}

答案 2 :(得分:1)

因为你没有指定语言:)这是Common Lisp中算法的并行版本:

(ql:quickload :lparallel)
(defpackage :compute-distances (:use :cl :lparallel))
(in-package :compute-distances)

(defun positions (number matrix)
  (loop :for i :from 0 :below (array-dimension matrix 0)
     :nconc (loop :for j :from 0 :below (array-dimension matrix 1)
               :if (= number (aref matrix i j))
               :collect (cons i j))))

(defun find-neighbours (point points)
  (loop :with x := (car point) :and y := (cdr point)
     :for point :across points
     :unless (and (= x (car point)) (= y (cdr point)))
     :collect (let ((width (- x (car point)))
                    (height (- y (cdr point))))
                (sqrt (+ (* width width) (* height height))))))

(defun find-all-neighbours (number matrix)
  (let* ((positions (coerce (positions number matrix) 'vector))
         (*kernel* (make-kernel (length positions))))
    (pmap 'vector (lambda (point) (find-neighbours point number matrix))
          :parts (length positions) positions)))

(defparameter *test-matrix*
  (make-array '(4 4) :initial-contents
              '((0 0 0 0)
                (0 0 0 1)
                (1 0 0 0)
                (1 0 0 0))))

(find-all-neighbours 1 *test-matrix*)
;; #((3.1622777 3.6055512) (3.1622777 1.0) (3.6055512 1.0))

答案 3 :(得分:0)

从一个矩阵开始,其中1表示1,而其他单元格上的数字较大(大于任何可能的距离)。然后迭代你的矩阵。在每个单元格中,将当前值和相邻单元格的最小值加上最小值加1。迭代直到您不需要任何更新。

答案 4 :(得分:0)

我知道这可能只是解决你的功课,但我必须这样做。

这是一种在JavaScript中解决问题的有效方法,我相信它只有O(n ^ 2)(我在O表示法上有点生疏,忽略可能在数据输入上完成的第一个循环)

它的工作原理如下

获取每个元素的位置

for (var a=0,aa=arr.length; a<aa; a++) // this loop may be able to be done when data is read in
{
 result[a] = [];
 for (var b=0,bb=arr[a].length; b<bb; b++)
 {
  result[a][b] = -1;
  if(arr[a][b]==1)pos.push({x:a,y:b,dist:0});
 }
}

开始循环遍历数组

抓住第一个条目并将其删除。在c ++中,您应该使用队列

while(pos.length>0)
{
 var p = pos[0];
 pos.splice(0,1);

检查距离是否尚未设置

 if(result[p.x][p.y]==-1)
 {

检查x和y坐标是否在数组范围内

将它们添加到位置数组/队列的末尾,以及一个额外的距离单位

   var x = p.x+dx[a];
   var y = p.y+dy[a];
    if(x>=0&&x<result.length&&y>=0&&y<result[p.x].length)pos.push({x:x,y:y,dist:p.dist+1});

显示输出

for (var a=0,aa=arr.length; a<aa; a++)
{
  console.log(result[a]);
}

完整代码:

<script>
var arr = [
[0,0,0,0],
[0,0,0,1],
[1,0,0,0],
[1,0,0,0]];
var result = [];
var pos = [];

for (var a=0,aa=arr.length; a<aa; a++) // this loop may be able to be done when data is read in
{
 result[a] = [];
 for (var b=0,bb=arr[a].length; b<bb; b++)
 {
  result[a][b] = -1;
  if(arr[a][b]==1)pos.push({x:a,y:b,dist:0});
 }
}
var dx = [-1,0,0,1];
var dy = [0,1,-1,0];

while(pos.length>0)
{
 var p = pos[0];
 pos.splice(0,1);
 if(result[p.x][p.y]==-1)
 {
  result[p.x][p.y] = p.dist;
  for(var a=0; a<4; a++)
  {
   var x = p.x+dx[a];
   var y = p.y+dy[a];
   if(x>=0&&x<result.length&&y>=0&&y<result[p.x].length)pos.push({x:x,y:y,dist:p.dist+1});
  }
 }
}
for (var a=0,aa=arr.length; a<aa; a++)
{
  console.log(result[a]);
}

</script>

答案 5 :(得分:0)

  • 使用BFS,首先将所有的“ 1”加到Q,然后在“成本”矩阵中将这些单元格视为0(用n初始化其他单元格)。
  • 然后尝试使x(即pair(i,j))出队,直到Q为空。
  • 仅当值小于当前值时,才使用“ x + 1”值更新“成本”矩阵中的邻居。
  • 将更新的邻居添加到Q中。