Отладка / исправление алгоритма BFS - PullRequest
1 голос
/ 05 мая 2011

Я решаю эту домашнюю задачу BFS, я верю, что логика, которой я следую, верна, но я застрял в ошибке реализации, которую не могу точно определить.Я ищу помощь в отладке этого решения, а не в предложении нового.

Постановка задачи:

У ребенка есть два робота, которыми он управляет удаленно,оба робота находятся на шахматной доске NxN и должны быть расположены в положениях A и B на шахматной доске.

Пульт дистанционного управления воздействует на обоих роботов одновременно, одна и та же команда влияет на оба их состояния.

Пульт дистанционного управления может одновременно поворачивать обоих роботов по часовой стрелке или против часовой стрелки на 90 градусов или приказывать обоим роботам двигаться вперед.

Пример: Крайнее левое изображение показывает начальную настройку.Стрелка, указывающая вправо, - это робот, обращенный на восток, а стрелка, направленная вверх, - это робот, обращенный на север.Позиции А и В - это судьбы роботов.

На центральном изображении показан результат перемещения обоих роботов на один шаг вперед.

На правом изображении показан результат вращения робота против часовой стрелки.

Figure 1

Ребенок хочет рассчитать минимальное количество движений, необходимое для перемещения роботов из их начальных положений в их судьбы.

Если роботу приказано бегать по стене, он останется на том же месте.

Оба робота останутся на своем первоначальном месте, если им будет приказано перейти в одно и то же место.

На рисунке 2 показаны эти особые случаи.

enter image description here

Оба робота должны одновременно прибыть в другую судьбу.

Ввод: Ввод состоит из различных тестовых случаев, первая строка начинается с целого числа с размером N inputMatrix (шахматной доски), с 2 <= N <= 25.</p>

Следующие N строк описывают шахматную доску и имеют по N символов каждая.

A '.'обозначает пустую позицию.

N, E, S или O (в переводе с испанского означает Oeste = West) обозначает исходную позицию a и ориентацию робота.

D указывает судьбу робота на шахматной доске, а '*' обозначает препятствие.

Ввод заканчивается регистром, в котором N = 0.

input.txt

5
D....
N...S
.....
*...*
....D
5
.....
S..S.
.....
.....
D..D.
3
SN.
***
.DD
0

правильный вывод для input.txt:

8
3
-1

input2.txt:

5
.....
..D.S
.D...
.....
..N..
6
......
..S...
......
.ED...
......
.D....
11
....E......
....D......
...........
..S...D....
...........
...........
...........
...........
...........
...........
...........
13
.............
.............
.............
.............
.....N.......
.............
.........D...
..D..........
.............
...E.........
.............
.............
.............
25
...*.......*.*...........
........*..D...*.**....*.
*..*.*.........*..*..*..D
...*.**.*........*...*...
......**..*..***.***...**
.............*...........
....*...***.....*.**.....
......**.......**.*.*...*
.........*..*...*.*......
....**.*.*....**.*.*.*.*.
.......*............**...
..........*.*.....*......
...........**....*.**....
.....E.*.*..........**.*.
.........*.*.*.*..*..*...
*........**...*..........
................***..*...
........*....*....*...*..
......*...*.*...*.....**.
...*..........*.**.......
.**............*.*..*.*..
........*........*...*...
*......*..........*......
*...*......N*......*..*.*
.    .....*..*.*..*...*......
0

"правильный"(?) вывод для input2.txt:

-1
-1
9
-1
46

Мое решение:

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;




class Position {

    int i;
    int j;
    char orientation;

        Position() {

    }


    void setIJ(int i, int j){
        this.i=i;
        this.j=j;
    }

    void setOrientation(char c){

        orientation = c;
    }

   public boolean equals(Object o){

        if(o instanceof Position){

          Position p = (Position)o;
          if((p.i==this.i)&&(p.j==this.j)&&(p.orientation==this.orientation))
          {
              return true;
          }
              else return false;
          }

            return false;
   }

} //end class Position


class TransitionState {

    Position positionA;
    Position positionB;

    int counter;

