2016-10-01 5 views
0

시작 지점과 끝점이 지정된 2 차원 배열에 BFS를 구현하려고합니다. 그리드에서 두 점을 내 함수에 제공하려고 시도했지만 경로가 없다는 의미의 빈 배열을 반환합니다.경로를 반환하지 않는 BFS

누군가 내가 잘못 가고있는 부분을 지적하고 가능한 경우 실수를 바로 잡을 수 있도록 도와 줄 수 있습니까? 감사.

public Point[] bfs2(Point start, Point end) { 
    boolean[][] visited = new boolean[50][50]; 
    for (int i = 0; i < visited.length; i++) 
     for(int j = 0; j < visited.length; j++) 
      visited[i][j] = false; 

    visited[start.getX()][start.getY()] = true; 
    LinkedList<Point> path = new LinkedList<>(); 
    Queue<Point> q = new LinkedList<>(); 
    q.add(start); 

    while (!q.isEmpty()) { 
     Point next = q.remove(); //i think the error is here 
     Point[] neighbours = next.getNeighbours(); 
     path.add(next); 

     if (next.getX() == end.getX() && next.getY() == end.getY()) 
      break; 
     else if (!visited[next.getX()][next.getY()]) { 
      for (Point neighbour : neighbours) { 
       if (!visited[neighbour.getX()][neighbour.getY()]) { 
        q.add(neighbour); 
       } 

       visited[neighbour.getX()][neighbour.getY()] = true; 
      } 
     } 
    } 

    Point current = path.removeLast(); 
    ArrayList<Point> v = new ArrayList<>(); 
    while (current.getX() != start.getX() || current.getY() != start.getY()) { 
     v.add(current); 
     current = path.removeLast(); 
    } 

    return v.toArray(new Point[v.size()]); 
} 

편집 :

 Point current=q.peek(); 
    ArrayList<Point> v=new ArrayList<>(); 
    if(start.getX()==end.getX() && start.getY()==end.getY()) return new Point[0]; 
    while(current.getX()!=start.getX() || current.getY()!=start.getY()){ 
     v.add(current); 
     current=current.parent; 
    } 
    return v.toArray(new Point[v.size()]); 
+0

간단한'Collections.reverse (path); 대신에 회선 코드의 마지막 7 줄을 사용해야하는 이유는 무엇입니까? –

+1

'Point'의 정의도 게시하십시오. 더 나은 아직 MCVE (http://stackoverflow.com/help/mcve) –

+0

('false로'방문한 요소를 초기화하는 것은 중복 됨) – greybeard

답변

0

첫 번째 문제는 당신이 경로 (나는 path.add(next);를 포함하는 라인을 말하는 겁니다)에 큐에서 제거 모든 요소를 ​​추가하는 것입니다.

대신 각 노드를 방문한 상위 노드를 추적해야합니다. 끝 노드를 찾으면 시작 노드로 단계를 추적 할 수 있습니다.

모든 노드가 모두 소모되었지만 여전히 끝 노드를 찾지 못한 경우 빈 목록을 반환 할 수 있습니다.

MCV example이 필요하면 알려주세요. 추가하겠습니다.

나중에 편집 :

이 같은 클래스에 포인트 부모 필드를 추가해야합니다

class Point { 
    int x; 
    int y; 
    Point parent; // reference to the Point from which this Point was visited 

    // constructors, getters, setters, etc. 
} 

그런 다음 당신은 당신의 BFS 구현을 변경할 수 있습니다 또한 현재의 부모를 설정 노드를 이웃 노드를 통해 반복 할 때. 루프를 다음과 같이 변경해야합니다 :

 for (Point neighbour : neighbours) { 
      if (!visited[neighbour.getX()][neighbour.getY()]) { 
       q.add(neighbour); 
       visited[neighbour.getX()][neighbour.getY()] = true; 
       neighbour.parent = next; 
      } 
     } 
+0

사과 질문이 막연하고 불완전하다면, 지금 막 스택 오버플로를 사용하기 시작했습니다. 제대로 질문하지 않았습니다. 내 다음 질문은 부모님을 추적 할 수있는 방법입니다. 내 코드에서 부모 위치는 어디입니까? 나는 처음에 다음 지점을 추적하고 배열의 105 개 이상의 항목 배열로 끝까지 추적하려고했습니다. – Amine

+0

이미 사용 된''visited'' 행렬과 비슷한 부모''Point''를 저장하는''Point'' 행렬을 정의 할 수 있습니다. 다음 노드를 방문한 것으로 표시 할 때 부모를''Point'' 배열로 설정할 수도 있습니다. Btw는 정의한 클래스 또는 java.awt.Point에 정의 된 클래스 인 "Point"클래스입니까? – Nikopol

+0

나는 Point 클래스를 코딩했다. 응답을 주셔서 감사합니다, 그러나 나는 아직도 부모를 얻는 방법을 이해하지 못합니다. 좋아, 나는 부모에게 각 부모를 어떻게 설정합니까? 나는 부모님이 어떻게 설정되어야하는지 정말로 이해하지 못한다. 도움을 주셔서 감사합니다 – Amine