예제 #1
0
  private Stack<Site[]> shortestSiteStack(Site from, Site to) {
    Queue<Site[]> temp = new LinkedList<Site[]>();
    Stack<Site[]> moves = new Stack<Site[]>();

    graph.mark(from);
    for (Site site : graph.neighbors(from)) {
      if (!graph.isMarked(site)) {
        temp.add(new Site[] {from, site});
        graph.mark(site);
      }
    }

    while (!temp.isEmpty()) {
      Site[] sites = temp.poll();
      moves.push(sites);
      if (sites[1].equals(to)) break;
      for (Site site : graph.neighbors(sites[1])) {
        if (!graph.isMarked(site)) {
          temp.add(new Site[] {sites[1], site});
          graph.mark(site);
        }
      }
    }
    graph.clearMarks();

    return moves;
  }
예제 #2
0
  /**
   * Implements a bidirectional breadth-first search to find the shortest path between Sites from
   * and to. Currently not completely implemented. More detailed notes in the code for the method.
   * If it worked it would be quadratic (O(n^2)), but would still be a bit faster than a non-bidi
   * search.
   *
   * @param from Starting position
   * @param to Ending position
   * @return Stack of Sites containing the shortest path in order to be taken.
   */
  public Stack<Site> bidiShortestSiteStack(Site from, Site to) {
    boolean fFound = false, tFound = false;
    Site fConnectSite = null, tConnectSite = null;
    Queue<Site[]> fTemp = new LinkedList<Site[]>(), tTemp = new LinkedList<Site[]>();
    ArrayList<Site> fromList = new ArrayList<Site>(), toList = new ArrayList<Site>();
    Stack<Site[]> fMoves = new Stack<Site[]>(), tMoves = new Stack<Site[]>();
    Stack<Site> moves = new Stack<Site>();

    graph.mark(from);
    for (Site site : graph.neighbors(from)) {
      if (site.equals(to)) {}
      fTemp.add(new Site[] {from, site});
      graph.mark(site);
      fromList.add(site);
    }

    graph.mark(to);
    for (Site site : graph.neighbors(to)) {
      tTemp.add(new Site[] {to, site});
      if (graph.isMarked(site) && fromList.contains(site)) {
        tFound = true;
        break;
      }
      toList.add(site);
      graph.mark(site);
    }

    if (tFound) {
      moves.add(to);
      return moves;
    }

    bigBreak:
    while (!fTemp.isEmpty() && !tTemp.isEmpty()) {
      Site[] fSites = fTemp.poll();
      fMoves.push(fSites);

      Site[] tSites = tTemp.poll();
      tMoves.push(tSites);

      for (Site site : graph.neighbors(fSites[1])) {
        fTemp.add(new Site[] {fSites[1], site});
        if (graph.isMarked(site) && toList.contains(site)) {
          fromList.add(site);
          fConnectSite = site;
          fFound = true;
          break bigBreak;
        } else graph.mark(site);
      }

      for (Site site : graph.neighbors(tSites[1])) {
        tTemp.add(new Site[] {tSites[1], site}); // I chose to put them in the same way.
        // While this does make it a bit more difficult to code, the consistency makes it less
        // confusing.
        if (graph.isMarked(site) && fromList.contains(site)) {
          toList.add(site);
          tConnectSite = site;
          tFound = true;
          break bigBreak;
        } else graph.mark(site);
      }
    }
    if (fFound) {
      Stack<Site> fTempMoves = pathFromStack(from, fMoves);
      Site[] sites = null;
      while (!tMoves.isEmpty()) {
        sites = tMoves.pop();
        if (sites[1].equals(fConnectSite)) break;
      }
      fMoves.push(sites);
      Stack<Site> tTempMoves = pathFromStack(to, tMoves);
      // need to combine them
    } else if (tFound) {
      Stack<Site> tTempMoves = pathFromStack(to, tMoves);
      Site[] sites = null;
      while (!fMoves.isEmpty()) {
        sites = fMoves.pop();
        if (sites[1].equals(tConnectSite)) break;
      }
      tMoves.push(sites);
      Stack<Site> fTempMoves = pathFromStack(from, fMoves);
      // need to combine them
    }
    return moves;
  }