    public boolean equals (Object o){

        if (o instanceof TransitionState){

          TransitionState transitionState= (TransitionState)o;

          if ((this.positionA.equals(transitionState.positionA))
                  &&(this.positionB.equals(transitionState.positionB)))
          {
              return true;
          }
        }
     return false;

    }

}


public class Robots {

static Position moveForward(Position oldPosition, int matrixSize, char orientation, char [][] inputMatrix){

     // add possible new Position
    Position newPosition= new Position();

    //first return oldPosition in border positions in which the robot shouldn't move

    if ((orientation=='O')&&(oldPosition.j==0))
           return oldPosition;

    if ((orientation=='E')&&(oldPosition.j==(matrixSize-1)))
           return oldPosition;

     if ((orientation=='N')&&(oldPosition.i==0))
           return oldPosition;

     if ((orientation=='S')&&(oldPosition.i==(matrixSize-1)))
           return oldPosition;


     if ((orientation=='O'))
         newPosition.setIJ(oldPosition.i, oldPosition.j-1);
     if ((orientation=='E'))
         newPosition.setIJ(oldPosition.i, oldPosition.j+1);
    if ((orientation=='S'))
         newPosition.setIJ(oldPosition.i-1, oldPosition.j);
    if ((orientation=='N'))
         newPosition.setIJ(oldPosition.i+1, oldPosition.j);


    //return oldPosition for positions in which the robot is blocked by *
    if (inputMatrix[newPosition.i][newPosition.j]=='*'){
        return oldPosition;
    }

    return newPosition; // if it got here, all ok

}


static char turnCounter (char orientation){

     if(orientation=='N')
         return 'O';
     if(orientation=='O')
         return 'S';
     if (orientation=='S')
         return 'E';
     else
         return 'N';

 }

static char turnClock(char orientation){

      if(orientation=='N')
         return 'E';
     if(orientation=='E')
         return 'S';
         if (orientation=='S')
         return 'O';
     else
         return 'N';

 }

static Position[] robotInitialPositions(char [][]inputMatrix){

     Position [] helperArray = new Position[2];

     int aux=0;

     for (int i=0; i<(inputMatrix[0].length); i++)
         for (int j=0; j<(inputMatrix[0].length); j++)
         {
            if((inputMatrix[i][j]=='N')||(inputMatrix[i][j]=='S')||(inputMatrix[i][j]=='O')||(inputMatrix[i][j]=='E'))
            {
                    helperArray[aux]= new Position();
                    helperArray[aux].setIJ(i, j);
                    if (inputMatrix[i][j]=='N'){helperArray[aux].orientation='N'; }
                    if (inputMatrix[i][j]=='S'){helperArray[aux].orientation='S'; }
                    if (inputMatrix[i][j]=='E'){helperArray[aux].orientation='E'; }
                    if (inputMatrix[i][j]=='O'){helperArray[aux].orientation='O'; }
                    aux= aux+1;
            }

         }

     return helperArray;

 }


static Position[] getDestinies(char [][]inputMatrix){

     Position [] helperArray = new Position[2];

     int aux=0;

     for (int i=0; i<(inputMatrix[0].length); i++)
         for (int j=0; j<(inputMatrix[0].length); j++)
         {
            if((inputMatrix[i][j]=='D'))
            {
                    helperArray[aux]= new Position();
                    helperArray[aux].i=i; helperArray[aux].j=j;
                    helperArray[aux].orientation='D';
                    aux=aux+1;

            }

         }

     return helperArray;

 }



static boolean [][]getUnvisitedMatrix(int matrixLength){


   boolean[][] unvisitedMatrix = new boolean [matrixLength][matrixLength];

    for (int i=0; i<matrixLength;i++)
        for (int j=0; j<matrixLength; j++)
            unvisitedMatrix[i][j]=false;

    return unvisitedMatrix;

}





static Position[]getNewRobotPositions (Position oldR1Pos,Position oldR2Pos, String movement, char [][]inputMatrix){

    Position[]newPositions = new Position[2];

    Position newR1Pos = new Position();
        Position newR2Pos = new Position();

    if(movement.equals("counter")){

        if (oldR1Pos.orientation=='N'){

            newR1Pos.orientation='O';

        }

        if (oldR1Pos.orientation=='S'){

            newR1Pos.orientation='E';

        }

        if (oldR1Pos.orientation=='E'){

            newR1Pos.orientation='N';

        }

        if (oldR1Pos.orientation=='O'){

            newR1Pos.orientation='S';
        }


        if (oldR2Pos.orientation=='N'){

            newR2Pos.orientation='O';
        }

        if (oldR2Pos.orientation=='S'){

            newR2Pos.orientation='E';

        }

        if (oldR2Pos.orientation=='E'){

            newR2Pos.orientation='N';

        }

        if (oldR2Pos.orientation=='O'){

            newR2Pos.orientation='S';

        }

        newR1Pos.i=oldR1Pos.i;
        newR1Pos.j=oldR1Pos.j;

        newR2Pos.i=oldR2Pos.i;
        newR2Pos.j=oldR2Pos.j;

        newPositions[0]=newR1Pos;
        newPositions[1]=newR2Pos;

//        System.out.println("MOVED COUNTERCLOCKWISE");
//        System.out.println("previous Robot 1 position was "+oldR1Pos.i + ","+oldR1Pos.j + " orientation was " + oldR1Pos.orientation +
//        " new Robot 1 position is " + newR1Pos.i + "," + newR1Pos.j+ " orientation is "+newR1Pos.orientation);
//
//        System.out.println("previous Robot 2 position was "+oldR2Pos.i + ","+oldR2Pos.j + " orientation was " + oldR2Pos.orientation +
//        " new Robot 2 position is " + newR2Pos.i + "," + newR2Pos.j+ " orientation is "+newR2Pos.orientation);

        return newPositions;


    }

    if(movement.equals("clock")){

        newR1Pos.i = oldR1Pos.i;
        newR1Pos.j = oldR1Pos.j;

        newR2Pos.i = oldR2Pos.i;
        newR2Pos.j = oldR2Pos.j;


        if (oldR1Pos.orientation=='N'){

             newR1Pos.orientation= 'E';
        }

        if (oldR1Pos.orientation=='S'){

             newR1Pos.orientation= 'O';
        }

        if (oldR1Pos.orientation=='E'){

             newR1Pos.orientation= 'S';
        }

        if (oldR1Pos.orientation=='O'){

             newR1Pos.orientation= 'N';

        }



        if (oldR2Pos.orientation=='N'){

             newR2Pos.orientation= 'E';
        }

        if (oldR2Pos.orientation=='S'){

             newR2Pos.orientation= 'O';

        }

        if (oldR2Pos.orientation=='E'){

             newR2Pos.orientation= 'O';

        }

        if (oldR2Pos.orientation=='O'){

             newR2Pos.orientation= 'N';

        }
//        System.out.println("MOVED CLOCKWISE");
//        System.out.println("previous Robot 1 position was "+oldR1Pos.i + ","+oldR1Pos.j + " orientation was " + oldR1Pos.orientation +
//        " new Robot 1 position is " + newR1Pos.i + "," + newR1Pos.j+ " orientation is "+newR1Pos.orientation);
/    /
//        System.out.println("previous Robot 2 position was "+oldR2Pos.i + ","+oldR2Pos.j + " orientation was " + oldR2Pos.orientation +
//        " new Robot 2 position is " + newR2Pos.i + "," + newR2Pos.j+ " orientation is "+newR2Pos.orientation);


        newPositions[0]=newR1Pos;
        newPositions[1]=newR2Pos;

        return newPositions;

    }

    if(movement.equals("forward")){

        //default case, if conditions not satisfied
        newR1Pos.i=oldR1Pos.i;
        newR1Pos.j=oldR1Pos.j;
            newR1Pos.orientation = oldR1Pos.orientation;

        newR2Pos.i=oldR2Pos.i;
        newR2Pos.j=oldR2Pos.j;
        newR2Pos.orientation = oldR2Pos.orientation; 


        if(oldR1Pos.orientation=='N'){

            if(oldR1Pos.i-1>=0){   //doesn't exceed the upper border

               //doesn't collide with '*'
               if (inputMatrix[oldR1Pos.i-1][oldR1Pos.j]!='*'){
                        newR1Pos.i=oldR1Pos.i-1;
                        newR1Pos.j=oldR1Pos.j;
                        newR1Pos.orientation = oldR1Pos.orientation;
               }

            }

        }

         if(oldR1Pos.orientation=='S'){

             if(oldR1Pos.i+1<inputMatrix.length){   //doesn't exceed the lower border

               //doesn't collide with '*'
               if (inputMatrix[oldR1Pos.i+1][oldR1Pos.j]!='*'){
                        newR1Pos.i=oldR1Pos.i+1;
                        newR1Pos.j=oldR1Pos.j;
                        newR1Pos.orientation = oldR1Pos.orientation;

               }
           }
        }

         if(oldR1Pos.orientation=='E'){

             if(oldR1Pos.j+1<inputMatrix.length){   //doesn't exceed the right border

               //doesn't collide with '*'
               if (inputMatrix[oldR1Pos.i][oldR1Pos.j+1]!='*'){
                        newR1Pos.i=oldR1Pos.i;
                        newR1Pos.j=oldR1Pos.j+1;
                        newR1Pos.orientation = oldR1Pos.orientation;
               }
           }

        }

        if(oldR1Pos.orientation=='O'){

             if(oldR1Pos.j-1>=0){   //doesn't exceed the left border

               //doesn't collide with '*'
               if (inputMatrix[oldR1Pos.i][oldR1Pos.j-1]!='*'){
                        newR1Pos.i=oldR1Pos.i;
                        newR1Pos.j=oldR1Pos.j-1;
                        newR1Pos.orientation = oldR1Pos.orientation;
               }

            }

        }

        //same for robot 2

       if(oldR2Pos.orientation=='N'){

            if(oldR2Pos.i-1>=0){   //doesn't exceed the upper border

               //doesn't collide with '*'
               if (inputMatrix[oldR2Pos.i-1][oldR2Pos.j]!='*'){
                        newR2Pos.i=oldR2Pos.i-1;
                        newR2Pos.j=oldR2Pos.j;
                        newR2Pos.orientation=oldR2Pos.orientation;
               }

            }

        }

         if(oldR2Pos.orientation=='S'){

             if(oldR2Pos.i+1<inputMatrix.length){   //doesn't exceed the lower border

               //doesn't collide with '*'
               if (inputMatrix[oldR2Pos.i+1][oldR2Pos.j]!='*'){
                        newR2Pos.i=oldR2Pos.i+1;
                        newR2Pos.j=oldR2Pos.j;
                        newR2Pos.orientation=oldR2Pos.orientation;
               }
           }
        }

         if(oldR2Pos.orientation=='E'){

             if(oldR2Pos.j+1<inputMatrix.length){   //doesn't exceed the right border

               //doesn't collide with '*'
               if (inputMatrix[oldR2Pos.i][oldR2Pos.j+1]!='*'){
                        newR2Pos.i=oldR2Pos.i;
                        newR2Pos.j=oldR2Pos.j+1;
                        newR2Pos.orientation=oldR2Pos.orientation;
               }
           }

        }

        if(oldR2Pos.orientation=='O'){

             if(oldR2Pos.j-1>=0){   //doesn't exceed the left border

               //doesn't collide with '*'
               if (inputMatrix[oldR2Pos.i][oldR2Pos.j-1]!='*'){
                        newR2Pos.i=oldR2Pos.i;
                        newR2Pos.j=oldR2Pos.j-1;
                        newR2Pos.orientation=oldR2Pos.orientation;
               }

            }

        }


        //if robots collide in new positions, revert to their original positions
        if ((newR1Pos.i==newR2Pos.i) && (newR1Pos.j==newR2Pos.j)){

            //revert robot 1 position
             newR1Pos.i=oldR1Pos.i;
             newR1Pos.j=oldR1Pos.j;
             newR1Pos.orientation = oldR1Pos.orientation;

             //revert robot 2 position
             newR2Pos.i=oldR2Pos.i;
             newR2Pos.j=oldR2Pos.j;
             newR2Pos.orientation = oldR2Pos.orientation;
        }

        newPositions[0] = newR1Pos;
        newPositions[1] = newR2Pos;

//        System.out.println("MOVED FORWARD");
//         System.out.println("previous Robot 1 position was "+oldR1Pos.i + ","+oldR1Pos.j + " orientation was " + oldR1Pos.orientation +
//        " new Robot 1 position is " + newR1Pos.i + "," + newR1Pos.j+ " orientation is "+newR1Pos.orientation);
//
//        System.out.println("previous Robot 2 position was "+oldR2Pos.i + ","+oldR2Pos.j + " orientation was " + oldR2Pos.orientation +
//        " new Robot 2 position is " + newR2Pos.i + "," + newR2Pos.j+ " orientation is "+newR2Pos.orientation);

    } //end movement.equals("forward")


    return newPositions;

}


//1  procedure BFS(Graph,source):
//2      create a queue Q
//3      enqueue source onto Q
//4      mark source
//5      while Q is not empty:
//6          dequeue an item from Q into v
//7          for each edge e incident on v in Graph:
//8              let w be the other end of e
//9              if w is not marked:
//10                 mark w
//11                 enqueue w onto Q



