0

例如:

m_array = new int[6][6];
m_array[0] = new int[]{2, 0, 0, 0, 0, 0};
m_array[1] = new int[]{0, 2, 0, 0, 0, 2};
m_array[2] = new int[]{2, 0, 0, 1, 0, 0};
m_array[3] = new int[]{0, 0, 0, 0, 0, 0};
m_array[4] = new int[]{0, 2, 0, 0, 2, 0};
m_array[5] = new int[]{0, 0, 2, 0, 0, 0};

我怎样才能找到最接近的 2 到 1?

我想要一个函数,它返回一个数组路径,包括数组点。例如,我将“m_array”给我的函数,它会返回给我最近的 2 换 1,一个数组路径,如 [2,3][3,4][4,4]

4

5 回答 5

1

这些是您让我们猜测的事情:

  • 只有一个 1,但有很多个 2;
  • 路径允许对角台阶;
  • 您正在寻找连接 1 和某些 2 的所有路径中最短的路径。

我目前的想法是,可以为任意两点之间的路径长度定义一个度量标准,因此“a 2 with the shortest path to 1”的概念等同于“the 2最接近1”的概念。度量标准可以定义为中心 1 周围的“环”数,必须经过才能达到 2:

0 0 0
0 1 0
0 0 2  --> the 2 is in the first ring

0 0 0 0 0
0 0 0 0 0
0 0 1 0 0
0 0 0 0 0
0 2 0 0 0 --> the 2 is in the second ring.

如果我所有的假设都是正确的,那么你需要一个函数来给出第一个环、第二个环等的所有成员,以及另一个在环中搜索 2 的函数。最后,你需要一个算法2.我希望你意识到路径不是唯一的。一个简单的算法将沿对角线移动直到与 2 对齐(水平或垂直),然后继续非对角线到目标。

于 2012-06-22T14:30:17.550 回答
0

不确定您的意思,因为您似乎在问两个不同的事情。在路径方面我真的无能为力,因为您没有指定太多关于我们如何移动的标准。您似乎也在问如何找到最接近的 2 到 1。虽然不是最有效的,但您可以简单地遍历矩阵并使用 Pythagoras' 根据索引计算出每个 2 到 1 的距离。或者,您可以从 1 开始,向外以正方形遍历矩阵。这可能会更快,因为您将在找到 2 的第二个停止,而不是必须使用第一个解决方案遍历整个矩阵检查 2,尽管第一个解决方案更容易实现并且不应该有那么大的区别你的矩阵很小(我相信两者都是 O(n),

我希望这是有道理的。

澄清后编辑:这是一种我希望满足您要求的方法。首先是一个类来总结点以便于访问。

public class Point {
    private int x, y;
    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }

    public int getX() { return x; }
    public int getY() { return y; }
    public int setX(int x) { this.x = x; }
    public int setY(int y) { this.y = y; }

}

现在方法本身:

public ArrayList<Point> getPath(int[][] matrix) {
    Point closestTwo = getClosestTwo(matrix); // Implement this as you wish
    Point onePosition = getOnePosition(matrix);

    ArrayList<Point> pointList = new ArrayList<Point>();

    Point currentlyOn = onePosition;

    while (currentlyOn.getX() != closestTwo.getX() && currentlyOn.getY() != closestTwo.getY()) {
        currentlyOn = oneStep(currentlyOn, closestTwo);
        pointList.add(currentlyOn);
    }

    return pointList;
}

这是一个可以用来靠近的 oneStep 方法的示例。它会返回一个点,该点会在您只执行一步的同时使您获得最大的进步(对角线优先)。

public Point oneStep(Point from, Point goal) {
    int x = from.getX() - goal.getX();
    int y = from.getY() - goal.getY();
    Point nextStep = new Point (from.getX(), from.getY());

    if (x > 0) {
        nextStep.setX(nextStep.getX() + 1)
    } else if (x < 0) {
        nextStep.setX(nextStep.getX() - 1)
    }

    if (y > 0) {
        nextStep.setY(nextStep.getY() + 1)
    } else if (y < 0) {
        nextStep.setY(nextStep.getY() - 1)
    }

    return nextStep;
}

我相信这应该可以正常工作。如果你使用它,你应该得到一个 Point 的 ArrayList。getClosestTwo 方法的一个例子可能是这样的(使用毕达哥拉斯的)。记得导入 java.lang.Math;

