ADT Grafo
Transcript
ADT Grafo
ADT Grafo L' ADT grafo è un contenitore di elementi memorizzati nelle posizioni del grafo (vertici e archi) le informazioni possono essere memorizzate sia sui vertici sia sugli archi del grafo Strutture Dati ADT Grafo Metodi fondamentali (grafo non orientato) Metodi iteratore – vertices(): restituisce una collezione iterabile su tutti i vertici del grafo – edges(): restituisce una collezione iterabile su tutti gli archi del grafo – incidentEdges(v): restituisce una collezione iterabile sugli archi incidenti su v Metodi di accesso – – – – – endVertices(e): restituisce un array dei due vertici estremità di e opposite(v, e): restituisce il vertice opposto a v sull'arco e areAdjacent(v, w): vero se e solo se v e w sono adiacenti replace(v, x): rimpiazza l'elemento memorizzato nel vertice v con x replace(e, x): rimpiazza l'elemento memorizzato nell'arco e con x Strutture Dati ADT Grafo Metodi fondamentali (grafo non orientato) Metodi di aggiornamento – insertVertex(o): inserisce un vertice che contiene l'elemento o – insertEdge(v, w, o): inserisce un arco (v,w) che contiene l'elemento o – removeVertex(v): rimuove il vertice v (e i suoi archi incidenti) – removeEdge(e): rimuove l'arco e Strutture Dati ADT Grafo Interfaccia Graph public interface Graph <V,E>{ public int numVertices(); public int numEdges(); public Iterable<Vertex<V>> vertices(); public Iterable<Edge<E>> edges(); public V replace(Vertex<V> p, V o) throws InvalidPositionException; public E replace(Edge<E> p, E o) throws InvalidPositionException; public Iterable<Edge<E>> incidentEdges(Vertex<V> v) throws InvalidPositionException; public Vertex[] endVertices(Edge<E> e) throws InvalidPositionException; ... } Strutture Dati ADT Grafo Interfaccia Graph public interface Graph <V,E>{ ... public Vertex<V> opposite(Vertex<V> v, Edge<E> e) throws InvalidPositionException; public boolean areAdjacent(Vertex<V> u, Vertex<V> v) throws InvalidPositionException; public Vertex<V> insertVertex(V o); public Edge<E> insertEdge(Vertex<V> u, Vertex<V> v, E o) throws InvalidPositionException; public V removeVertex(Vertex<V> v) throws InvalidPositionException; public E removeEdge(Edge<E> e) throws InvalidPositionException; } Strutture Dati ADT Grafo Decorator pattern Il decorator pattern è un design pattern che serve ad inserire informazioni extra (colori) ad un oggetto Una decorazione consiste di - una chiave (che identifica il tipo di decorazione) - un valore associato alla chiave Strutture Dati ADT Grafo Decorator pattern Esempio: algoritmi come BFS e DFS richiedono che i nodi e/o gli archi del grafo vengano colorati per tenere traccia dell'esplorazione Si può usare un decorator pattern per “decorare” i nodi del grafo: ad ogni nodo sarà associata una coppia (chiave, valore) dove la chiave identifica l'attributo esplorato e il valore (ad essa associato) è un booleano (esplorato, sì) Strutture Dati (esplorato, no) ADT Grafo Interfacce Vertex e Edge public interface DecorablePosition<T> extends Position<T>, Map<Object,Object> { } public interface Vertex<V> extends DecorablePosition<V> { } public interface Edge<E> extends DecorablePosition<E> { } Strutture Dati ADT Grafo Uso della decorable position Esempio: final Object COLOR = new Object(); final Object WHITE = new Object(); ... chiave valore v.put(COLOR, WHITE); ... if(v.get(COLOR) != WHITE) ... Strutture Dati su un oggetto Vertex<V> si possono usare i metodi della mappa per gestire le colorazioni ADT Grafo Implementazione mediante lista di archi Ciascun vertice del grafo è rappresentato da un oggetto di tipo vertex, tutti gli oggetti vertex sono memorizzati in un contenitore V V Ciascun arco del grafo è rappresentato da un oggetto di tipo edge, tutti gli oggetti edge sono memorizzati in un contenitore E E Strutture Dati ADT Grafo Implementazione mediante lista di archi Oggetto vertex o l'oggetto vertex per un vertice v che memorizza l'elemento o ha: - un riferimento a o - un riferimento alla posizione dell'oggetto-vertex nel contenitore V dei vertici del grafo Strutture Dati ADT Grafo Implementazione mediante lista di archi Oggetto edge o l'oggetto edge per un arco e = (u,v) che memorizza l'elemento o ha: - un riferimento a o - un riferimento agli oggetti-vertex per u e v - un riferimento alla posizione dell'oggetto-edge nel contenitore E degli archi del grafo Strutture Dati ADT Grafo Implementazione mediante lista di archi z u a v c b d V w u a E Strutture Dati v b w z c d ADT Grafo Implementazione mediante lista di archi Vantaggi: - implementazione semplice - accesso diretto dagli archi ai vertici su cui essi sono incidenti (endVertices(e) e opposite(v,e) sono semplici da implementare e richiedono tempo O(1)) Svantaggi: - l'accesso agli archi che sono incidenti su un dato vertice richiede un'ispezione esaustiva di tutto il contenitore E. I seguenti metodi richiedono un tempo proporzionale al numero di archi del grafo: - incidentEdges(v) - areAdjacent(v,w) - removeVertex(v) Strutture Dati Grafi Domanda Qual è il massimo numero di archi che un grafo G = (V,E) di n = |V| vertici può avere? Grafi Domanda Qual è il massimo numero di archi che un grafo G = (V,E) di n = |V| vertici può avere? grafi orientati Grafi Domanda Qual è il massimo numero di archi che un grafo G = (V,E) di n = |V| vertici può avere? grafi orientati n2 Grafi Domanda Qual è il massimo numero di archi che un grafo G = (V,E) di n = |V| vertici può avere? grafi orientati n2 grafi non orientati Grafi Domanda Qual è il massimo numero di archi che un grafo G = (V,E) di n = |V| vertici può avere? grafi orientati n2 grafi non orientati n 2 ( ) Rappresentazione in memoria Liste di adiacenza e matrice di adiacenza Esistono due modi per rappresentare un grafo G=(V,E) in memoria: liste di adiacenza matrice di adiacenza Liste di adiacenza G =( V,E ) La rappresentazione consiste di un array Adj di |V| liste (una per ogni vertice) Per ogni u in V la lista Adj [u] contiene tutti i vertici v adiacenti ad u in G Liste di adiacenza Grafi non orientati 1 G =(V,E) grafo non orientato 2 4 Array Adj di |V| liste: 3 Adj [1], Adj [2], Adj [3], Adj [4], Adj [5] Adj [1] 1 2 3 / Adj [2] 2 1 4 Adj [3] 3 1 4 / Adj [4] 4 2 3 Adj [5] 5 2 4 / 5 / 5 / 5 Liste di adiacenza Grafi orientati G =(V,E) grafo orientato 1 2 V= {1,2,3,4,5} 4 Array Adj di |V| liste: 3 Adj [1], Adj [2], Adj [3], Adj [4], Adj [5] Adj [1] 1 2 Adj [2] 2 4 / Adj [3] 3 4 / Adj [4] 4 5 / Adj [5] 5 2 / 3 / 5 Liste di adiacenza Spazio di memoria richiesto 1 1 2 2 4 4 3 5 3 5 G =(V,E) grafo orientato G =(V,E) grafo non orientato 1 2 3 / 2 1 4 3 1 4 / 4 2 3 5 2 4 / 5 / 5 / 1 2 2 4 / 3 4 / 4 5 / 5 2 / 3 / Liste di adiacenza Spazio di memoria richiesto 1 2 3 / 2 1 4 3 1 4 / 4 2 3 5 2 4 / somma delle lunghezze delle liste = 5 / 5 / 1 2 2 4 / 3 4 / 4 5 / 5 2 / somma delle lunghezze delle liste = 3 / Liste di adiacenza Spazio di memoria richiesto 1 2 3 / 2 1 4 3 1 4 / 4 2 3 5 2 4 / somma delle lunghezze delle liste = 5 / 5 / 1 2 2 4 / 3 4 / 4 5 / 5 2 / somma delle lunghezze delle liste = |E| 3 / Liste di adiacenza Spazio di memoria richiesto 1 2 3 / 2 1 4 3 1 4 / 4 2 3 5 2 4 / somma delle lunghezze delle liste = 2|E| 5 / 5 / 1 2 2 4 / 3 4 / 4 5 / 5 2 / somma delle lunghezze delle liste = |E| 3 / Liste di adiacenza Spazio di memoria richiesto 1 2 3 / 2 1 4 3 1 4 / 4 2 3 5 2 4 / somma delle lunghezze delle liste = 2|E| 5 / 5 / 1 2 2 4 / 3 4 / 4 5 / 5 2 / somma delle lunghezze delle liste = |E| Spazio di memoria richiesto in entrambi i casi: 3 / Liste di adiacenza Spazio di memoria richiesto 1 2 3 / 2 1 4 3 1 4 / 4 2 3 5 2 4 / somma delle lunghezze delle liste = 2|E| 5 / 5 / 1 2 2 4 / 3 4 / 4 5 / 5 2 / somma delle lunghezze delle liste = |E| Spazio di memoria richiesto in entrambi i casi: Θ(max{|V|,|E|}) = Θ(|V|+|E|) 3 / Liste di adiacenza Grafi pesati Un grafo pesato G è una coppia (V,E) con una funzione peso w: E R Il peso w(u,v) di ogni arco (u,v) in E viene memorizzato nella lista di u insieme a v in un nuovo campo. 6 1 2 5 10 23 3 4 19 3 5 1 2 6 2 4 5 / 3 4 23 / 4 5 19 / 5 2 3 / 3 10 / Liste di adiacenza Vantaggi e svantaggi Buone notizie Spazio di memoria richiesto: Θ(|V|+|E|) Cattive notizie Non esiste un modo veloce per determinare se un dato arco (u,v) è presente nel grafo. Unico modo: scandire la lista di adiacenza di u alla ricerca di v ADT Grafo Implementazione con liste di adiacenza Come nella implementazione mediante lista di archi: Ciascun vertice del grafo è rappresentato da un oggetto di tipo vertex, tutti gli oggetti vertex sono memorizzati in un contenitore V Ciascun arco del grafo è rappresentato da un oggetto di tipo edge, tutti gli oggetti edge sono memorizzati in un contenitore E Strutture Dati ADT Grafo Implementazione con liste di adiacenza Oggetto vertex o l'oggetto vertex per un vertice v che memorizza l'elemento o ha: - un riferimento a o - un riferimento alla posizione dell'oggetto-vertex nel contenitore V dei vertici del grafo - un riferimento a un contenitore I(v) (contenitore di incidenza di v) i cui elementi hanno i riferimenti agli archi incidenti su v Strutture Dati ADT Grafo Implementazione con liste di adiacenza Oggetto edge o l'oggetto edge per un arco e = (u,v) che memorizza l'elemento o ha: - un riferimento a o - un riferimento agli oggetti-vertex per u e v - un riferimento alla posizione dell'oggetto-edge nel contenitore E degli archi del grafo - un riferimento alle posizioni associate all'arco e nei contenitori di incidenza I(u) e I(v) Strutture Dati ADT Grafo Implementazione con liste di adiacenza a u v b V w u v I(u) I(v) a E Strutture Dati w I(w) b