 static void BFS (char [][] inputMatrix){

    ArrayList<TransitionState> transitionStatesArray = new ArrayList<TransitionState>();

    int moveCounter=0; //turns and forward movements add here

    int tempMoveCounterRobot1=0; int tempMoveCounterRobot2=0;
    int maxMoveCounter=0;

    PositionsAndCounter positionsAndCounter= new PositionsAndCounter();

    Queue <PositionsAndCounter>queue = new LinkedList<PositionsAndCounter>();

    Position robotInitial[] = robotInitialPositions(inputMatrix); //get source
    positionsAndCounter.positionPair=robotInitial; //used to encapsulate the positions with a counter to output
    positionsAndCounter.counter=0;//first initialize to 0

    Position destinies[] = getDestinies(inputMatrix); //get destinies


    TransitionState firstTransitionState = new TransitionState();
    firstTransitionState.positionA=robotInitial[0];
    firstTransitionState.positionB=robotInitial[1];

    transitionStatesArray.add(firstTransitionState);

    //mark transition used , if the transition is new, it should be queued

    queue.add(positionsAndCounter);

    String [] movement =  {"forward", "counter", "clock"}; 
    //possible movements inside inputMatrix


    outer: while (!queue.isEmpty()){ //while queue is not empty

         PositionsAndCounter v= queue.poll(); //dequeue an item from Q into V

         for(int k = 0; k<3; k++){ //for each edge e incident on v in Graph:

            Position[] newRobotPositions = getNewRobotPositions(v.positionPair[0], v.positionPair[1], movement[k], inputMatrix);

            TransitionState newTransitionState = new TransitionState();
            newTransitionState.positionA=newRobotPositions[0];
            newTransitionState.positionB=newRobotPositions[1];

            if(!transitionStatesArray.contains(newTransitionState)){  //if the transition state is new add and enqueue new robot positions

                 transitionStatesArray.add(newTransitionState);

                   //if transition is new then queue
                 PositionsAndCounter newPositionsAndCounter = new PositionsAndCounter();
                 newPositionsAndCounter.positionPair=newRobotPositions;
                 newPositionsAndCounter.counter = v.counter +1;


                  queue.add(newPositionsAndCounter);


             }


             inputMatrix[v.positionPair[0].i][v.positionPair[1].j]='.'; 
             inputMatrix[v.positionPair[1].i][v.positionPair[1].j]='.';

             //inputMatrix[v[0].i][v[0].j]='.'; // mark old position of robot 1 with .
             //inputMatrix[v[1].i][v[1].j]='.'; // mark old position of robot 2 with .

             //update new robot positions
             inputMatrix[newRobotPositions[0].i][newRobotPositions[0].j]= newRobotPositions[0].orientation;
             inputMatrix[newRobotPositions[1].i][newRobotPositions[1].j]= newRobotPositions[1].orientation;


             //check if solution has been found
                   if
                   (
                   ((destinies[0].i==newRobotPositions[0].i)&&(destinies[0].j==newRobotPositions[0].j) //robot in 0 arrived to destiny
                   || (destinies[1].i==newRobotPositions[0].i)&&(destinies[1].j==newRobotPositions[0].j))// in 0 or 1
                        &&                                                                                                      //and 
                  ((destinies[0].i==newRobotPositions[1].i)&&(destinies[0].j==newRobotPositions[1].j) //robot in 1 arrived to destiny
                  || (destinies[1].i==newRobotPositions[0].i)&&(destinies[1].j==newRobotPositions[0].j))//in 0 or 1

                   ) //end if
                   {

                      System.out.println("robots arrived at destinies");
                      System.out.println("robot 1, starting at " + robotInitial[0].i + "," + robotInitial[0].j
                               + " is in " + newRobotPositions[0].i + ","+ newRobotPositions[0].j);
                      System.out.println("robot 2, starting at " + robotInitial[1].i + "," + robotInitial[1].j
                               + " is in " + newRobotPositions[1].i + ","+ newRobotPositions[1].j);

                     System.out.println("movements: " + (v.counter));

                     return;
                     //break outer;

                   }


                }

            }

            System.out.println("robots can never arrive at their destinies");
            System.out.println(-1);


    }


static void printInputMatrix(char [][] inputMatrix){


    for (int i=0; i<inputMatrix[0].length;i++)
        for(int j=0; j<inputMatrix[0].length;j++)
        {

            System.out.print(" "+inputMatrix[i][j]+" ");
            if(j==inputMatrix[0].length-1){System.out.println("");}

        }


}