public Point getClosestTwo(int[][] matrix) { // Assumes matrix is initialized, non-empty etc.
    int x, y;
    double smallestDistance = matrix.size() * matrix[0].size(); // bigger than possible
    Point onePosition = getOnePosition(matrix);

    for (int i = 0; i < matrix.size(); i++) {
        for (int j = 0; j < matrix[0].size(); j++) {
            double tmp = (double)(Math.abs(i - y) + Math.abs(j - x))
            double distance = Math.sqrt(tmp);
            if (distance < smallestDistance) {
                y = i;
                x = j;
                smallestDistance = distance;
            }
        }
    }

    return new Point(x, y);
}

getOnePosition(int[][] matrix) 可以像这样简单地实现:

// Return null if no 1 in matrix
public Point getOnePosition(int[][] matrix) {
    for (int i = 0; i < matrix.size(); i++) {
        for (int j = 0; j < matrix[0].size(); j++) {
            if (matrix[i][j] == 1) {
                return new Point(j, i);
            }
        }
    }
    return null;
}

希望这有帮助。请记住检查空值,编写安全代码等。您可能可以将它们放在一起。我希望此代码没有任何您无法修复的拼写错误或错误。

于 2012-06-22T13:20:59.147 回答
0

此函数将我的矩阵数组拼接为环半径。

public static int[][] SpliceMatrix(int orginX, int orginY, int ringRadius, int[][] map){

    int[][] tempMap = new int[ringRadius * 2 + 1][ringRadius * 2 + 1];

    int tempY = -ringRadius;
    for(int i = 0; i < (ringRadius * 2 + 1); i++){
        int tempX = -ringRadius;

        for(int j = 0; j < (ringRadius * 2 + 1); j++){
            try{
                tempMap[i][j] = map[orginY + tempY][orginX + tempX];
            }catch(ArrayIndexOutOfBoundsException e){
                tempMap[i][j] = 1;
            }

            tempX++;
        }

        tempY++;
    }

    return tempMap;
}

我在这个函数中使用了 A* 算法:

private static Point findNext2(int orginX, int orginY, int[][] map){

    //Find "2"s
    ArrayList<Point> ends = new ArrayList<Point>();

    for(int i = 0; i < map.length; i++){
        for(int j = 0; j < map[0].length; j++){
            if(map[i][j] == 2){
                ends.add(new Point(j, i));

                map[i][j] = 0;//Clear for A*
            }
        }
    }

    //Find the closest
    if(ends.size() > 0){
        Point p = null;
        int distance = 100;

        for(int i = 0; i < ends.size(); i++){
            int tempDistance = APlus.go(orginX, orginY, ends.get(i).x, ends.get(i).y, map).size();
            System.out.println(tempDistance);
            if(tempDistance != 0 && tempDistance < distance){
                distance = tempDistance;
                p = new Point(ends.get(i).x, ends.get(i).y);
            }

        }

        if(p == null){
            System.out.println("2 is not accesible");

            return null;
        }

        return p;

    }else{
        System.out.println("There is no 2 in ring");

        return null;
    }

}

然后我用

public static void main(String args[]){

    int[][] m_array = new int[6][6];
    m_array[0] = new int[]{1, 1, 0, 0, 2, 0};
    m_array[1] = new int[]{0, 0, 0, 0, 0, 1};
    m_array[2] = new int[]{1, 1, 1, 0, 1, 0};
    m_array[3] = new int[]{1, 0, 1, 0, 1, 0};
    m_array[4] = new int[]{0, 0, 0, 0, 1, 0};
    m_array[5] = new int[]{0, 0, 0, 0, 0, 0};

    int[][] c = SpliceMatrix(2, 2, 2, m_array);//int x, int y, ringRadius, matrix

    Point p = findNext2(3, 3, c);//orginX, orginY, matrix
    System.out.println(p + " is the closest 2");
 }

我希望那是描述性的。我还不能正确使用 HTML。

于 2012-06-25T06:50:09.707 回答
0

我更喜欢快速图来找到更近的点或路径;所以,请看这个链接: http: //www.codeproject.com/Articles/5603/QuickGraph-A-100-C-graph-library-with-Graphviz-Sup

