Salve per motivi di studio mi trovo a dover studiare analizzare e commentare l'algoritmo di Dijkstra utilizzato in un modo e in un contesto molto creativo.
L'input consiste in una sequenza di offerte di biglietti e una serie di itinerari di
viaggio da realizzare.
La sequenza inizia con una riga contenente N, il numero di offerte di biglietti,
seguito da N descrizioni, una per riga. Ogni descrizione consiste in un numero
reale positivo che specifica il prezzo del biglietto, il numero di città previste
dall’itinerario del biglietto, e poi così l’elenco delle città. Ogni città è identificata da
un numero intero positivo.
La riga successiva contiene L, il numero di itinerari il cui costo deve essere
minimizzato. Le L righe successive indicano il percorso previsto dall’itinerario.
Ogni riga è composta dal numero di città dell'itinerario (compresa la città di
partenza), seguita da una sequenza di numeri che rappresentano le città
nell'ordine in cui devono essere visitate.
Per ogni itinerario, il programma deve produrre in output il numero che
contraddistingue l’itinerario, il costo minimo da pagare e i biglietti utilizzati per il
viaggio, nell'ordine in cui saranno utilizzati.
Es:
INPUT:
3
225 3 1 3 4
200 2 1 2
50 2 2 3
1
2 1 3
OUTPUT
Itinerario 1:
Costo = 225
Biglietto N. : 1
Qualcuno è in grado di spiegarmi come questo programma svolge questo compito? Vengono utilizzate delle strutture avanzate e delle classi che non conosco, se qualcuno riuscisse a commentare questo codice mi aiuterebbe a fare enormi passi avanti.
import java.io.File;
import java.io.FileNotFoundException;
import javafx.util.Pair;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.PriorityQueue;
import java.util.Scanner;
public class Airline {
//classe edge: un edge contiene una relazione, nello specifico la sorgente, la destinazione e il peso
static class Edge {
int source;
int destination;
int weight;
//costruttore della classe edge
public Edge(int source, int destination, int weight) {
this.source = source;
this.destination = destination;
this.weight = weight;
}
}
//classe graph: ho scelto la rappresentazione tramite linkedlist, perchè la LinkedList è una struttura di dati lineare,
//gli elementi LinkedList sono collegati tra loro utilizzando i puntatori. Nello specifico creo una Linkedlist di Edge.
static class Graph
{
int vertices;
LinkedList<Edge>[] adjacencylist;
Graph(int vertices)
{
this.vertices = vertices;
adjacencylist = new LinkedList[vertices];
for (int i = 0; i <vertices ; i++) {
adjacencylist[i] = new LinkedList<>();
}
}
public void addEdge(int source, int destination, int weight)
{
Edge edge = new Edge(source, destination, weight);
adjacencylist[source].addFirst(edge);
edge = new Edge(destination, source, weight);
adjacencylist[destination].addFirst(edge);
}
public void dijkstra_GetMinDistances(int sourceVertex,int destinationV){
boolean[] SPT = new boolean[vertices];
int [] distance = new int[vertices];
for (int i = 0; i <vertices ; i++) {
distance[i] = Integer.MAX_VALUE;
}
PriorityQueue<Pair<Integer, Integer>> pq = new PriorityQueue<>(vertices, new Comparator<Pair<Integer, Integer>>() {
@Override
public int compare(Pair<Integer, Integer> p1, Pair<Integer, Integer> p2) {
int key1 = p1.getKey();
int key2 = p2.getKey();
return key1-key2;
}
});
distance[0] = 0;
Pair<Integer, Integer> p0 = new Pair<>(distance[0],0);
pq.offer(p0);
while(!pq.isEmpty()){
Pair<Integer, Integer> extractedPair = pq.poll();
int extractedVertex = extractedPair.getValue();
if(SPT[extractedVertex]==false) {
SPT[extractedVertex] = true;
LinkedList<Edge> list = adjacencylist[extractedVertex];
for (int i = 0; i < list.size(); i++) {
Edge edge = list.get(i);
int destination = edge.destination;
if (SPT[destination] == false) {
int newKey = distance[extractedVertex] + edge.weight ;
int currentKey = distance[destination];
if(currentKey>newKey){
Pair<Integer, Integer> p = new Pair<>(newKey, destination);
pq.offer(p);
distance[destination] = newKey;
}
}
}
}
}
printDijkstra(distance, sourceVertex,destinationV);
}
public void printDijkstra(int[] distance, int sourceVertex,int dv){
for (int i = 0; i <vertices ; i++) {
if(dv-1==(i))
System.out.println("Costo = " + distance[i]);
}
}
public static void main(String[] args) throws FileNotFoundException {
int vertices = 4;
Graph graph = new Graph(vertices);
File file = new File("input.txt");
Scanner sc = new Scanner(file);
int numLines=0;
while (sc.hasNextLine())
{ numLines++;
sc.nextLine();
}
int i=0;
sc= new Scanner(file);
String[] data = new String[numLines];
while (sc.hasNextLine())
{
data[i]= sc.nextLine();
i++;
}
int n= Integer.parseInt(data[0]);
for(i=0;i<=n;i++)
{
String[] s= data[i].split(" ");
for(int j=2;j<s.length-1;j++)
{
graph.addEdge( Integer.parseInt(s[j])-1,Integer.parseInt(s[j+1])-1,Integer.parseInt(s[0]));
}
}
int np = Integer.parseInt(data[n+1]);
n+=2;
for(i=0;i<np;i++)
{
System.out.println("Itinerario "+(i+1));
String[] s= data[n+i].split(" ");
graph.dijkstra_GetMinDistances(Integer.parseInt(s[s.length-2])-1,Integer.parseInt(s[s.length-1]));
System.out.println("Biglietto = "+s[1]);
}
}
}
}