    public static void main(String[] args) throws IOException {

//        System.out.println("Test transition checker");
//        Position p1 = new Position();
//        p1.i=1;
//        p1.j=1;
//        p1.orientation='N';
//        Position p2 = new Position();
//        p2.i=1;
//        p2.j=2;
//        p2.orientation='N';
//        Position p3 = new Position();
//        p3.i=1;
//        p3.j=1;
//        p3.orientation='N';
//        Position p4 = new Position();
//        p4.i=1;
//        p4.j=1;
//        p4.orientation='N';
//
//        TransitionState transitionChecker1 = new TransitionState();
//        transitionChecker1.positionA=p1;
//        transitionChecker1.positionB=p2;
//
//        TransitionState transitionChecker2 = new TransitionState();
//        transitionChecker2.positionA=p1;
//        transitionChecker2.positionB=p2;
//
//
//        ArrayList<TransitionState> arrayTransitions = new ArrayList<TransitionState>();
//        arrayTransitions.add(transitionChecker1);
//        System.out.println("Test contains? " + arrayTransitions.contains(transitionChecker2));




        BufferedReader br = new BufferedReader(new FileReader(new File("input.txt")));

        char [][] inputMatrix;

        String line;
        char [] lineAsCharArray;
        int matrixSize;

        while(true){

            line = br.readLine();
            matrixSize=Integer.parseInt(line);

            inputMatrix = new char [matrixSize][matrixSize];

            if (matrixSize==0){  // end outer looping
                break;
            }

            else { //begin inner looping

                for (int i=0; i<matrixSize; i++){

                    line = br.readLine();
                    inputMatrix[i] =line.toCharArray();

                }

                //matrix loaded

                BFS(inputMatrix);

            }


        }

    }

}

