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; }
/** * 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; }