当前位置: 代码迷 >> java >> 选择方向以启动洪水填充算法进行环路检测
  详细解决方案

选择方向以启动洪水填充算法进行环路检测

热度:94   发布时间:2023-07-31 11:30:21.0

我已经在程序中为矩阵实现了洪水填充算法,我想选择从哪个方向开始。 我想检测由网格上的元素创建的循环:当网格上给定位置有一个元素时,矩阵中将显示1。 当没有任何东西时,它是0。当它是不会移动的元素时,它是2。洪水填充算法从1开始,并将遇到的每1变成2。
例:

0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 
0 0 2 1 1 1 1 0 0 0 
0 0 2 0 0 0 1 0 0 0  
0 0 1 1 1 1 1 0 0 0 
0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0

会成为:

0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 
0 0 2 2 2 2 2 0 0 0 
0 0 2 0 0 0 2 0 0 0
0 0 2 2 2 2 2 0 0 0 
0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0

这是我的代码:

import TUIO.*;
import java.util.Arrays;
import java.util.Scanner;

TuioProcessing tuioClient;

// Create matrix
static int[][] matrix = new int[10][10];

// these are some helper variables which are used
// to create scalable graphical feedback
int k, l, iD, x,y;
String myType;

void setup() {
  size(1000, 600);
  noCursor();
  noStroke();
  fill(0);
}

void draw() {

  matrix [1][5]= 2;
  matrix [1][6]= 2;
  matrix [2][5]= 2;
  matrix [2][6]= 2;
  matrix [3][5]=1;

  ArrayList<TuioObject> tuioObjectList = tuioClient.getTuioObjectList();
  for (int i=0; i<tuioObjectList.size (); i++) {
    TuioObject tobj= tuioObjectList.get(i);
    stroke(0);
    fill(0, 0, 0);
    pushMatrix();
    translate(tobj.getScreenX(width), tobj.getScreenY(height));
    rotate(tobj.getAngle());
    rect(-80, -40, 80, 40);
    popMatrix();
    fill(255);
    x = round(10*tobj.getX ());
    y = round(10*tobj.getY ());
    iD = tobj.getSymbolID();
    int taille = fiducialsList.length;
    for (int o = 0; o<taille; o++) {
      if (iD == o) { 
        myType = fiducialsList [o];
      }
    } 

    activList.add(new Fiducial (x, y, iD, myType));
    fiducialCoordinates ();
    matrix [x][y] = 1 ;

    circuitState ();
    for (int p = 0; p < 10; p++) {
      for (int r = 0; r < 10; r++) {
        System.out.print(matrix[p][r] + " ");
      }
      System.out.print("\n");
    }
    System.out.print("\n");
    // activList.removeAll(activList);
  }
  for (int[] row : matrix)
    Arrays.fill(row, 0);
}

public static class FloodFill {

  public static void resolution(String[] args) {

    solve(matrix, 2, 5, 3);

    //result
    System.out.println("-------------------"); 

    for (int i=0; i<matrix.length; i++) {
      for (int j=0; j<matrix[i].length; j++) {
        System.out.print(matrix[i][j] + " ");
      }
      System.out.print("\n");
    }
    System.out.print("\n");
  }

  public static void solve(int[][] matrix, int x, int y, int fillValue) {

    if (x>=matrix.length)
      return;
    if (y>=matrix[x].length)
      return;

    int originValue=matrix[x][y];
    matrix[x][y]=fillValue;

    // Up
    if (x-1>=0 && originValue==matrix[x-1][y])
      solve(matrix, x-1, y, fillValue);      

    // Right
    if (y+1<matrix[x].length && originValue==matrix[x][y+1])
      solve(matrix, x, y+1, fillValue);
    //south-east

    // Down
    if (x+1<matrix.length  && originValue==matrix[x+1][y])
      solve(matrix, x+1, y, fillValue);  
    //south-west

    // Left
    if (y-1>=0 && originValue==matrix[x][y-1])
      solve(matrix, x, y-1, fillValue);
  }
}

该算法是在FloodFill创建的。实际情况要复杂得多,所以这就是我的问题:给出起点后,如何防止它朝一个方向看(例如左侧)? 有没有办法做到这一点? 我不希望算法“看”起点左侧的位置。

它是Java,但在处理中使用。

通过注释,您要求一种允许您检查循环的算法。 下面的解决方案使用修改后的洪水填充来实现。

private static enum Direction{
    UP,
    RIGHT,
    DOWN,
    LEFT,
    NONE;
}

public static boolean checkIfPositionIsInLoop(int[][] matrix, int x, int y, int fillValue){
    int targetX = x;
    int targetY = y;
    return fillReachesTargetPosition(matrix, x, y, targetX, targetY, fillValue, Direction.LEFT /*don't allow it to start filling to the left*/);
}