class PositionsAndCounter {

    Position[] positionPair;
    int counter;

    PositionsAndCounter() {
        positionPair = new Position[2];
        counter=0;

    }
}

Проблемы: 1) На первом входе.txt файл, он находит 9 движений, чтобы найти решение первого курса (когда они должны быть 8) и 6, чтобы найти решение второго курса (когда это должно быть 3), хотя он правильно выводит -1 для последнего курса(невозможно) настройка курса.

2) Во втором файле input.txt профессор говорит, что он должен напечатать -1 и -1 для первых курсов, хотя моя программа находит вероятное решение для второго случая истранный для первого (это, где я думаю, что более опытный отладчик мог бы помочь, я затрудняюсь отследить причину вывода перемещенной судьбы в первом случае).Верны ли результаты, предложенные моим профессором?Мой алгоритм также застревает в том случае, когда 46 должно быть напечатано.

1 Ответ

4 голосов
/ 05 мая 2011

2 неосторожные проблемы с копированием и вставкой приводят к тому, что код не работает, 1, в поворотной части по часовой стрелке:

        if (oldR2Pos.orientation == 'E') {

            newR2Pos.orientation = 'O';

        }

Это неправильно ... это должно быть прямое копирование и вставка из вышеуказанного блока

        if (oldR2Pos.orientation == 'E') {

            newR2Pos.orientation = 'S';
        }

