Пример #1
0
  /**
   * Implementation of <b>Dijkstra's algorithm</b>.
   *
   * @param sourceDisplacement : source <b>Coordinate</b>.
   * @param destinationDisplacement : destination <b>Coordinate</b>.
   * @param avoidGuardian : a boolean which indicates whether to consider <b>Guardians</b> (<code>
   *     true</code>) or not (<code>false</code>) when calculating the route. (Used to calculate a
   *     route patrol regardless of the position of <b>Guardians</b>).
   * @return a list containing <b>Coordinates</b> steps to move from source <b>Coordinate</b>
   *     (included) to destination <b>Coordinate</b> (included).
   */
  public ArrayList<Coordinate> routeCalculation(
      Coordinate sourceDisplacement, Coordinate destinationDisplacement, boolean avoidGuardian) {
    if (areAdjacent(sourceDisplacement, destinationDisplacement)
        && grid.isValidGuardian(destinationDisplacement)) {
      ArrayList<Coordinate> route = new ArrayList<Coordinate>();
      route.add(sourceDisplacement);
      route.add(destinationDisplacement);
      return route;
    }
    // INITIALISATION
    // toutes les coordonnes valables
    int dimension = grid.getDimension();
    Coordinate coordinates[][] = new Coordinate[dimension][dimension];
    for (int i = 0; i < dimension; i++) {
      for (int j = 0; j < dimension; j++) {
        coordinates[i][j] = new Coordinate(i, j);
      }
    }

    // Coordonnees : la coordonee (cle) dont on connait la plus petite
    // distance (valeur) a la source
    HashMap<Coordinate, Integer> distanceSource = new HashMap<Coordinate, Integer>();

    // Coordonnees : les coordonnes dont il faut verifier la distance
    ArrayList<Coordinate> coordinatesToCheck = new ArrayList<Coordinate>();

    // Coordonnees : les coordonnes dont on a verifié la distance
    ArrayList<Coordinate> coordinatesChecked = new ArrayList<Coordinate>();

    // tableau contenant l'ordre des cases pour le (un des) plus court
    // chemin pour chaque case
    // 1ere coordonnee (cle) : coordonnee dont on veut connaitre le
    // predecesseur
    // 2em coordonee (valeur) : predecesseur de la coordonnee cle
    HashMap<Coordinate, Coordinate> predecessorCoordinate = new HashMap<Coordinate, Coordinate>();

    // source du deplacement
    Coordinate source = coordinates[sourceDisplacement.getCoordX()][sourceDisplacement.getCoordY()];

    // initialisation/remplissage de parcours
    for (int i = 0; i < dimension; i++) {
      for (int j = 0; j < dimension; j++) {
        predecessorCoordinate.put(coordinates[i][j], source);
        distanceSource.put(coordinates[i][j], Integer.MAX_VALUE);
      }
    }

    // ajout de la source dans la Hashmap avec une distance nulle
    distanceSource.put(source, 0);

    // ajout de la source a l'arraylist des cases verifiees, et le reste
    // dans l'arraylist des cases � verifier
    for (int i = 0; i < dimension; i++) {
      for (int j = 0; j < dimension; j++) {
        if (avoidGuardian) {
          if (grid.isValidGuardian(coordinates[i][j])) coordinatesToCheck.add(coordinates[i][j]);
        } else {
          if (grid.isValid(coordinates[i][j])) coordinatesToCheck.add(coordinates[i][j]);
        }
      }
    }

    coordinatesToCheck.remove(source);
    coordinatesChecked.add(source);
    // FIN INITIALISATION

    // pour chaque case valable de la grille
    for (int i = 0; i < coordinatesChecked.size(); i++) {
      Coordinate coordSource = coordinatesChecked.get(i);
      for (int j = 0; j < coordinatesToCheck.size(); j++) {
        Coordinate coordEnCoursDeVerif = coordinatesToCheck.get(j);
        if (areAdjacent(coordSource, coordEnCoursDeVerif)) {
          coordinatesToCheck.remove(coordEnCoursDeVerif);
          coordinatesChecked.add(coordEnCoursDeVerif);
          j--;
          if (distanceSource.get(coordEnCoursDeVerif)
              > distanceSource.get(predecessorCoordinate.get(coordSource)) + 1) {
            distanceSource.put(coordEnCoursDeVerif, distanceSource.get(coordSource) + 1);
            predecessorCoordinate.put(coordEnCoursDeVerif, coordSource);
            //						System.out.println("Coordonnee : " + coordEnCoursDeVerif + " --- distance a la
            // source "+ source +" : " +
            //								distanceSource.get(coordEnCoursDeVerif) + " --- predecesseur pour chemin le
            // plus court : "+
            //								parcours.get(coordEnCoursDeVerif)+" destination "+destination);
            //						 Coordonnee : (10,17) --- distance a la source : 27	 --- predecesseur pour
            // chemin le plus court : (9,17)
          }
        }
      }
    }

    // construire chemin
    ArrayList<Coordinate> reverseRoute = new ArrayList<Coordinate>();
    ArrayList<Coordinate> route = new ArrayList<Coordinate>();
    Coordinate coordTemp =
        coordinates[destinationDisplacement.getCoordX()][destinationDisplacement.getCoordY()];

    reverseRoute.add(destinationDisplacement);

    while (!(predecessorCoordinate.get(coordTemp).equals(source))) {
      reverseRoute.add(predecessorCoordinate.get(coordTemp));
      coordTemp = predecessorCoordinate.get((coordTemp));
    }

    reverseRoute.add(source);

    for (int i = 0; i < reverseRoute.size(); i++) {
      route.add(reverseRoute.get(reverseRoute.size() - i - 1));
    }

    // itineraire.get(0) = coordSource
    // itineraire.get(itineraire.size()-1) = destination
    return route;
  }