private static boolean fillReachesTargetPosition(int[][] matrix, int x, int y, int targetX, int targetY,  int fillValue, Direction forbiddenDirection) {

    if (x>=matrix.length)
      return false;
    if (y>=matrix[x].length)
      return false;

    int originValue=matrix[x][y];
    matrix[x][y]=fillValue;

    int xToFillNext;
    int yToFillNext;

    boolean fillingReachedTargetPosition = false;

    // Up
    xToFillNext = x-1;
    yToFillNext = y;
    if(xToFillNext==targetX && yToFillNext==targetY && !forbiddenDirection.equals(Direction.UP)){
        return true;
    } else if (xToFillNext>=0 && originValue==matrix[xToFillNext][yToFillNext] && !forbiddenDirection.equals(Direction.UP)){            
        fillingReachedTargetPosition = 
                fillReachesTargetPosition(matrix, xToFillNext, yToFillNext, targetX, targetY, fillValue,Direction.DOWN /*Just came from up- don't allow it to try filling here again*/);
        if(fillingReachedTargetPosition){
            return true;
        }
    }

    // Right
    xToFillNext = x;
    yToFillNext = y+1;
    if(xToFillNext==targetX  && yToFillNext==targetY && !forbiddenDirection.equals(Direction.RIGHT)){
        return true;
    } else if (yToFillNext<matrix[xToFillNext].length && originValue==matrix[xToFillNext][yToFillNext] && !forbiddenDirection.equals(Direction.RIGHT)) {
      fillingReachedTargetPosition = 
        fillReachesTargetPosition(matrix, xToFillNext, yToFillNext,targetX, targetY, fillValue,Direction.LEFT /*Just came from right- don't allow it to try filling here again*/);
      if(fillingReachedTargetPosition){
          return true;
      }
    }

    // Down
    xToFillNext = x+1;
    yToFillNext = y;
    if(xToFillNext==targetX && yToFillNext==targetY && !forbiddenDirection.equals(Direction.DOWN)){
        return true;
    } else if (xToFillNext<matrix.length  && originValue==matrix[xToFillNext][yToFillNext] && !forbiddenDirection.equals(Direction.DOWN)){
        fillingReachedTargetPosition = 
                fillReachesTargetPosition(matrix, xToFillNext, yToFillNext, targetX, targetY, fillValue,Direction.UP /*Just came from up- don't allow it to try filling here again*/);  
        if(fillingReachedTargetPosition){
              return true;
        }
    }

    // Left
    xToFillNext = x;
    yToFillNext = y-1;
    if(xToFillNext==targetX && yToFillNext==targetY && forbiddenDirection.equals(Direction.RIGHT)){
        return true;
    } else if (yToFillNext>=0 && originValue==matrix[xToFillNext][yToFillNext] && !forbiddenDirection.equals(Direction.LEFT)){
        fillingReachedTargetPosition = 
                fillReachesTargetPosition(matrix, xToFillNext, yToFillNext, targetX, targetY, fillValue,Direction.RIGHT /*Just came from left- don't allow it to try filling here again*/);
        if(fillingReachedTargetPosition){
            return true;
        }
    }

    return false;
  }

这里是一个驱动程序,以演示它的作用:

public static void main(String[] arg){
    System.out.println("Show matrix with loop, before fill");
    int[][] matrix = getMatrixWithWideLoop();
    printMatrix(matrix);
    System.out.println("Found loop: "+checkIfPositionIsInLoop(matrix, 0, 2, 2 /*fill with 2s*/));

    System.out.println("-----------------------------------------");
    System.out.println("Show matrix without loop, before fill");
    matrix = getMatrixWithoutLoop();
    printMatrix(matrix);
    System.out.println("Found loop: "+checkIfPositionIsInLoop(matrix, 0, 2, 2 /*fill with 2s*/));


    System.out.println("-----------------------------------------");
    System.out.println("Show matrix with small loop, before fill");
    matrix = getMatrixWithSmallLoop();
    printMatrix(matrix);
    System.out.println("Found loop: "+checkIfPositionIsInLoop(matrix, 0, 2, 2 /*fill with 2s*/));


    System.out.println("-----------------------------------------");
    System.out.println("Show matrix without loop, before fill");
    matrix = getMatrixWithoutLoop();
    printMatrix(matrix);
    System.out.println("Found loop: "+checkIfPositionIsInLoop(matrix, 0, 1, 2 /*fill with 2s*/));

}

并输出:

Show matrix with loop, before fill
01110
01010
01110
Found loop: true
-----------------------------------------
Show matrix without loop, before fill
01110
00010
01110
Found loop: false
-----------------------------------------
Show matrix with small loop, before fill
01100
01100
00000
Found loop: true
-----------------------------------------
Show matrix without loop, before fill
01110
00010
01110
Found loop: false
  相关解决方案