001    /*
002     *  www.ti.bfh.ch
003     *
004     *  Copyright 2007, Berne University of Applied Sciences, 
005     *  School of Engineering and Information Technology
006     *  and individual contributors as indicated by the @authors tag.
007     *
008     *  This is free software; you can redistribute it and/or modify it under the terms of the 
009     *  GNU Lesser General Public License as published by the Free Software Foundation; 
010     *  either version 3 of the License, or (at your option) any later version.
011     *
012     *  This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
013     *  without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
014     *  See the GNU Lesser General Public License for more details.
015     *
016     *  You should have received a copy of the GNU Lesser General Public License along with this software; 
017     *  if not, see <http://www.gnu.org/licenses/>.
018     *
019     */
020    package ch.bfh.algo.example;
021    import ch.bfh.algo.Direction;
022    import ch.bfh.algo.Graph;
023    import ch.bfh.algo.Position;
024    import ch.bfh.algo.Sequence;
025    import ch.bfh.algo.graph.DefaultGraph;
026    import ch.bfh.algo.graph.DefaultGraphFactory;
027    import ch.bfh.algo.graph.Vertex;
028    import ch.bfh.algo.sequence.LinkedSequence;
029    
030    
031    /**
032     * The class <code>GraphExample2</code> contains an example of the
033     * <code>ch.bfh.algo.Graph</code> interface, using the Factory Pattern
034     * to have specialized Vertices.
035     * 
036     * This example contains the creation of one graph containing 10
037     * vertices and 12 edges. The vertices have two new properties visited
038     * which is used durring the algorithm and
039     * <code>connectedComponentNumber</code> which contains the number of
040     * the connencted component containing this vertex. They are
041     * implemented using another class and the Factory Pattern to create
042     * new instances without changing anything in the graph classes.
043     *
044     * @author <a href="mailto:">Emmanuel Benoist</a>
045     * @version 1.0
046     */
047    public class GraphExample2{
048    
049    
050            private class DecoratedVertex extends Vertex<Integer,String>{
051    
052                // We add two properties to this vertex,
053                //
054                // First we have the visited boolean which indicates if this node
055                // has already been inserted in the buffer.
056                boolean visited;
057    
058                // The second property is a return property to indicate to which
059                // connected component the vertex belong to.
060                int connectedComponentNumber;
061    
062                /**
063                 * Get the Visited value.
064                 * @return the Visited value.
065                 */
066                public boolean isVisited() {
067                    return visited;
068                }
069    
070                /**
071                 * Set the Visited value.
072                 * @param newVisited The new Visited value.
073                 */
074                public void setVisited(boolean newVisited) {
075                    this.visited = newVisited;
076                }
077    
078                /**
079                 * Get the ConnectedComponentNumber value.
080                 * @return the ConnectedComponentNumber value.
081                 */
082                public int getConnectedComponentNumber() {
083                    return connectedComponentNumber;
084                }
085    
086                /**
087                 * Set the ConnectedComponentNumber value.
088                 * @param newConnectedComponentNumber The new ConnectedComponentNumber value.
089                 */
090                public void setConnectedComponentNumber(int newConnectedComponentNumber) {
091                    this.connectedComponentNumber = newConnectedComponentNumber;
092                }
093    
094                public String toString(){
095                    return element().toString()+"("+connectedComponentNumber+")";
096                    
097                }
098                
099            }
100            
101            private class DecoratedGraphFactory extends DefaultGraphFactory<Integer,String>{
102                    
103                public Vertex<Integer,String> createVertex(){
104                    return new DecoratedVertex();
105                }
106                    
107                public Vertex<Integer,String> castVertex(Position<?> p){
108                    return (DecoratedVertex) p;
109                }
110            }
111    
112    
113    
114            
115            
116        /**
117         * The <code>bfsTraversal</code> is an example of the possible
118         * implementation of a Breadth First Search traversal of a
119         * <code>Graph</code>. In this case, we use the
120         * <code>DecoratedVertex</code> to store inside each vertex if it
121         * has been visited.
122         *
123         * @return a <code>Sequence</code> value
124         */
125        public static Sequence<Position<String>> bfsTraversal(Graph<Integer,String> g){
126            Sequence<Position<String>> buffer = new LinkedSequence<Position<String>>();
127            Sequence<Position<String>> result = new LinkedSequence<Position<String>>();
128    
129            // ccNumber represents the number of the current Connected Component.
130            int ccNumber = 0;
131            for(Position<String> v1 : g.vertices()){
132                DecoratedVertex v = (DecoratedVertex) v1;
133                if(!v.isVisited()){
134                    ccNumber++;
135                    buffer.add(v);
136                    v.setVisited(true);
137                    while(! buffer.isEmpty()){
138                        Position<Position<String>> pFirst= buffer.first();
139                        v = (DecoratedVertex)buffer.element(pFirst);
140                        buffer.delete(pFirst);
141                        result.add(v);
142                        v.setConnectedComponentNumber(ccNumber);
143                        for(Position<String> v2 : g.adjacentVertices(v,Direction.ALL)){
144                            DecoratedVertex vv = (DecoratedVertex) v2;
145                            if(vv !=null && !vv.isVisited() ){
146                                vv.setVisited(true);
147                                buffer.add(vv);
148                            }
149                        }
150                    }
151                }
152                
153            }
154            return result;
155        }
156    
157        /**
158         * The <code>constructUndirectedGraph</code> method is used to
159         * initialize a default undirected <code>Graph</code>.
160         *
161         * The returned graph contains 10 vertices and 12 edges. 
162         *
163         * @return a <code>Graph</code> value
164         */
165        public Graph<Integer,String> constructUndirectedGraph(){
166        boolean directed=false;
167            Graph<Integer,String> g = 
168                new DefaultGraph<Integer,String>(new DecoratedGraphFactory(),directed);
169            Position<String> vertA = g.insertVertex("A");
170            Position<String> vertB = g.insertVertex("B");
171            Position<String> vertI = g.insertVertex("I");
172            Position<String> vertJ = g.insertVertex("J");
173            Position<String> vertC = g.insertVertex("C");
174            Position<String> vertH = g.insertVertex("H");
175            Position<String> vertD = g.insertVertex("D");
176            Position<String> vertE = g.insertVertex("E");
177            Position<String> vertF = g.insertVertex("F");
178            Position<String> vertG = g.insertVertex("G");
179    
180            g.insertEdge(0,vertA,vertE);
181            g.insertEdge(0,vertE,vertD);
182            g.insertEdge(0,vertC,vertE);
183            g.insertEdge(0,vertC,vertD);
184            g.insertEdge(0,vertB,vertC);
185            g.insertEdge(0,vertA,vertB);
186            g.insertEdge(0,vertA,vertF);
187            g.insertEdge(0,vertA,vertF);
188            g.insertEdge(0,vertG,vertH);
189            g.insertEdge(0,vertH,vertI);
190            g.insertEdge(0,vertJ,vertH);
191            g.insertEdge(0,vertI,vertJ);
192    
193            return g;
194        }
195    
196    
197        public void run(){
198            Graph<Integer,String> g = constructUndirectedGraph();
199            Sequence<Position<String>> bfs = bfsTraversal(g);
200            System.out.println("BFS= "+bfs);
201    
202        }
203    
204    
205        public static void main(String[] args){
206            System.out.println("***************");
207            System.out.println("Example of use of Graphs with a decorated vertex.");
208            System.out.println("Computes for each Vertex its Connected Component (CC-number):");
209            new GraphExample2().run();
210            System.out.println("***************");
211            System.out.println("");
212    
213        }
214    
215    
216    }