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;
021    
022    import java.util.List;
023    
024    /**
025     * The <code>Graph</code> interface has the functionalities of both a
026     * directed and an undirected graph.
027     * 
028     * A graph contains two types of elements: E and V. The E's are stored
029     * in the edges and the V's in the vertices. Edges and Vertices are
030     * seen as <code>Position</code>s, containing E's or V's.
031     * 
032     * Here is the implementation of a BFS Traversal for a <code>Graph</code>.
033     * <pre>
034        public static Sequence<Position<String>> bfsTraversal(Graph<Integer,String> g){
035            Sequence<Position<String>> buffer = new LinkedSequence<Position<String>>();
036            Sequence<Position<String>> result = new LinkedSequence<Position<String>>();
037            Set<Position<String>> bufferedVertices = new HashSet<Position<String>>();
038            List<Position<String>> vertices = g.vertices();
039            for(Position<String> v : vertices){
040                if(! bufferedVertices.contains(v)){
041                    buffer.add(v);
042                    bufferedVertices.add(v);
043                    while(! buffer.isEmpty()){
044                        Position<Position<String>> pFirst= buffer.first();
045                        v = (Position<String>)buffer.element(pFirst);
046                        buffer.delete(pFirst);
047                        result.add(v);
048                        
049                        for(Position<String> v2 : g.adjacentVertices(v,Direction.ALL)){
050                            if(!bufferedVertices.contains(v2) && v2 !=null){
051                                bufferedVertices.add(v2);
052                                buffer.add(v2);
053                            }
054                        }
055                    }
056                }
057                
058            }
059            return result;
060        }
061      * </pre>
062      *
063      * @author <a href="http://www.iam.unibe.ch/til/staff/kraehenbuehl">Juerg
064      * Kraehenbuehl</a> (code) and <a href="http://prof.hti.bfh.ch/bie1">Emmanuel
065      * Benoist</a> (Javadoc)
066      * @version 1.0
067      */
068    public interface Graph<E,V> extends Container<V>{
069    
070        /**
071         * Creates a new vertex containing the <code>element</code>. This
072         * vertex is then returned (it is a
073         * <code>Position&lt;V&gt;</code>).
074         * 
075         * @param element the element to be used as a label for the new vertex. 
076         * @return the new vertex 
077         * <code>Position</code>
078         */
079        public Position<V> insertVertex(V element);
080    
081        /**
082         * Creates a new edge containing the <code>element</code>. This
083         * edge is then returned (it is a <code>Position&lt;E&gt;</code>).
084         * The edge does not have any extremities (adjacent
085         * vertices). They have to be defined afterward.
086         * 
087         * @param element the element to be used as a label for the new edge. 
088         * @return the new edge
089         * <code>Position</code>
090         */
091        public Position<E> insertEdge(E element);
092    
093    
094        /**
095         * Creates a new edge containing the <code>element</code>. Which
096         * extremities are the two vertices <code>origin</code> and
097         * <code>destination</code>. This edge is then returned (it is a
098         * <code>Position&lt;E&gt;</code>).
099         * 
100         * If the graph is directed, the new edge is directed; if we
101         * have an undirected graph, then the new edge is also undirected.
102         *
103         * @param element the element to be used as a label for the new edge. 
104         * @param origin the vertex that will be the origin of the new edge
105         * @param destination the vertex that will become the destination
106         * of the new edge.
107         * @return the new edge 
108         * <code>Position</code>
109         */
110        public Position<E> insertEdge(E element, Position<?> origin, Position<?> destination) throws InvalidAccessorException;
111    
112    
113        /**
114         * Deletes the edge <code>position</code>. The edge is
115         * automatically removed from the two vertices at its extremities.
116         *
117         * @param position the edge to be removed from the graph.
118         * @return the element contained by the removed edge.
119         * @throws InvalidAccessorException if the position is not a
120         * valide edge of this graph.
121         */
122        public E deleteEdge(Position<?> position) throws InvalidAccessorException;
123        
124        /**
125         * Deletes the vertex <code>position</code>. This also removes all
126         * the edges that had position for an extremity.
127         *
128         * @param position the vertex to be removed from the graph.
129         * @return the element contained by the removed vertex.
130         * @throws InvalidAccessorException if the position is not a
131         * valide vertex of this graph.
132         */
133        public V deleteVertex(Position<?> position) throws InvalidAccessorException;
134    
135        /**
136         * Replaces the element contained in the edge <code>edge</code> by <code>element</code>.
137         *
138         * @param edge the edge whose element will be replaced;
139         * @param element the new label of the <code>edge</code>.
140         * @return the old value of <code>edge</code> that has just be replaced.
141         * @throws InvalidAccessorException if the position is not a
142         * valide edge of this graph.
143         */
144        public E replaceEdge(Position<?> edge, E element) throws InvalidAccessorException;
145    
146    
147        /**
148         * Replaces the element contained in the vertex <code>vertex</code> by <code>element</code>.
149         *
150         * @param vertex the vertex whose element will be replaced;
151         * @param element the new label of the <code>vertex</code>.
152         * @return the old value of <code>vertex</code> that has just be replaced.
153         * @throws InvalidAccessorException if the position is not a
154         * valide edge of this graph.
155         */
156        public V replaceVertex(Position<?> vertex, V element) throws InvalidAccessorException;
157    
158        /**
159         * Exchanges the content of the two edges <code>edge0</code> and <code>edge1</code>. 
160         *
161         * @param edge0 the first edge
162         * @param edge1 the second edge
163         * @throws InvalidAccessorException if one of the edges is not a
164         * valide edge of this graph.
165         */
166        public void swapEdge(Position<?> edge0, Position<?> edge1) throws InvalidAccessorException;
167    
168    
169        /**
170         * Exchanges the content of the two vertices <code>vertex0</code> and <code>vertex1</code>. 
171         *
172         * @param vertex0 the first vertex
173         * @param vertex1 the second vertex
174         * @throws InvalidAccessorException if one of the vertices is not a
175         * valide vertex of this graph.
176         */
177        public void swapVertex(Position<?> vertex0, Position<?> vertex1) throws InvalidAccessorException;
178            
179    
180        /**
181         * Defines the vertex <code>vertex</code> to be the new origin of the edge <code>edge</code>.
182         * If the edge is undirected, origin is simply one of the two extremities.
183         *
184         * @param edge the edge whose origin is being defined
185         * @param vertex the new origin
186         * @throws InvalidAccessorException if the vertex or the edge do not belong to the graph
187         */
188        public void setOrigin(Position<?> edge, Position<?> vertex) throws InvalidAccessorException;
189    
190        /**
191         * Defines the vertex <code>vertex</code> to be the new destination of the edge <code>edge</code>.
192         * If the edge is undirected, destination is simply one of the two extremities.
193         *
194         * @param edge the edge whose destination is being defined
195         * @param vertex the new destination.
196         * @throws InvalidAccessorException if the vertex or the edge do not belong to the graph
197         */
198        public void setDestination(Position<?> edge, Position<?> vertex) throws InvalidAccessorException;
199    
200        /**
201         * Returns the origine of the edge <code>edge</code>
202         *
203         * @param edge an edge
204         * @return the origin (a vertex) of the edge.
205         * @throws InvalidAccessorException if the vertex or the edge do not belong to the graph
206         */
207        public Position<V> origin(Position<?> edge) throws InvalidAccessorException;
208        /**
209         * Returns the destination of the edge <code>edge</code>
210         *
211         * @param edge an edge
212         * @return the destination (a vertex) of the edge.  
213         * @throws InvalidAccessorException if the vertex or the edge do not belong to the graph
214         */
215        public Position<V> destination(Position<?> edge) throws InvalidAccessorException;
216    
217        
218        /**
219         * Separates <code>edge</code> from one of its extremities, the vertex <code>vertex</code>.
220         *
221         *
222         * @param edge an edge
223         * @param vertex one of the two extremities of edge
224         * @throws InvalidAccessorException if the vertex or the edge do
225         * not belong to the graph, or if the edge is not incident to the
226         * vertex.
227         */
228        public void detach(Position<?> edge, Position<?> vertex) throws InvalidAccessorException;
229    
230        /**
231         * Defines the <code>edge</code> as a directed edge.
232         *
233         *
234         * @param edge an edge
235         * @throws InvalidAccessorException if the edge does not belong to
236         * the graph
237         */
238        public void setDirected(Position<?> edge) throws InvalidAccessorException;
239    
240        /**
241         * Defines the <code>edge</code> as an undirected edge.
242         *
243         *
244         * @param edge an edge
245         * @throws InvalidAccessorException if the edge does not belong to
246         * the graph
247         */
248        public void setUndirected(Position<?> edge) throws InvalidAccessorException;
249        
250        /**
251         * Verifies if an edge is directed. 
252         * 
253         * @param edge an edge
254         * @return true if <code>edge</code> is directed
255         * @throws InvalidAccessorException if the edge does not belong to
256         * the graph
257         */
258        public boolean isDirected(Position<?> edge) throws InvalidAccessorException;
259        
260        /**
261         * Exchanges the two extremities of an edge. The origin becomes the destination and vice versa.
262         * 
263         * @param edge an edge
264         * @throws InvalidAccessorException if the edge does not belong to
265         * the graph
266         */
267        public void reverse(Position<?> edge) throws InvalidAccessorException;
268    
269        
270        /**
271         * Returns the vertex that is opposite to the vertex
272         * <code>vertex</code> on the edge <code>edge</code>. It
273         * <code>vertex</code> is the origin of <code>edge</code>, then it
274         * returns its destination, and it returns its origin if
275         * <code>vertex</code> is the destination of <code>edge</code>.
276         * 
277         * @param edge an edge
278         * @throws InvalidAccessorException if the edge does not belong to
279         * the graph
280         */
281        public Position<V> opposite(Position<?> edge, Position<?> vertex) throws InvalidAccessorException;
282    
283        /**
284         * Returns a list of all the vertices contained in the graph.
285         * 
286         * @return the list of all vertices
287         */
288        public List<Position<V>> vertices();
289    
290        /**
291         * Returns a list of all the edges contained in the graph.
292         * 
293         * @return the list of all edges
294         */
295        public List<Position<E>> edges();
296    
297        /**
298         * Returns a list of all the edges of a desired type.
299         * <code>type</code> can have the following values: 
300         * <ul><li><code>Direction.DIRECTED</code></li>
301         * <li><code>Direction.UNDIRECTED</code></li>
302         * <li><code>Direction.ALL</code></li>
303         * </ul>
304         * @param type the type of the edges
305         * @return the list of all edges
306         */
307        public List<Position<E>> edges(Direction type);
308    
309        
310        /**
311         * Returns a list of the incident edges of the
312         * <code>vertex</code>. Depending on the value of
313         * <code>type</code>, the result is different.
314         *
315         * <ul><li>if <code>type==Direction.IN</code> the method returns
316         * the in incident edges</li>
317         * <li>if <code>type==Direction.OUT</code> the method returns the
318         * out incident edges</li>
319         * <li>and if <code>type==Direction.ALL</code> then the method
320         * returns all the incident edges (including the undirected
321         * ones).</li> </ul>
322         *
323         * @param vertex the vertex
324         * @param type the type of the edges
325         * @return the list of all edges
326         */
327        public List<Position<E>> incidentEdges(Position<?> vertex, Direction type) throws InvalidAccessorException;       
328    
329        
330        /**
331         * Returns a list of the vertices adjacent to
332         * <code>vertex</code>. Depending on the value of
333         * <code>type</code>, the result is different.
334         *
335         * <ul><li>if <code>type==Direction.IN</code> the method returns
336         * the vertices linked to <code>vertex</code> through an in incident edge</li>
337         * <li>if <code>type==Direction.OUT</code> the method returns the
338         *  vertices linked to <code>vertex</code> through an out incident edges</li>
339         * <li>and if <code>type==Direction.ALL</code> then the method
340         * returns all the adjacent vertices.</li> </ul>
341         *
342         * @param vertex the vertex
343         * @param type the type of the edges
344         * @return the list of adjacent vertices
345         */
346        public List<Position<V>> adjacentVertices(Position<?> vertex, Direction type) throws InvalidAccessorException;
347    
348        /**
349         * Returns a list of all elements contained in the vertices.
350         *
351         * @return the list of elements contained in the vertices
352         */
353        public List<V> vertexElements();
354        
355        /**
356         * Returns a list of all elements contained in the edges.
357         *
358         * @return the list of elements contained in the edges
359         */
360        public List<E> edgeElements();
361            
362        /**
363         * Returns the element contained in <code>vertex</code>
364         *
365         * @param vertex the vertex containing the element
366         * @return element contained in the vertex
367         */
368        public V vertexElement(Position<?> vertex) throws InvalidAccessorException;
369    
370        /**
371         * Returns the element contained in <code>edge</code>
372         *
373         * @param edge the edge containing the element
374         * @return element contained in the edge
375         */
376        public E edgeElement(Position<?> edge) throws InvalidAccessorException;
377    
378    }