001 // GraphLab Project: http://graphlab.sharif.edu 002 // Copyright (C) 2008 Mathematical Science Department of Sharif University of Technology 003 // Distributed under the terms of the GNU Lesser General Public License (LGPL): http://www.gnu.org/licenses/ 004 005 /* 006 * BreadthFirstSearch.java 007 * 008 * Created on November 21, 2004, 12:58 AM 009 */ 010 011 package graphlab.library.algorithms.traversal; 012 013 import graphlab.library.BaseEdge; 014 import graphlab.library.BaseGraph; 015 import graphlab.library.BaseVertex; 016 import graphlab.library.algorithms.Algorithm; 017 import graphlab.library.algorithms.AutomatedAlgorithm; 018 import graphlab.library.algorithms.util.EventUtils; 019 import graphlab.library.event.GraphRequest; 020 import graphlab.library.event.PreWorkEvent; 021 import graphlab.library.event.VertexRequest; 022 import graphlab.library.event.handlers.PreWorkHandler; 023 import graphlab.library.exceptions.InvalidVertexException; 024 025 import java.util.LinkedList; 026 027 /** 028 * Description here. 029 * 030 * @author Omid Aladini 031 */ 032 public class BreadthFirstSearch<VertexType extends BaseVertex, EdgeType extends BaseEdge<VertexType>> 033 extends Algorithm implements AutomatedAlgorithm { 034 private BaseGraph<VertexType, EdgeType> graph; 035 036 public BreadthFirstSearch(BaseGraph<VertexType, EdgeType> graph) { 037 this.graph = graph; 038 } 039 040 public BreadthFirstSearch() { 041 this.graph = null; 042 } 043 044 public boolean doSearch(VertexType vertex, PreWorkHandler<VertexType> handler) 045 throws InvalidVertexException { 046 //int vertexId = vertex.getId(); 047 048 for (VertexType v : graph) 049 v.setMark(false); 050 051 vertex.setMark(true); 052 LinkedList<VertexType> queue = new LinkedList<VertexType>(); 053 LinkedList<VertexType> roots = new LinkedList<VertexType>(); 054 queue.offer(vertex); 055 roots.offer(vertex); 056 try { 057 while (queue.size() != 0) { 058 VertexType index = queue.poll(); 059 VertexType root = roots.poll(); 060 061 if (handler != null) 062 if (handler.doPreWork(root, index)) 063 return true; 064 065 dispatchEvent(new PreWorkEvent<VertexType, EdgeType>(root, index, graph)); 066 EventUtils.algorithmStep(this, "explore: " + index.getId()); 067 068 069 for (VertexType i : graph) { 070 if (graph.isEdge(index, i) && !i.getMark()) { 071 i.setMark(true); 072 EventUtils.algorithmStep(this, "visit: " + i.getId()); 073 queue.offer(i); 074 roots.offer(index); 075 } 076 077 } 078 } 079 } catch (Exception e) { 080 throw new RuntimeException(e); 081 } 082 return false; 083 } 084 085 public void doAlgorithm() { 086 GraphRequest<VertexType, EdgeType> gr = new GraphRequest<VertexType, EdgeType>(); 087 dispatchEvent(gr); 088 this.graph = gr.getGraph(); 089 VertexRequest<VertexType, EdgeType> vr = new VertexRequest<VertexType, EdgeType>(graph, "Please choose a vertex for the BFS algorithm."); 090 dispatchEvent(vr); 091 this.doSearch(vr.getVertex(), null); 092 } 093 }