/** * Verifica che i costi minimi tra tutti i nodi siano uguali tra il grafo originale e il grafo a * cui sono stati aggiunti i nodi per fare in modo che non ci siano archi tassati consecutivi o * più archi tassati entranti o uscenti dallo stesso nodo e che non ci siano archi tassati che * escono da una sorgente o archi tassati che entrano in una destinazione. * * @param originalGraph grafo originale. * @param addNodesGraph grafo con i nodi aggiunti. * @return true se i due grafi corrispondono false altrimenti. */ public static boolean testAddNodes(Graph originalGraph, Graph addNodesGraph) { // Scorro tutti i nodi for (int i = 0; i < NODES; i++) { // Applico Dijkstra a entrambe la matrici int[] costsOriginalGraph = Dijkstra.dijkstra(originalGraph, i, true); int[] costsAddNodesGraph = Dijkstra.dijkstra(addNodesGraph, i, true); // Controllo i valori dei primi N nodi for (int j = 0; j < costsOriginalGraph.length; j++) { if (costsAddNodesGraph[j] != costsOriginalGraph[j]) { System.err.println( "Il percorso minimo tra (" + i + "," + j + ") non corrisponde. Archi tassati = true"); System.err.println("Orginal graph: " + toStringArray(costsOriginalGraph)); System.err.println("Orginal graph: " + toStringArray(originalGraph.getLabels())); System.err.println("Orginal graph: " + toStringArray(costsAddNodesGraph)); System.err.println("Orginal graph: " + toStringArray(addNodesGraph.getLabels())); return false; } } int[] addNodeLabels = addNodesGraph.getLabels(); // Verifico anche quelli che sono stati aggiunti: i nodi nuovi sul grafo // "espanso" devono avere lo stesso costo che i avevano i nodi originali // prima dell'espansione. for (int j = costsOriginalGraph.length; j < costsAddNodesGraph.length; j++) { int originalNode = addNodeLabels[j]; if (costsOriginalGraph[originalNode] != costsAddNodesGraph[j]) { System.err.println( "Il percorso minimo tra (" + i + "," + j + ") non corrisponde. Archi tassati = true"); System.err.println("Orginal graph: " + toStringArray(costsOriginalGraph)); System.err.println("Orginal graph: " + toStringArray(originalGraph.getLabels())); System.err.println("Orginal graph: " + toStringArray(costsAddNodesGraph)); System.err.println("Orginal graph: " + toStringArray(addNodesGraph.getLabels())); return false; } } } // Scorro tutti i nodi for (int i = 0; i < NODES; i++) { // Applico Dijkstra a entrambe la matrici int[] costsOriginalGraph = Dijkstra.dijkstra(originalGraph, i, false); int[] costsAddNodesGraph = Dijkstra.dijkstra(addNodesGraph, i, false); // Controllo i valori dei primi N nodi for (int j = 0; j < costsOriginalGraph.length; j++) { if (costsAddNodesGraph[j] != costsOriginalGraph[j]) { System.err.println( "Il percorso minimo tra (" + i + "," + j + ") non corrisponde. Archi tassati = false"); System.err.println("Orginal graph: " + toStringArray(costsOriginalGraph)); System.err.println("Orginal graph: " + toStringArray(originalGraph.getLabels())); System.err.println("Orginal graph: " + toStringArray(costsAddNodesGraph)); System.err.println("Orginal graph: " + toStringArray(addNodesGraph.getLabels())); return false; } } int[] addNodeLabels = addNodesGraph.getLabels(); // Verifico anche quelli che sono stati aggiunti: i nodi nuovi sul grafo // "espanso" devono avere lo stesso costo che i avevano i nodi originali // prima dell'espansione. for (int j = costsOriginalGraph.length; j < costsAddNodesGraph.length; j++) { int originalNode = addNodeLabels[j]; if (costsOriginalGraph[originalNode] != costsAddNodesGraph[j]) { System.err.println( "Il percorso minimo tra (" + i + "," + j + ") non corrisponde. Archi tassati = false"); System.err.println("Orginal graph: " + toStringArray(costsOriginalGraph)); System.err.println("Orginal graph: " + toStringArray(originalGraph.getLabels())); System.err.println("Orginal graph: " + toStringArray(costsAddNodesGraph)); System.err.println("Orginal graph: " + toStringArray(addNodesGraph.getLabels())); return false; } } } return true; }
/** * Verifica che il grafo originale sia equivalente all'SPGM "totale". 1) Le commodity siano le * stesse (ovviamente con gli indici convertiti per l'SPGM). 2) Gli archi tassati siano gli stessi * (ovviamente con gli indici convertiti per l'SPGM). 3) I costi degli archi tassati siano gli * stessi. 4) I costi tra sorgenti e nodi da cui iniziano gli archi tassati corrispondano. 5) I * costi tra nodi terminali di archi tassati e le destinazioni corrispondano. 6) I costi dei * percorsi non tassati tra sorgenti e destinazioni corrispondano. * * @param originalGraph grafo originale. * @param totalSPGM SPGM "totale". * @return true se se i due grafi corrispondono, false altrimenti. */ public static boolean testTotalSPGMWithoutReduction(Graph originalGraph, Graph totalSPGM) { // Partendo dal SPGM grafo originale estraggo i suoi archi tassati. // Estraggo anche gli archi tassati del totalSPGM. Gli archi e i costi // devono coincidere. Arc[][] originalMap = originalGraph.getGraph(); Arc[][] totalSPGMMap = totalSPGM.getGraph(); int[] totalSPGMLabels = totalSPGM.getLabels(); ArrayList<TassedArc> originalGraphTassedArcs = new ArrayList<TassedArc>(); ArrayList<TassedArc> totalSPGMTassedArcs = new ArrayList<TassedArc>(); for (int i = 0; i < originalMap.length; i++) { for (int j = 0; j < originalMap.length; j++) { try { if (originalMap[i][j].exist() && originalMap[i][j].getTariffed()) { TassedArc tassedArc = new TassedArc( i, i, j, j, originalMap[i][j].getCost(), originalMap[i][j].getTariffedLength()); originalGraphTassedArcs.add(tassedArc); } } catch (ArcNotDefinedException e) { System.err.println( "originalMap[" + i + "][" + j + "] non è definita in \"testTotalSPGM\"!"); } catch (ArcNotTariffedException e) { System.err.println( "originalMap[" + i + "][" + j + "] non è tassato in \"testTotalSPGM\"!"); } } } for (int i = 0; i < totalSPGMMap.length; i++) { for (int j = 0; j < totalSPGMMap.length; j++) { try { if (totalSPGMMap[i][j].exist() && totalSPGMMap[i][j].getTariffed()) { int sourceLabel = totalSPGMLabels[i]; int destinationLabel = totalSPGMLabels[j]; TassedArc tassedArc = new TassedArc( i, sourceLabel, j, destinationLabel, totalSPGMMap[i][j].getCost(), totalSPGMMap[i][j].getTariffedLength()); totalSPGMTassedArcs.add(tassedArc); } } catch (ArcNotDefinedException e) { System.err.println( "originalMap[" + i + "][" + j + "] non è definita in \"testTotalSPGM\"!"); } catch (ArcNotTariffedException e) { System.err.println( "originalMap[" + i + "][" + j + "] non è tassato in \"testTotalSPGM\"!"); } } } // Se la dimensione dei due arrayList non corrisponde posso già dire che // c'è qualcosa che non è andato per il verso giusto. if (originalGraphTassedArcs.size() != totalSPGMTassedArcs.size()) { System.err.println("Il numero di archi tassati tra il grafo originale e l'SPGM è diverso."); return false; } TassedArc[][] tassedArcses = new TassedArc[originalGraphTassedArcs.size()][2]; // Verifico se gli archi tassati corrispondono per sorgente, destinazione // e costo. Ne approfitto per salvare le relazioni tra gli archi dei due // grafi. for (int i = 0; i < originalGraphTassedArcs.size(); i++) { TassedArc originalTassedArc = originalGraphTassedArcs.get(i); boolean exist = false; for (int j = 0; j < totalSPGMTassedArcs.size(); j++) { TassedArc totalSPGMTassedArc = totalSPGMTassedArcs.get(j); try { if (originalTassedArc.getOriginNode() == totalSPGMTassedArc.getLabelOriginNode() && originalTassedArc.getDestinationNode() == totalSPGMTassedArc.getLabelDestinationNode() && originalTassedArc.getArc().getCost() == totalSPGMTassedArc.getArc().getCost()) { exist = true; tassedArcses[i][0] = originalTassedArc; tassedArcses[i][1] = totalSPGMTassedArc; } } catch (ArcNotDefinedException e) { System.err.println( "L'arco [" + originalTassedArc.getOriginNode() + "][" + originalTassedArc.getDestinationNode() + "] non è definita in \"testTotalSPGM\"!"); } } if (!exist) { System.err.println( "Non sono riuscito a trovare il nodo tassato equivalente tra il grafo originale e l'SPGM."); return false; } } // Calcolo per ogni arco tassato sul grafo originale il costo minimo // tra la fine e l'inizio di due archi tassati e verifico che sia uguale // anche per il totalSPGM. for (int i = 0; i < tassedArcses.length; i++) { TassedArc originalTassedArc = tassedArcses[i][0]; TassedArc totalSPGMTassedArc = tassedArcses[i][1]; for (int j = 0; j < tassedArcses.length; j++) { // Salto se stesso if (i == j) { continue; } TassedArc originalTassedArc2 = tassedArcses[j][0]; TassedArc totalSPGMTassedArc2 = tassedArcses[j][1]; int[] costsArray = Dijkstra.dijkstra(originalGraph, originalTassedArc.getDestinationNode(), false); int costBetweenOriginalTassedArcEndAndOriginalTassedArc2Start = costsArray[originalTassedArc2.getOriginNode()]; Arc arc = totalSPGMMap[totalSPGMTassedArc.getDestinationNode()][ totalSPGMTassedArc2.getOriginNode()]; if (!arc.exist() && costBetweenOriginalTassedArcEndAndOriginalTassedArc2Start == Integer.MAX_VALUE) { continue; } try { int costBetweenTotalSPGMTassedArcEndAndTotalSPGMTassedArc2Start = arc.getCost(); if (costBetweenTotalSPGMTassedArcEndAndTotalSPGMTassedArc2Start != costBetweenOriginalTassedArcEndAndOriginalTassedArc2Start) { System.err.println( "L'arco che collega il nodo " + originalTassedArc.getDestinationNode() + " inizio di un arco tassato al nodo " + originalTassedArc2.getOriginNode() + " non ha lo stesso peso tra il grafo originale e l'SPGM "); return false; } } catch (ArcNotDefinedException e) { System.err.println( "L'arco [" + totalSPGMTassedArc.getDestinationNode() + "][" + totalSPGMTassedArc2.getOriginNode() + "] non è definita in \"testTotalSPGM\"!"); } } } // Devo verificare che le commodity corrispondano cioè che siano le // stesse (opportunamente convertite per l'SPGM). Commodity[] originalCommodities = originalGraph.getCommodities(); Commodity[] totalSPGMCommodities = totalSPGM.getCommodities(); // Se il numero non corrisponde posso già dire che c'è qualcosa che non va if (originalCommodities.length != totalSPGMCommodities.length) { System.err.print( "Il numero delle commodity differisce tra il grafo originale e il totalSPGM"); return false; } // Conto sul fatto che per come ho costruito l'SPGM l'ordine delle // commodity delle SPGM non è cambiato rispetto al grafo iniziale. for (int i = 0; i < originalCommodities.length; i++) { Commodity originalCommodity = originalCommodities[i]; Commodity totalSPGMCommodity = totalSPGMCommodities[i]; int originalCommoditySource = originalCommodity.getSource(); int originalCommodityDestination = originalCommodity.getDestination(); int totalSPGMCommodityConvertitedSource = totalSPGMLabels[totalSPGMCommodity.getSource()]; int totalSPGMCommodityConvertitedDestination = totalSPGMLabels[totalSPGMCommodity.getDestination()]; if (originalCommoditySource != totalSPGMCommodityConvertitedSource || originalCommodityDestination != totalSPGMCommodityConvertitedDestination) { System.err.print("Le commodities non corrispondono tra il grafo originale e il totalSPGM"); return false; } } // Devo verificare per ogni commodity che il costo minimo tra sorgente e // i nodi da cui iniziano gli archi tassati sia uguale al costo degli // archi tra la sorgente e il nodo iniziale dell'arco tassato del SPGM. // Devo anche verificare che l'arco che collega sorgente e destinazione // del grafo originale abbia lo stesso costo anche per l'SPGM. // Scorro tutte le commodity e per ogni commodity tutti gli archi tassati. for (int i = 0; i < originalCommodities.length; i++) { int originalSource = originalCommodities[i].getSource(); int originalDestination = originalCommodities[i].getDestination(); int[] originalCostsBetweenSourceAndOtherNodes = Dijkstra.dijkstra(originalGraph, originalSource, false); int sPGMSource = totalSPGMCommodities[i].getSource(); int sPGMDestination = totalSPGMCommodities[i].getDestination(); for (int j = 0; j < tassedArcses.length; j++) { TassedArc originalTassedArc = tassedArcses[j][0]; TassedArc sPGMTassedArc = tassedArcses[j][1]; // Source -> nodo iniziale arco tassato. int originalCostBetweenSourceAndTassedArcStartNode = originalCostsBetweenSourceAndOtherNodes[originalTassedArc.getOriginNode()]; Arc sPGMArcBetweenSPGMSourceAndTassedArcSPGMDestination = totalSPGMMap[sPGMSource][sPGMTassedArc.getOriginNode()]; if (!sPGMArcBetweenSPGMSourceAndTassedArcSPGMDestination.exist() && originalCostBetweenSourceAndTassedArcStartNode == Integer.MAX_VALUE) { // OK } else { try { if (originalCostBetweenSourceAndTassedArcStartNode != sPGMArcBetweenSPGMSourceAndTassedArcSPGMDestination.getCost()) { System.err.println( "L'arco che collega il nodo " + originalSource + " inizio di un arco tassato al nodo " + originalTassedArc.getOriginNode() + " non ha lo stesso peso tra il grafo originale e l'SPGM "); return false; } } catch (ArcNotDefinedException e) { System.err.println( "L'arco [" + sPGMSource + "][" + sPGMTassedArc.getOriginNode() + "] non è definita in \"testTotalSPGM\"!"); } } // Nodo finale arco tassato -> destination. int[] originalCostsBetweenTassedArcEndNodeAndOtherNodes = Dijkstra.dijkstra(originalGraph, originalTassedArc.getDestinationNode(), false); int originalCostsBetweenTassedArcEndNodeAndOriginalDestination = originalCostsBetweenTassedArcEndNodeAndOtherNodes[originalDestination]; Arc sPGMArcBetweenTassedArcEndNodeAndSPGMDestination = totalSPGMMap[sPGMTassedArc.getDestinationNode()][sPGMDestination]; if (!sPGMArcBetweenTassedArcEndNodeAndSPGMDestination.exist() && originalCostsBetweenTassedArcEndNodeAndOriginalDestination == Integer.MAX_VALUE) { // OK } else { try { if (originalCostsBetweenTassedArcEndNodeAndOriginalDestination != sPGMArcBetweenTassedArcEndNodeAndSPGMDestination.getCost()) { System.err.println( "L'arco che collega il nodo " + originalTassedArc.getDestinationNode() + " inizio di un arco tassato al nodo " + originalDestination + " non ha lo stesso peso tra il grafo originale e l'SPGM "); return false; } } catch (ArcNotDefinedException e) { System.err.println( "L'arco [" + originalTassedArc.getDestinationNode() + "][" + originalDestination + "] non è definita in \"testTotalSPGM\"!"); } } } // Verifico anche il percorso non tassato tra sorgente e destinazione // della commodity. int originalCostsBetweenSourceAndDestination = originalCostsBetweenSourceAndOtherNodes[originalDestination]; Arc sPGMArcBetweenSPGMSourceAndSPGMDestination = totalSPGMMap[sPGMSource][sPGMDestination]; if (!sPGMArcBetweenSPGMSourceAndSPGMDestination.exist() && originalCostsBetweenSourceAndDestination == Integer.MAX_VALUE) { // OK } else { try { if (originalCostsBetweenSourceAndDestination != sPGMArcBetweenSPGMSourceAndSPGMDestination.getCost()) { System.err.println( "L'arco che collega il nodo " + originalSource + " inizio di un arco tassato al nodo " + originalDestination + " non ha lo stesso peso tra il grafo originale e l'SPGM "); return false; } } catch (ArcNotDefinedException e) { System.err.println( "L'arco [" + originalSource + "][" + originalDestination + "] non è definita in \"testTotalSPGM\"!"); } } } return true; }