И все же ты пропустил это.

Другая проблема на самом деле в блоке проверки конечного состояния

     //check if solution has been found
           if
           (
           ((destinies[0].i==newRobotPositions[0].i)&&(destinies[0].j==newRobotPositions[0].j) //robot in 0 arrived to destiny
           || (destinies[1].i==newRobotPositions[0].i)&&(destinies[1].j==newRobotPositions[0].j))// in 0 or 1
                &&                                                                                                      //and 
          ((destinies[0].i==newRobotPositions[1].i)&&(destinies[0].j==newRobotPositions[1].j) //robot in 1 arrived to destiny
          || **(destinies[1].i==newRobotPositions[0].i)&&(destinies[1].j==newRobotPositions[0].j)**)//in 0 or 1

           ) //end if

Последняя часть (выделенный код) должна быть

(destinies[1].i==newRobotPositions[1].i)&&(destinies[1].j==newRobotPositions[1].j)

Это, очевидно, копирование и вставка, но забудьте об ошибке. Логика немного сложна для понимания, но работает,

(A в X или B в Y) и (A в Y или B в X)

Хотя это одно и то же (логически не совсем то же самое, но в некотором смысле это работает для вашего случая, так как A и B не могут занимать одно и то же место), гораздо понятнее, если вы используете

