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,3][3,4][4,4] のような配列パスである、最も近い 2 対 1 が返されます。

4

5 に答える 5

1

これらは、あなたが私たちに推測させているものです:

  • 1 は 1 つだけですが、2 はたくさんあります。
  • パスは斜めのステップを許可します。
  • 1 と 2 を結ぶすべてのパスの中で最短のものを探しています。

私の現在の考えでは、任意の 2 点間のパスの長さに対して定義できるメトリックがあるため、「1 への最短パスを持つ 2」という概念は「1 に最も近い 2」という概念と同等です。メトリックは、中央の 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への道を描きます。道がユニークではないことを理解していただければ幸いです。自明なアルゴリズムは、2 と整列するまで (水平または垂直のいずれかで) 対角線上に移動し、非対角線上でターゲットに移動します。

于 2012-06-22T14:30:17.550 に答える
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

これが私のコードです。ここで見たものよりもはるかに簡単に思えるので、投稿することにしました:

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 == リング 1、半径 2 == リング 2 など)。

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 に答える
0

より近いポイントまたはパスを見つけるためのクイックグラフを好みます。したがって、このリンクを参照してください: http://www.codeproject.com/Articles/5603/QuickGraph-A-100-C-graph-library-with-Graphviz-Sup

于 2012-06-25T07:13:39.733 に答える
0

あなたは2つの異なることを求めているように見えるので、あなたが何を意味するのかわかりません. どのように移動できるかについて多くの基準を指定しなかったため、パスの側面についてはあまり役に立ちません。また、最も近い 2 対 1 を見つける方法を尋ねているようです。最も効率的ではありませんが、単純に行列を走査し、ピタゴラスを使用して、インデックスに基づいて各 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 メソッドの例です。1 つのステップを実行するだけで、最も前進するポイントを返します (対角線が優先されます)。

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;
}

これが役に立ったことを願っています。null をチェックすること、安全なコードを書くことなどを忘れないでください。おそらくこれをすべてまとめることができます。このコードに、修正できないタイプミスやエラーがないことを願っています。

于 2012-06-22T13:20:59.147 に答える