Calcolo spanning tree

This commit is contained in:
L3o15 2025-05-29 10:16:59 +00:00
parent 7ded8fc62c
commit 8d022781eb
5 changed files with 176 additions and 8 deletions

View file

@ -31,4 +31,15 @@ public class Coordinata {
", altezza=" + altezza +
'}';
}
public double calcolaDistanza(Coordinata c, TipoVeicolo tipoVeicolo){
if (tipoVeicolo == TipoVeicolo.METZTLI){
return Math.abs(altezza - c.getAltezza());
} else if (tipoVeicolo == TipoVeicolo.TONATIUH){
return Math.sqrt(Math.pow(x - c.getX(), 2) + Math.pow(y - c.getY(), 2));
}
return -1;
}
}

View file

@ -1,17 +1,25 @@
package it.unibs.arnaldo.rovineperdute;
import java.util.HashMap;
import java.util.List;
import java.util.*;
public class Graph {
private final HashMap<RovinaPerduta, List<RovinaPerduta>> graph = new HashMap<>();
private final HashMap<RovinaPerduta, List<RovinaPerduta>> graph;
public Graph(){}
public Graph(){
graph = new HashMap<>();
}
public Graph(HashMap<RovinaPerduta, List<RovinaPerduta>> graph){
this.graph = graph;
}
public void add(RovinaPerduta rp, List<RovinaPerduta> links) {
graph.put(rp, links);
}
public HashMap<RovinaPerduta, List<RovinaPerduta>> getGraph() {
return graph;
}
public List<RovinaPerduta> getListaCollegamenti(RovinaPerduta rp){
return graph.get(rp);
}
@ -28,4 +36,68 @@ public class Graph {
}
return ret.toString();
}
public List<RovinaPerdutaGrafo> calcolaSpanningTree(RovinaPerduta puntoPartenza, TipoVeicolo tipo){
HashMap<RovinaPerduta, Double> distanze = new HashMap<>();
HashMap<RovinaPerduta, RovinaPerduta> predecessori = new HashMap<>();
HashMap<RovinaPerduta, Integer> salti = new HashMap<>();
Queue<RovinaPerduta> coda = new PriorityQueue<>(Comparator.comparingDouble(distanze::get));
// inizializzazione variabili
for (RovinaPerduta rp : graph.keySet()) {
distanze.put(rp, Double.POSITIVE_INFINITY);
salti.put(rp, Integer.MAX_VALUE);
}
distanze.put(puntoPartenza, 0.0);
coda.add(puntoPartenza);
salti.put(puntoPartenza, 0);
// fino a quando non ho visitato tutti i percorsi
while (!coda.isEmpty()){
RovinaPerduta rp = coda.poll();
List<RovinaPerduta> listaVicine = graph.get(rp);
for (RovinaPerduta vicina : listaVicine){
double distanza = rp.getCoordinata().calcolaDistanza(vicina.getCoordinata(), tipo);
double nuovaDistanza = distanze.get(rp) + distanza;
double distanzaAttuale = distanze.get(vicina);
int nuoviSalti = salti.get(rp) + 1;
int saltiAttuali = salti.get(vicina);
// aggiorno la distanza
if (nuovaDistanza < distanzaAttuale
|| (Double.compare(nuovaDistanza, distanzaAttuale) == 0 && nuoviSalti < saltiAttuali)
|| (Double.compare(nuovaDistanza, distanzaAttuale) == 0 && nuoviSalti == saltiAttuali && rp.getId() > predecessori.getOrDefault(vicina, rp).getId())) {
distanze.put(vicina, nuovaDistanza);
predecessori.put(vicina, rp);
salti.put(vicina, nuoviSalti);
coda.add(vicina);
}
}
}
// trovo la rovina perduta
RovinaPerduta rovinePerdute = null;
int maxId = 0;
for (RovinaPerduta rp : graph.keySet()) {
if (rp.getId() > maxId) {
maxId = rp.getId();
rovinePerdute = rp;
}
}
// ricostruisce il percorso dal punto di partenza alla rovina perduta
LinkedList<RovinaPerdutaGrafo> percorso = new LinkedList<>();
RovinaPerduta corrente = rovinePerdute;
while (corrente != null) {
percorso.addFirst(new RovinaPerdutaGrafo(corrente.getCoordinata(), corrente.getNome(), corrente.getId(), distanze.get(corrente)));
corrente = predecessori.get(corrente);
}
return percorso;
}
}

View file

