Files
ASDL/asdl/src/network/network/Network.java
T
2026-05-19 13:42:21 +02:00

312 lines
7.7 KiB
Java

package network.network;
import network.Graph;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Map;
import java.util.Queue;
import java.util.Set;
import java.util.Stack;
import java.util.TreeMap;
import java.util.TreeSet;
public class Network<Vertex extends Comparable<? super Vertex>> implements Graph<Vertex, Double>{
protected TreeMap<Vertex, TreeMap<Vertex, Double>> adjacencyMap;
public Network() {
this.adjacencyMap = new TreeMap<Vertex, TreeMap<Vertex, Double>>();
}
public Network(Network<Vertex> network) {
this.adjacencyMap = new TreeMap<Vertex, TreeMap<Vertex, Double>>(network.adjacencyMap);
}
@Override
public boolean equals(Object object) {
if (object == null) return false;
if (object == this) return true;
if (!(object instanceof Network)) return false;
Network<?> network = (Network<?>) object;
return adjacencyMap.equals(network.adjacencyMap);
}
@Override
public boolean containsVertex(Vertex vertex) {
return adjacencyMap.containsKey(vertex);
}
@Override
public boolean addVertex(Vertex vertex) {
// Null Check
if (vertex == null) throw new NullPointerException();
// Se l'elemento è già presente
if (containsVertex(vertex)) return false;
// Inserimento
adjacencyMap.put(vertex, new TreeMap<Vertex, Double>());
return true;
}
@Override
public boolean removeVertex(Vertex vertex) {
// Null check
if (vertex == null) throw new NullPointerException();
// Se l'elemento non è presente
if (!containsVertex(vertex)) return false;
// Rimozione del vertice dalle liste di adiacenza
for (Vertex v : adjacencyMap.keySet()) {
adjacencyMap.get(v).remove(vertex);
}
// Rimozione del vertice dalle chiavi
adjacencyMap.remove(vertex);
return true;
}
/*
* Restituisce il numero di archi presenti all'interno del grafo
*/
@Override
public int edgeSize() {
// Variabile contatore
int edges = 0;
// Conto degli archi
for (Vertex v : adjacencyMap.keySet()) {
edges += adjacencyMap.get(v).size();
}
return edges;
}
@Override
public Double getEdgeWheight(Vertex v1, Vertex v2) {
// Null check
if (v1 == null || v2 == null) throw new NullPointerException();
// Verifichiamo se ambedue sono presenti nel grafo, se non ci sono allora return null.
if (!(containsVertex(v1) && containsVertex(v2))) return null;
// Otteniamo la lista di adiacenza
Map<Vertex, Double> tmp = adjacencyMap.get(v1);
// Se il vertex2 non presenta il vertice2 allora non esiste il peso
if (!tmp.containsKey(v2)) return null;
return tmp.get(v2);
}
@Override
public boolean containsEdge(Vertex v1, Vertex v2) {
// Null check
if (v1 == null || v2 == null) throw new NullPointerException();
// Verifichiamo che ambedue siano nel grafico
if (!(containsVertex(v1) && containsVertex(v2))) return false;
// Otteniamo la lista di adiacenza
Map<Vertex, Double> tmp = adjacencyMap.get(v1);
return tmp.containsKey(v2);
}
@Override
public boolean addEdge(Vertex v1, Vertex v2, Double weight) {
// Null check
if (v1 == null || v2 == null || weight == null) throw new NullPointerException();
// Verifichiamo che ambedue siano nel grafico
if (!(containsVertex(v1) && containsVertex(v2))) return false;
// Verifichiamo che non esista l'arco. Se esiste allora non fa nulla. Se non esiste lo aggiunge.
if (containsEdge(v1, v2)) return false;
// Aggiunta dell'edge
Map<Vertex, Double> tmp = adjacencyMap.get(v1);
tmp.put(v2, weight);
return true;
}
@Override
public boolean removeEdge(Vertex v1, Vertex v2) {
// Null check
if (v1 == null || v2 == null) throw new NullPointerException();
// Verifichiamo che ambedue siano nel grafico
if (!(containsVertex(v1) && containsVertex(v2))) return false;
// Verifichiamo se l'arco esiste oppure no.
if (!containsEdge(v1, v2)) return false;
// Rimozione dell'edge
Map<Vertex, Double> tmp = adjacencyMap.get(v1);
tmp.remove(v2);
return true;
}
@Override
public boolean isEmpty() {
return adjacencyMap.isEmpty();
}
@Override
public int size() {
return adjacencyMap.keySet().size();
}
@Override
public Set<Vertex> neighbors(Vertex v) {
// Null check
if (v == null) throw new NullPointerException();
// Presenza del vertice nel grafo
if (!containsVertex(v)) return null;
// Se il vertice è presente, allora restituisco il tutto
return new TreeSet<Vertex>(adjacencyMap.get(v).keySet());
}
@Override
public Iterator<Vertex> iterator() {
return new NetworkIterator();
}
protected class NetworkIterator implements Iterator<Vertex> {
// Variabili
protected Iterator<Vertex> iterator;
protected Vertex currentVertex;
// Costruttore
public NetworkIterator() {
this.iterator = adjacencyMap.keySet().iterator();
}
// hasNext
public boolean hasNext() {
return this.iterator.hasNext();
}
// next
public Vertex next() {
this.currentVertex = iterator.next();
return this.currentVertex;
}
// remove
public void remove() {
throw new UnsupportedOperationException();
}
}
@Override
public Iterator<Vertex> breadthFirstIterator(Vertex vertex) {
if (!this.adjacencyMap.containsKey(vertex)) throw new IllegalArgumentException();
return new BreadthFirstIterator(vertex);
}
protected class BreadthFirstIterator implements Iterator<Vertex> {
// Variabili
protected Queue<Vertex> queue;
protected HashMap<Vertex, Boolean> research;
protected Vertex currentVertex;
// Costruttore
public BreadthFirstIterator(Vertex vertex) {
this.queue = new LinkedList<Vertex>();
this.research = new HashMap<Vertex, Boolean>();
for (Vertex v : adjacencyMap.keySet()) {
research.put(v, false);
}
queue.add(vertex);
research.put(vertex, true);
}
public boolean hasNext() {
return !(queue.isEmpty());
}
public Vertex next() {
currentVertex = queue.remove();
Set<Vertex> neighborsSet = adjacencyMap.get(currentVertex).keySet();
for (Vertex v : neighborsSet) {
if (research.get(v)) continue;
research.put(v, true);
queue.add(v);
}
return currentVertex;
}
public void remove() {
throw new UnsupportedOperationException();
}
}
@Override
public Iterator<Vertex> depthFisrtIterator(Vertex v) {
return new DepthFirstIterator(v);
}
protected class DepthFirstIterator implements Iterator<Vertex>{
// Variabili
protected Stack<Vertex> stack = new Stack<Vertex>();
protected HashMap<Vertex, Boolean> reached;
Vertex current;
// Costruttore
public DepthFirstIterator(Vertex vertex) {
this.stack = new Stack<Vertex>();
this.reached = new HashMap<Vertex, Boolean>();
for (Vertex v : adjacencyMap.keySet()) {
this.reached.put(v, false);
}
this.stack.add(vertex);
this.reached.put(vertex, true);
}
public boolean hasNext() {
return !stack.isEmpty();
}
public Vertex next() {
this.current = this.stack.pop();
Set<Vertex> neighborsSet = adjacencyMap.get(this.current).keySet();
for (Vertex v : neighborsSet) {
if (this.reached.get(v)) {
if (this.stack.remove(v)) stack.add(v);
} else {
this.stack.add(v);
this.reached.put(v, true);
}
}
return current;
}
public void remove() {
throw new UnsupportedOperationException();
}
}
// ESERCIZI
/*
* Un grafo è detto fortementeConnesso quando per ogni vertice
* si può raggiungere un qualsiasi altro vertice del grafo
*/
public boolean isStronglyConnected() {
for (Vertex SS : adjacencyMap.keySet()) {
Iterator<Vertex> it = this.breadthFirstIterator(SS);
int counter = 0;
while (it.hasNext()) {
counter++;
it.next();
}
if (counter < adjacencyMap.size()) return false;
}
return true;
}
}