于 2012-06-25T07:13:39.733 回答
0

这是我的一段代码。似乎比我在这里看到的任何东西都简单,所以决定发布:

public static boolean isWithinRadius(int[] position, int[] centerPosition, int radius) {

        int xCenterPoint = centerPosition[0];
        int yCenterPoint = centerPosition[1];
        int zCenterPoint = centerPosition[2];


        int xPoint = position[0];
        int yPoint = position[1];
        int zPoint = position[2];

        boolean xMatch = (xPoint - radius <= xCenterPoint) && (xPoint >= xCenterPoint - radius);
        boolean yMatch = (yPoint - radius <= yCenterPoint) && (yPoint >= yCenterPoint - radius);
        boolean zMatch = (zPoint - radius <= zCenterPoint) && (zPoint >= zCenterPoint - radius);


        return xMatch && yMatch && zMatch;

    } // public boolean isWithinRadius (int[], int)

如果位置在 centerPosition 的半径内,这将返回 true。

  1. centerPosition 是环的中心。(如果您不需要 Z 值,只需将 0 放在要求的任何位置。)
  2. 半径 1 == 环 1 ,半径 2 == 环 1 和环 2 等。您可以扫描半径。尝试以此为基础。如果您有兴趣,我编写了一个高级矩阵类,您可以扫描(基于散列)并在其中查找对象。我正要编写代码来返回在半径内找到的对象的 ArrayList。

如果您希望仅在特定环内查找对象(而不是半径内的所有对象),请使用以下代码:

public static boolean isWithinRadiusRing(int[] position, int[] centerPosition, int radius) {


        int xCenterPoint = centerPosition[0];
        int yCenterPoint = centerPosition[1];
        int zCenterPoint = centerPosition[2];


        int xPoint = position[0];
        int yPoint = position[1];
        int zPoint = position[2];

        boolean xRingMatch = (xPoint - radius == xCenterPoint) || (xPoint == xCenterPoint - radius);
        boolean yRingMatch = (yPoint - radius == yCenterPoint) || (yPoint == yCenterPoint - radius);
        boolean zRingMatch = (zPoint - radius == zCenterPoint) || (zPoint == zCenterPoint - radius);

        boolean xRadiusMatch = (xPoint - radius <= xCenterPoint) && (xPoint >= xCenterPoint - radius);
        boolean yRadiusMatch = (yPoint - radius <= yCenterPoint) && (yPoint >= yCenterPoint - radius);
        boolean zRadiusMatch = (zPoint - radius <= zCenterPoint) && (zPoint >= zCenterPoint - radius);

        boolean xMatch = xRingMatch && yRadiusMatch && zRadiusMatch;
        boolean yMatch = yRingMatch && xRadiusMatch && zRadiusMatch;
        boolean zMatch = zRingMatch && xRadiusMatch && yRadiusMatch;

        /*
            System.out.println("xRingMatch="+xRingMatch+" yRingMatch="+yRingMatch+" zRingMatch="+zRingMatch);
            System.out.println("xRadiusMatch="+xRadiusMatch+" yRadiusMatch="+yRadiusMatch+" zRadiusMatch="+zRadiusMatch);
            System.out.println("xMatch="+xMatch+" yMatch="+yMatch+" zMatch=" +zMatch);
            System.out.println("return=" + (xMatch || yMatch || zMatch));
        */

        return xMatch || yMatch || zMatch;

    } // public boolean isWithinRadiusRing(int[], int[] , int)

true如果给定位置在 centerPosition 的给定半径环内(半径 1 == ring1,半径 2 == ring 2 等),这将返回

要找出两个位置之间的半径距离:

        public static int getDistanceRadius(int[] startPosition, int[] endPosition) {

            // The xyz value that streches the most the distance between two positions
            // is the radius value.
            int xDistance = Math.abs(startPosition[0] - endPosition[0]);
            int yDistance = Math.abs(startPosition[1] - endPosition[1]);
            int zDistance = Math.abs(startPosition[2] - endPosition[2]);

            int radius = (xDistance > yDistance ? xDistance : yDistance);        
            radius = (radius > zDistance ? radius : zDistance);

            return radius;

        } // public static int getDistanceRadius(int[], int[])
于 2015-04-27T19:40:24.997 回答