(A в X и B в Y) или (A в Y и B в X)

Помимо неустранимых ошибок, указанных выше, в вашей программе необходимо решить еще несколько проблем. Похоже, что вы студент университета, изучающий информатику, пожалуйста, прочитайте данный исходный код перед кодированием: класс TransistionState не используется в все, кроме того, что вы создали свой собственный PositionsAndCounter, логика поворота реализована дважды, если вы не переписали код поворота и не используете указанный код, вы не совершите задачу 1 .... Если бы я был вашим профессором, я мог бы потерпеть неудачу Вы на это. Хорошо спланируйте свое решение, прежде чем нажимать на клавиатуру, и убедитесь, что ваш код понятен и читаем как план английского, если вы смотрите на свой исходный код в течение 5 минут и не можете понять, для чего предназначен блок кода, возможно, вы этого не сделали структурируйте его правильно.

Ниже приведен пример решения вашего вопроса:

import java.awt.Point;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;


public class DualRobot {

    public enum Orientation{
        E(1, 0), S(0, 1), O(-1, 0), N(0, -1);

        public final int dx, dy;
        private Orientation(int dx, int dy){
            this.dx = dx;
            this.dy = dy;
        }

        public Orientation left(){
            return Orientation.values()[(this.ordinal() + 3) % 4];
        }

        public Orientation right(){
            return Orientation.values()[(this.ordinal() + 1) % 4];
        }

        public static Orientation valueOf(char c){
            for(Orientation o : Orientation.values()){
                if(o.toString().equalsIgnoreCase("" + c)) return o;
            }
            return null;
        }

    }

    public enum Action {FORWARD, COUNTER_CLOCKWISE, CLOCKWISE}; // F: forward, L: Counter clockwise, R: clockwise

    private static class Robot{
        Point position;
        Orientation orientation;

        public Robot(Robot r){
            this.position = new Point(r.position);
            this.orientation = r.orientation;
        }
        public Robot(int x, int y, Orientation orientation){
            this.position = new Point(x, y);
            this.orientation = orientation;
        }

