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 java.util.HashMap;
022    import java.util.List;
023    import java.util.Map;
024    
025    import ch.bfh.algo.Direction;
026    import ch.bfh.algo.Graph;
027    import ch.bfh.algo.Position;
028    import ch.bfh.algo.Sequence;
029    import ch.bfh.algo.graph.DefaultGraph;
030    import ch.bfh.algo.graph.DefaultGraphFactory;
031    import ch.bfh.algo.graph.Vertex;
032    import ch.bfh.algo.sequence.LinkedSequence;
033    import ch.bfh.algo.InvalidAccessorException;
034    
035    import java.util.Random;
036    
037    
038    /**
039     * The class <code>GraphExampleNonGenerics</code> contains an example of use
040     * of graph without any generics.
041     *
042     * @author <a href="mailto:">Emmanuel Benoist</a>
043     * @version 1.0
044     */
045    public class GraphExampleNonGenerics{
046        final static int NUMBER_OF_VERTICES = 30;
047        final static int NUMBER_OF_EDGES = 50;
048      
049    
050    
051            private class DecoratedVertex extends Vertex{
052    
053                // We add two properties to this vertex,
054                //
055                // First we have the visited boolean which indicates if this node
056                // has already been inserted in the buffer.
057                boolean visited;
058    
059                // The second property is a return property to indicate to which
060                // connected component the vertex belong to.
061                int connectedComponentNumber;
062    
063                /**
064                 * Get the Visited value.
065                 * @return the Visited value.
066                 */
067                public boolean isVisited() {
068                    return visited;
069                }
070    
071                /**
072                 * Set the Visited value.
073                 * @param newVisited The new Visited value.
074                 */
075                public void setVisited(boolean newVisited) {
076                    this.visited = newVisited;
077                }
078    
079                /**
080                 * Get the ConnectedComponentNumber value.
081                 * @return the ConnectedComponentNumber value.
082                 */
083                public int getConnectedComponentNumber() {
084                    return connectedComponentNumber;
085                }
086    
087                /**
088                 * Set the ConnectedComponentNumber value.
089                 * @param newConnectedComponentNumber The new ConnectedComponentNumber value.
090                 */
091                public void setConnectedComponentNumber(int newConnectedComponentNumber) {
092                    this.connectedComponentNumber = newConnectedComponentNumber;
093                }
094    
095                public String toString(){
096                    return element().toString()+"("+connectedComponentNumber+")";
097                    
098                }
099                
100            }
101    
102            private class DecoratedGraphFactory extends DefaultGraphFactory{
103                    
104                public Vertex createVertex(){
105                    return new DecoratedVertex();
106                }
107                    
108                public Vertex castVertex(Position p){
109                    return (Vertex) p;
110                }
111            }
112    
113    
114    
115    
116        /**
117         * The <code>dfsTraversal</code> is an example of the possible
118         * implementation of a Depth 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 dfsTraversal(Graph g, List vertices){
126    
127            Sequence buffer = new LinkedSequence();
128            Sequence result = new LinkedSequence();
129    
130            // ccNumber represents the number of the current Connected Component.
131            int ccNumber = 0;
132            for(Object o1 : vertices){
133                Position v1=(Position)o1;
134                DecoratedVertex v = (DecoratedVertex) v1;
135                if(!v.isVisited()){
136                    ccNumber++;
137                    buffer.add(v);
138                    v.setVisited(true);
139                    while(! buffer.isEmpty()){
140                        Position pLast= buffer.last();
141                        v = (DecoratedVertex)buffer.element(pLast);
142                        buffer.delete(pLast);
143                        result.add(v);
144                        v.setConnectedComponentNumber(ccNumber);
145                        for(Object o2 : g.adjacentVertices(v,Direction.OUT)){
146                            Position v2 = (Position) o2;
147                            DecoratedVertex vv = (DecoratedVertex) v2;
148                            if(vv !=null && !vv.isVisited() ){
149                                vv.setVisited(true);
150                                buffer.add(vv);
151                            }
152                        }
153                    }
154                }
155                
156            }
157            return result;
158        }
159    
160    
161        /**
162         * The <code>constructDirectedGraph</code> method is used to
163         * initialize a default directed <code>Graph</code>.
164         *
165         * The returned graph contains <code>numberOfVertices</code> vertices and
166         * <code>numberOfEdges</code> directed edges.
167         *
168         * @return a <code>Graph</code> value
169         */
170        public Graph constructDirectedGraph(int numberOfVertices,
171                                                            int numberOfEdges){
172        boolean directed=true;
173            Graph g = 
174                new DefaultGraph(new DecoratedGraphFactory(),directed);
175    
176            // Array containing all the vertices
177            Position<String>[] vertices = new Position[numberOfVertices];
178    
179            for(int i=0;i < numberOfVertices;i++){
180                vertices[i]= g.insertVertex(""+i);
181            }
182            
183            Random generator = new Random();
184            for(int j=0; j < numberOfEdges;j++){
185                Position v1, v2;
186                int i1 = generator.nextInt(numberOfVertices);
187                int i2= generator.nextInt(numberOfVertices);
188                v1=vertices[i1];
189                v2=vertices[i2];
190                g.insertEdge(0,v1,v2);
191            }
192    
193            return g;
194        }
195    
196    
197        public void run(){
198    
199            Graph g = constructDirectedGraph(NUMBER_OF_VERTICES,NUMBER_OF_EDGES);
200            Sequence dfs = dfsTraversal(g,g.vertices());
201            System.out.println("DFS= " + dfs);
202            
203        }
204    
205    
206        public static void main(String[] args){
207            System.out.println("***************");
208            System.out.println("Example of use of a Directed Graphs with edges and vertices non generics.");
209            System.out.println("Computes the DFS of the Graph:");
210            new GraphExampleNonGenerics().run();
211            System.out.println("***************");
212            System.out.println("");
213    
214        }
215    
216    
217    }