Пример #2
0
  /**
   * Calculates patrol's <b>Coordinates</b>.</br>
   *
   * @param guardians : a list of <b>Guardians</b> to share the patrol.
   * @return a list containing the <b>Coordinates</b> checkpoints of the patrol. (Debug)
   */
  public ArrayList<Coordinate> calculCoordinatesPatrouille(ArrayList<Guardian> guardians) {
    // long debut = System.currentTimeMillis();
    int dimension = grid.getDimension();
    // ArrayList de coordonnees pour l'itineraire de patrouille
    ArrayList<Coordinate> validCoordinates = new ArrayList<Coordinate>();
    // ArrayList de coordonnees pour l'itineraire de patrouille
    // HashMap de coordonnees, et de l'ArrayList contenant le champ de vision a partir de cette
    // coordoneee
    HashMap<Coordinate, ArrayList<Coordinate>> visible =
        new HashMap<Coordinate, ArrayList<Coordinate>>();

    // init ArrayList, tableau et HashMap
    for (int i = 0; i < dimension; i++) {
      for (int j = 0; j < dimension; j++) {
        Coordinate coordTemp = new Coordinate(i, j);
        //				System.out.println(grid);
        if (grid.isValid(coordTemp) && grid.isDirectlyAccessible(coordTemp)) {
          validCoordinates.add(coordTemp);
          visible.put(coordTemp, visualFieldCalculation(coordTemp));
        }
      }
    }

    // Remplissage d'une HashMap avec les gardians pour Cle, et une ArrayList de coordonnees
    // atteignables en Valeur
    HashMap<Guardian, ArrayList<Coordinate>> guardianToCoordinates =
        new HashMap<Guardian, ArrayList<Coordinate>>();
    for (Guardian guard : guardians) {
      ArrayList<Coordinate> accessibleCoordinatesGuardian = new ArrayList<Coordinate>();
      for (Coordinate coord : validCoordinates) {
        ArrayList<Coordinate> itineraireTemp = routeCalculation(guard.getPosition(), coord, false);
        if (itineraireTemp.size() > 2
            || areAdjacent(guard.getPosition(), coord)) // Coord accessible
        accessibleCoordinatesGuardian.add(coord);
      }
      accessibleCoordinatesGuardian.add(guard.getPosition());
      Collections.sort(accessibleCoordinatesGuardian, new Tri.SortByCoordinate());
      guardianToCoordinates.put(guard, accessibleCoordinatesGuardian);
    }
    //		System.out.println(guardianVersCoordinates);
    //		System.out.println();
    //		System.out.println();

    // Fusion en ArrayList si plusieurs gardiens ont les mêmes coordonnees atteignables
    HashMap<ArrayList<Coordinate>, ArrayList<Guardian>> coordinatesToGuardians =
        new HashMap<ArrayList<Coordinate>, ArrayList<Guardian>>();
    for (Guardian guard : guardians) {
      ArrayList<Guardian> guardiansCoord =
          coordinatesToGuardians.get(guardianToCoordinates.get(guard));
      if (guardiansCoord == null) {
        guardiansCoord = new ArrayList<Guardian>();
      }
      if (!guardiansCoord.contains(guard)) guardiansCoord.add(guard);
      coordinatesToGuardians.put(guardianToCoordinates.get(guard), guardiansCoord);
    }
    //		System.out.println(coordinatesVersGuardian);
    //		A ce moment, coordinatesVersGuardian contient des ArrayList de coordonnees atteignables
    // comme clé,
    //		et des ArrayList des guardiens qui peuvent les atteindre comme valeur

    // HashMap inverse de CoordinatesVersGuardians
    HashMap<ArrayList<Guardian>, ArrayList<Coordinate>> guardiansToCoordinates =
        new HashMap<ArrayList<Guardian>, ArrayList<Coordinate>>();
    for (ArrayList<Coordinate> alCoord : coordinatesToGuardians.keySet()) {
      guardiansToCoordinates.put(coordinatesToGuardians.get(alCoord), alCoord);
    }

    // initialisation des coordonnes a visiter pour effectuer la patrouille (checkpoint)
    // ne represente pas l'itineraire
    // ne garde que quelques coordonnes cles
    ArrayList<Coordinate> patrolCoordinates = new ArrayList<Coordinate>(validCoordinates);

    // calculer si un ensemble d'ArrayList de coordonnees ne contiendrait pas par hasard toutes les
    // coordonnees visibles depuis une certaine coordonnee
    // calculer si le fait de supprimer une coordonnee enleve des cases visibles a l'ArrayList
    for (int i = 0; i < patrolCoordinates.size(); i++) {
      ArrayList<Coordinate> coordinatesMinusOne = new ArrayList<Coordinate>();
      ArrayList<Coordinate> unsortedVisibleCoordinatesMinusOne = new ArrayList<Coordinate>();
      ArrayList<Coordinate> sortedVisibleCoordinatesMinusOne = new ArrayList<Coordinate>();

      for (Coordinate coordTest : patrolCoordinates) {
        coordinatesMinusOne.add(coordTest);
      }

      Coordinate coordReference = patrolCoordinates.get(i);
      coordinatesMinusOne.remove(coordReference);
      for (Coordinate coordTemp : coordinatesMinusOne) {
        unsortedVisibleCoordinatesMinusOne.addAll(visible.get(coordTemp));
      }

      Set<Coordinate> mySet = new HashSet<Coordinate>(unsortedVisibleCoordinatesMinusOne);
      sortedVisibleCoordinatesMinusOne.addAll(mySet);

      if (sortedVisibleCoordinatesMinusOne.containsAll(validCoordinates)) {
        patrolCoordinates.remove(coordReference);
        i--;
      }
    }

    return patrolCoordinates;
  }