@ -2,6 +2,7 @@ package it.unibs.arnaldo.rovineperdute;
import javax.xml.stream.*;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
@ -10,7 +11,7 @@ import java.util.List;
public class Parser {
// rovina = città
public static void parseRovinePerduteXML(String fileName) {
public static Graph parseRovinePerduteXML(String fileName) {
XMLInputFactory xmlif;
XMLStreamReader xmlr = null;
@ -60,7 +61,7 @@ public class Parser {
if (endTag.equals("city")) {
mappaCollegamenti.put(cityId, link);
link = new ArrayList<>();
RovinaPerduta rovinaPerduta = new RovinaPerduta(new Coordinata(x, y, h), nome);
RovinaPerduta rovinaPerduta = new RovinaPerduta(new Coordinata(x, y, h), nome, cityId);
nome = null;
x = -1;
y = -1;
@ -94,10 +95,69 @@ public class Parser {
grafo.add(rp, listaCollegamenti);
}
System.out.println(grafo);
return grafo;
} catch (FactoryConfigurationError | XMLStreamException | IOException e) {
System.out.println("Error reading the file: " + e.getMessage());
return null;
}
}
public static void generaXML(List<RovinaPerdutaGrafo> minimumTreeTonatium, List<RovinaPerdutaGrafo> minimumTreeMetztli) {
String fileName = "routes.xml";
try (FileOutputStream outputStream = new FileOutputStream(fileName)) {
XMLOutputFactory xmlOutputFactory = XMLOutputFactory.newInstance();
XMLStreamWriter xmlWriter = xmlOutputFactory.createXMLStreamWriter(outputStream, "UTF-8");
xmlWriter.writeStartDocument("UTF-8", "1.0");
xmlWriter.writeStartElement("routes");
// Tonatiuh
double consumoTonatiuh = minimumTreeTonatium.get(minimumTreeTonatium.size() - 1).getDistanza();
int numeroCittaTonatiuh = minimumTreeTonatium.size();
xmlWriter.writeStartElement("route");
xmlWriter.writeAttribute("team", "Tonatiuh");
xmlWriter.writeAttribute("cost", String.format("%.0f", consumoTonatiuh));
xmlWriter.writeAttribute("cities", String.valueOf(numeroCittaTonatiuh));
for (RovinaPerdutaGrafo citta : minimumTreeTonatium) {
xmlWriter.writeStartElement("city");
xmlWriter.writeAttribute("id", String.valueOf(citta.getId()));
xmlWriter.writeAttribute("name", citta.getNome());
xmlWriter.writeEndElement(); // city
}
xmlWriter.writeEndElement(); // route
// Metztli
double consumoMetztli = minimumTreeMetztli.get(minimumTreeMetztli.size() - 1).getDistanza();
int numeroCittaMetztli = minimumTreeMetztli.size();
xmlWriter.writeStartElement("route");
xmlWriter.writeAttribute("team", "Metztli");
xmlWriter.writeAttribute("cost", String.format("%.0f", consumoMetztli));
xmlWriter.writeAttribute("cities", String.valueOf(numeroCittaMetztli));
for (RovinaPerdutaGrafo citta : minimumTreeMetztli) {
xmlWriter.writeStartElement("city");
xmlWriter.writeAttribute("id", String.valueOf(citta.getId()));
xmlWriter.writeAttribute("name", citta.getNome());
xmlWriter.writeEndElement(); // city
}
xmlWriter.writeEndElement();
xmlWriter.writeEndElement();
xmlWriter.writeEndDocument();
xmlWriter.flush();
System.out.println("File 'routes.xml' generato correttamente.");
} catch (XMLStreamException | IOException e) {
System.out.println("Errore durante la scrittura del file XML: " + e.getMessage());
}
}
}

View file

@ -3,10 +3,12 @@ package it.unibs.arnaldo.rovineperdute;
public class RovinaPerduta {
private final Coordinata coordinata;
private final String nome;
private final int id;
public RovinaPerduta(Coordinata coordinata, String nome) {
public RovinaPerduta(Coordinata coordinata, String nome, int id) {
this.coordinata = coordinata;
this.nome = nome;
this.id = id;
}
public Coordinata getCoordinata() {
@ -17,6 +19,10 @@ public class RovinaPerduta {
return nome;
}
public int getId(){
return id;
}
@Override
public String toString() {
return nome + " (" + coordinata.getX() + ", " + coordinata.getY() + ", " + coordinata.getAltezza() + ")";

View file

@ -0,0 +1,19 @@
package it.unibs.arnaldo.rovineperdute;
public class RovinaPerdutaGrafo extends RovinaPerduta{
private final double distanza;
public RovinaPerdutaGrafo(Coordinata coordinata, String nome, int id, double distanza) {
super(coordinata, nome, id);
this.distanza = distanza;
}
public double getDistanza() {
return distanza;
}
@Override
public String toString(){
return getNome() + " (" + getCoordinata().getX() + ", " + getCoordinata().getY() + ", " + getCoordinata().getAltezza() + ") Distanza: " + distanza;
}
}