        public void move(Action action, char[][] map){
            switch (action) {
            case FORWARD:
                Point nextPosition = new Point(position);
                nextPosition.translate(orientation.dx, orientation.dy);
                if(isValidPosition(nextPosition, map)) position = nextPosition;
                break;
            case COUNTER_CLOCKWISE:
                this.orientation = this.orientation.left();
                break;
            case CLOCKWISE:
                this.orientation = this.orientation.right();
                break;
            }
        }

        @Override
        public boolean equals(Object obj) {
            if (obj instanceof Robot) {
                Robot r = (Robot) obj;
                return r.position.equals(this.position) && r.orientation == this.orientation;
            }
            return super.equals(obj);
        }

        @Override
        public int hashCode() {
            return orientation.ordinal() + position.x * 10 + position.y * 1000;
        }

        private boolean isValidPosition(Point p, char[][] map){
            return p.x >= 0 && p.x < map[0].length 
                && p.y >= 0 && p.y < map.length
                && map[p.y][p.x] != '*';
        }
    }

    private static class State{
        private Robot a, b;
        private int counter;

        public State(Robot a, Robot b, int counter) {
            this.a = new Robot(a);
            this.b = new Robot(b);
            this.counter = counter;
        }

        public List<State> nextStates(char[][] map){
            List<State> states = new ArrayList<State>();
            for(Action action : Action.values()){
                State s = new State(this.a, this.b, this.counter + 1);
                s.a.move(action, map);
                s.b.move(action, map);
                if(!s.a.position.equals(s.b.position)){ // Test for collision
                    states.add(s);
                }
            }
            return states;
        }

        @Override
        public boolean equals(Object obj) {
            if (obj instanceof State) {
                State state = (State) obj; // Consider the state to be the same if the 2 robots are at identical location and orientation
                return (this.a.equals(state.a) && this.b.equals(state.b))
                    || (this.a.equals(state.b) && this.b.equals(state.a));
            }
            return super.equals(obj);
        }

        @Override
        public int hashCode() {
            // The quality of this hashCode can affect the program's speed
            // Multiply is transitive, so if you swap a and b, the hashcode is the same
            return a.hashCode() * b.hashCode();
        }

    }

    public static void main(String[] args) throws IOException {
        BufferedReader input = new BufferedReader(new FileReader("input.txt"));
        int size;

        while((size = Integer.parseInt(input.readLine())) > 0){
            // Load the data;
            char[][] map = new char[size][size];
            for (int i = 0; i < size; i++) {
                map[i] = input.readLine().toCharArray();
            }

            // Construct initial state
            List<Robot> robots = new ArrayList<Robot>();
            List<Point> destinations = new ArrayList<Point>();
            for(int i = 0; i < size; i ++){
                for(int j = 0; j < size; j ++){
                    Orientation orientation = Orientation.valueOf(map[i][j]);
                    if(orientation != null){
                        robots.add(new Robot(j, i, orientation));
                    }else if(map[i][j] == 'D'){
                        destinations.add(new Point(j, i));
                    }
                }
            }

            System.out.println(BFSSearch(map, new State(robots.get(0), robots.get(1), 0), destinations));

        }

    }

    private static int BFSSearch(char[][] map, State initialState, List<Point> destinations) throws IOException{
        List<State> queue = new LinkedList<State>(); // Array list is slightly more efficient
        queue.add(initialState); // Initial state
        Map<State, Boolean> testedStates = new HashMap<State, Boolean>();
        while(queue.size() > 0){
            State currentState = queue.remove(0);
            if(testedStates.containsKey(currentState)) continue;

            // Testing for end condition
            if((currentState.a.position.equals(destinations.get(0)) && currentState.b.position.equals(destinations.get(1)))
            || (currentState.a.position.equals(destinations.get(1)) && currentState.b.position.equals(destinations.get(0)))){
                return currentState.counter;
            }
            testedStates.put(currentState, true);
            queue.addAll(currentState.nextStates(map));
        }
        return -1;
    }   
}

Эта программа выкладывает окончательный ответ примерно за 10 секунд.

Основное отличие состоит в том, что я использовал хеш-таблицу для хранения тестируемых состояний для повышения скорости, поэтому качество хеш-функции будет влиять на скорость.

Рекомендуемое чтение: хэш-таблица, принцип DRY.

...