Пример #3
0
  /**
   * Calculates patrol routes (depending on reachable <b>Coordinates</b> by <b>Guardian</b>) to see
   * all the <b>Grid</b>.</br> A patrol route is then assigned to each <b>Guardian</b> (If several
   * <b>Guardians</b> have access to the same <b>Coordinates</b>, their patrol will be the same).
   *
   * @param guardians : a list of <b>Guardians</b> in order to directly assign their patrol route.
   * @return a list containing all the <b>Coordinates</b> of all the patrols routes. (Debug)
   */
  public ArrayList<Coordinate> patrolRouteCalculation(ArrayList<Guardian> guardians) {
    // long debut = System.currentTimeMillis();
    int dimension = grid.getDimension();
    // ArrayList de coordonnees pour l'itineraire de patrouille
    ArrayList<Coordinate> validCoordinates = new ArrayList<Coordinate>();
    // ArrayList de coordonnees pour l'itineraire de patrouille
    // HashMap de coordonnees, et de l'ArrayList contenant le champ de vision a partir de cette
    // coordoneee
    HashMap<Coordinate, ArrayList<Coordinate>> visible =
        new HashMap<Coordinate, ArrayList<Coordinate>>();

    // init ArrayList, tableau et HashMap
    for (int i = 0; i < dimension; i++) {
      for (int j = 0; j < dimension; j++) {
        Coordinate coordTemp = new Coordinate(i, j);
        //				System.out.println(grid);
        if (grid.isValid(coordTemp) && grid.isDirectlyAccessible(coordTemp)) {
          validCoordinates.add(coordTemp);
          visible.put(coordTemp, visualFieldCalculation(coordTemp));
        }
      }
    }

    // Remplissage d'une HashMap avec les gardians pour Cle, et une ArrayList de coordonnees
    // atteignables en Valeur
    HashMap<Guardian, ArrayList<Coordinate>> guardianToCoordinates =
        new HashMap<Guardian, ArrayList<Coordinate>>();
    for (Guardian guard : guardians) {
      ArrayList<Coordinate> accessibleCoordinatesGuardian = new ArrayList<Coordinate>();
      for (Coordinate coord : validCoordinates) {
        ArrayList<Coordinate> itineraireTemp = routeCalculation(guard.getPosition(), coord, false);
        if (itineraireTemp.size() > 2
            || areAdjacent(guard.getPosition(), coord)) // Coord accessible
        accessibleCoordinatesGuardian.add(coord);
      }
      accessibleCoordinatesGuardian.add(guard.getPosition());
      Collections.sort(accessibleCoordinatesGuardian, new Tri.SortByCoordinate());
      guardianToCoordinates.put(guard, accessibleCoordinatesGuardian);
    }
    //		System.out.println(guardianVersCoordinates);
    //		System.out.println();
    //		System.out.println();

    // Fusion en ArrayList si plusieurs gardiens ont les mêmes coordonnees atteignables
    HashMap<ArrayList<Coordinate>, ArrayList<Guardian>> coordinatesToGuardians =
        new HashMap<ArrayList<Coordinate>, ArrayList<Guardian>>();
    for (Guardian guard : guardians) {
      ArrayList<Guardian> guardiansCoord =
          coordinatesToGuardians.get(guardianToCoordinates.get(guard));
      if (guardiansCoord == null) {
        guardiansCoord = new ArrayList<Guardian>();
      }
      if (!guardiansCoord.contains(guard)) guardiansCoord.add(guard);
      coordinatesToGuardians.put(guardianToCoordinates.get(guard), guardiansCoord);
    }
    //		System.out.println(coordinatesVersGuardian);
    //		A ce moment, coordinatesVersGuardian contient des ArrayList de coordonnees atteignables
    // comme clé,
    //		et des ArrayList des guardiens qui peuvent les atteindre comme valeur

    // HashMap inverse de CoordinatesVersGuardians
    HashMap<ArrayList<Guardian>, ArrayList<Coordinate>> guardiansToCoordinates =
        new HashMap<ArrayList<Guardian>, ArrayList<Coordinate>>();
    for (ArrayList<Coordinate> alCoord : coordinatesToGuardians.keySet()) {
      guardiansToCoordinates.put(coordinatesToGuardians.get(alCoord), alCoord);
    }

    // initialisation des coordonnes a visiter pour effectuer la patrouille (checkpoint)
    // ne represente pas l'itineraire
    // ne garde que quelques coordonnes cles
    ArrayList<Coordinate> globalPatrolCoordinates = new ArrayList<Coordinate>(validCoordinates);

    // calculer si un ensemble d'ArrayList de coordonnees ne contiendrait pas par hasard toutes les
    // coordonnees visibles depuis une certaine coordonnee
    // calculer si le fait de supprimer une coordonnee enleve des cases visibles a l'ArrayList
    for (int i = 0; i < globalPatrolCoordinates.size(); i++) {
      ArrayList<Coordinate> coordinatesMinusOne = new ArrayList<Coordinate>();
      ArrayList<Coordinate> unsortedVisibleCoordinatesMinusOne = new ArrayList<Coordinate>();
      ArrayList<Coordinate> sortedVisibleCoordinatesMinusOne = new ArrayList<Coordinate>();

      for (Coordinate coordTest : globalPatrolCoordinates) {
        coordinatesMinusOne.add(coordTest);
      }

      Coordinate coordReference = globalPatrolCoordinates.get(i);
      coordinatesMinusOne.remove(coordReference);
      for (Coordinate coordTemp : coordinatesMinusOne) {
        unsortedVisibleCoordinatesMinusOne.addAll(visible.get(coordTemp));
      }

      Set<Coordinate> mySet = new HashSet<Coordinate>(unsortedVisibleCoordinatesMinusOne);
      sortedVisibleCoordinatesMinusOne.addAll(mySet);

      if (sortedVisibleCoordinatesMinusOne.containsAll(validCoordinates)) {
        globalPatrolCoordinates.remove(coordReference);
        i--;
      }
    }

    ArrayList<Coordinate> allPatrolsRoutes = new ArrayList<Coordinate>();

    // debut boucle
    for (ArrayList<Guardian> alGuardian : coordinatesToGuardians.values()) {
      // On ne garde que les coordonnees atteignables par le groupe de gardiens
      ArrayList<Coordinate> groupPatrolCoordinates =
          new ArrayList<Coordinate>(globalPatrolCoordinates);

      //			for(Coordinates coord : coordinatesPatrouilleGroupe) {
      //				if(!guardiansVersCoordinates.get(alGuardian).contains(coord))
      //					coordinatesPatrouilleGroupe.remove(coord);
      //			}
      for (int i = 0; i < groupPatrolCoordinates.size(); i++) {
        Coordinate coord = groupPatrolCoordinates.get(i);
        if (!guardiansToCoordinates.get(alGuardian).contains(coord)) {
          groupPatrolCoordinates.remove(coord);
          i--;
        }
      }

      TreeMap<Integer, Coordinate> patrolRoute = new TreeMap<Integer, Coordinate>();

      // Si aucun checkpoint accessible
      if (groupPatrolCoordinates.size() == 0) {
        for (Guardian guardTemp : alGuardian) {
          guardTemp.setPatrolPosition(-2);
        }
      } else {

        ArrayList<Coordinate> routeFinal = new ArrayList<Coordinate>();
        ArrayList<Coordinate> routeTemp = new ArrayList<Coordinate>();

        Coordinate coordSource = groupPatrolCoordinates.get(0);
        Coordinate coordSourceTemp = coordSource;
        Coordinate coordTemp = null;

        int index = 0;

        while (groupPatrolCoordinates.size() > 0) {
          groupPatrolCoordinates.remove(coordSourceTemp);
          routeFinal.clear();
          routeTemp.clear();

          for (Coordinate coordDestinationTemp : groupPatrolCoordinates) {
            routeTemp = routeCalculation(coordSourceTemp, coordDestinationTemp, false);
            // System.out.println("Itineraire " + coordSourceTemp + " vers " + coordDestinationTemp
            // + " : " + itineraireTemp);
            if (routeFinal.size() == 0
                || (routeTemp.size() != 0 && routeTemp.size() < routeFinal.size())) {
              routeFinal = new ArrayList<Coordinate>(routeTemp);
              coordTemp = coordDestinationTemp;
            }
          }
          // System.out.println(itineraireFinal);
          coordSourceTemp = coordTemp;
          for (int i = 0; i < routeFinal.size() - 1; i++) {
            patrolRoute.put(index, routeFinal.get(i));
            index++;
          }
        }

        // Ajout de l'itineraire pour aller e la fin de la patrouille vers le debut
        routeFinal = routeCalculation(coordTemp, coordSource, false);
        for (int i = 0; i < routeFinal.size() - 1; i++) {
          patrolRoute.put(index, routeFinal.get(i));
          index++;
        }

        // affectation de la patrouille a tous les gardiens, a modifier
        for (Guardian guardTemp : alGuardian) {
          guardTemp.setPatrol(patrolRoute);
          guardTemp.setReachableCoordinates(guardiansToCoordinates.get(alGuardian));
        }
        allPatrolsRoutes.addAll(patrolRoute.values());
      }
      // fin boucle
    }
    // entre 100 et 1000ms en fonction de la taille (complexite lineaire)
    // System.out.println(System.currentTimeMillis() - debut);
    // System.out.println(itinerairePatrouille);

    return allPatrolsRoutes;
  }