From: Stefan F. <ste...@us...> - 2010-05-12 18:50:35
|
Update of /cvsroot/rails/18xx/rails/algorithms In directory sfp-cvsdas-4.v30.ch3.sourceforge.com:/tmp/cvs-serv7190/rails/algorithms Modified Files: RevenueCalculator.java RevenueAdapter.java Log Message: Some minor RC improvements Index: RevenueCalculator.java =================================================================== RCS file: /cvsroot/rails/18xx/rails/algorithms/RevenueCalculator.java,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -d -r1.11 -r1.12 *** RevenueCalculator.java 11 May 2010 21:47:21 -0000 1.11 --- RevenueCalculator.java 12 May 2010 18:50:26 -0000 1.12 *************** *** 9,12 **** --- 9,13 ---- private final int nbVertexes; private final int nbTrains; + private final int nbEdges; // static vertex data *************** *** 15,21 **** private final boolean[] vertexMinor; private final int[] vertexNbNeighbors; ! private final int[] vertexNbBlocks; private final int[][] vertexNeighbors; private final int[][] vertexVisitSets; --- 16,23 ---- private final boolean[] vertexMinor; private final int[] vertexNbNeighbors; ! private final int[] vertexNbVisitSets; private final int[][] vertexNeighbors; + private final int[][] vertexEdges; private final int[][] vertexVisitSets; *************** *** 24,32 **** // static edge data ! private final boolean[][] edgeGreedy; ! private final int[][] edgeDistance; // dynamic edge data ! private final boolean[][] edgeUsed; // static train data --- 26,34 ---- // static edge data ! private final boolean[] edgeGreedy; ! private final int[] edgeDistance; // dynamic edge data ! private final boolean[] edgeUsed; // static train data *************** *** 41,44 **** --- 43,47 ---- private final boolean[][] trainVisited; private final int[][] trainVertexStack; + private final int[][] trainEdgeStack; private final int[] trainStackPos; private final int [] trainBottomPos; *************** *** 63,67 **** private int countVisits; private int countEdges; ! private int nbEdges; private int nbEvaluations; private int nbPredictions; --- 66,70 ---- private int countVisits; private int countEdges; ! private int nbEdgesTravelled; private int nbEvaluations; private int nbPredictions; *************** *** 82,92 **** ! public RevenueCalculator (RevenueAdapter revenueAdapter, int nbVertexes, int maxNeighbors, int maxBlocks, int nbTrains) { ! log.info("RC defined: nbVertexes = " + nbVertexes + ", maxNeighbors = " + maxNeighbors + ", maxBlocks = " + maxBlocks + ", nbTrains = " + nbTrains); this.revenueAdapter = revenueAdapter; this.nbVertexes = nbVertexes; this.nbTrains = nbTrains; --- 85,96 ---- ! public RevenueCalculator (RevenueAdapter revenueAdapter, int nbVertexes, int nbEdges, int maxNeighbors, int maxBlocks, int nbTrains) { ! log.info("RC defined: nbVertexes = " + nbVertexes + ", nbEdges = " + nbEdges + ", maxNeighbors = " + maxNeighbors + ", maxBlocks = " + maxBlocks + ", nbTrains = " + nbTrains); this.revenueAdapter = revenueAdapter; this.nbVertexes = nbVertexes; + this.nbEdges = nbEdges; this.nbTrains = nbTrains; *************** *** 98,108 **** vertexMinor = new boolean[nbVertexes]; vertexNbNeighbors = new int[nbVertexes]; ! vertexNbBlocks = new int[nbVertexes]; ! vertexNeighbors = new int[nbVertexes][maxNeighbors]; vertexVisitSets = new int[nbVertexes][maxBlocks]; ! edgeGreedy = new boolean[nbVertexes][nbVertexes]; ! edgeDistance = new int[nbVertexes][nbVertexes]; ! edgeUsed = new boolean[nbVertexes][nbVertexes]; trainMaxMajors = new int[nbTrains]; --- 102,113 ---- vertexMinor = new boolean[nbVertexes]; vertexNbNeighbors = new int[nbVertexes]; ! vertexNbVisitSets = new int[nbVertexes]; ! vertexNeighbors = new int[nbVertexes][maxNeighbors]; ! vertexEdges = new int[nbVertexes][maxNeighbors]; vertexVisitSets = new int[nbVertexes][maxBlocks]; ! edgeGreedy = new boolean[nbEdges]; ! edgeDistance = new int[nbEdges]; ! edgeUsed = new boolean[nbEdges]; trainMaxMajors = new int[nbTrains]; *************** *** 115,118 **** --- 120,124 ---- trainVisited = new boolean[nbTrains][nbVertexes]; trainVertexStack = new int[nbTrains][nbVertexes]; + trainEdgeStack = new int[nbTrains][nbVertexes]; trainStackPos = new int[nbTrains]; trainBottomPos = new int[nbTrains]; *************** *** 129,133 **** // default neighbors && blocks vertexNbNeighbors[id] = 0; ! vertexNbBlocks[id] = 0; } --- 135,139 ---- // default neighbors && blocks vertexNbNeighbors[id] = 0; ! vertexNbVisitSets[id] = 0; } *************** *** 136,143 **** } ! void setVertexNeighbors(int id, int[] neighbors) { // copy neighbors for (int j=0; j < neighbors.length; j++) { vertexNeighbors[id][j] = neighbors[j]; } vertexNbNeighbors[id] = neighbors.length; --- 142,150 ---- } ! void setVertexNeighbors(int id, int[] neighbors, int[] edges) { // copy neighbors for (int j=0; j < neighbors.length; j++) { vertexNeighbors[id][j] = neighbors[j]; + vertexEdges[id][j] = edges[j]; } vertexNbNeighbors[id] = neighbors.length; *************** *** 150,154 **** vertexVisitSets[id][j] = blocks[j]; } ! vertexNbBlocks[id] = blocks.length; } --- 157,161 ---- vertexVisitSets[id][j] = blocks[j]; } ! vertexNbVisitSets[id] = blocks.length; } *************** *** 158,164 **** ! void setEdge(int vertexLo, int vertexHi, boolean greedy, int distance) { ! edgeGreedy[vertexLo][vertexHi] = greedy; ! edgeDistance[vertexLo][vertexHi] = distance; } --- 165,171 ---- ! void setEdge(int edgeId, boolean greedy, int distance) { ! edgeGreedy[edgeId] = greedy; ! edgeDistance[edgeId] = distance; } *************** *** 183,187 **** if (useRevenuePrediction) statistics.append(", " + nbPredictions + " predictions"); ! statistics.append(" and " + nbEdges + " edges travelled."); return statistics.toString(); } --- 190,194 ---- if (useRevenuePrediction) statistics.append(", " + nbPredictions + " predictions"); ! statistics.append(" and " + nbEdgesTravelled + " edges travelled."); return statistics.toString(); } *************** *** 237,251 **** if (startTrain > finalTrain) return; - - nbEvaluations = 0; nbPredictions = 0; nbEdges = 0; useRevenuePrediction = true; this.maxCumulatedTrainRevenues = new int[nbTrains]; ! initRevenueValues(startTrain, finalTrain); if (startTrain == finalTrain) return; // start prediction runs ! nbEvaluations = 0; nbPredictions = 0; nbEdges = 0; log.info("RC: start individual prediction Runs"); --- 244,256 ---- if (startTrain > finalTrain) return; useRevenuePrediction = true; this.maxCumulatedTrainRevenues = new int[nbTrains]; ! initRevenueValues(startTrain, finalTrain); if (startTrain == finalTrain) return; // start prediction runs ! nbEvaluations = 0; nbPredictions = 0; nbEdgesTravelled = 0; log.info("RC: start individual prediction Runs"); *************** *** 297,300 **** --- 302,308 ---- log.debug("RC: runTrain " + trainId); + // intialize value + trainCurrentValue[trainId] = 0; + // initialize lengths trainMajors[trainId] = trainMaxMajors[trainId]; *************** *** 304,307 **** --- 312,319 ---- trainStackPos[trainId] = 0; trainBottomPos[trainId] = 0; + + // check if the revenue is enough + if (useRevenuePrediction && predictRevenues(trainId)) + return; // try all startVertexes *************** *** 309,343 **** int vertexId = startVertexes[i]; log.debug("RC: Using startVertex nr. " + i + " for train " + trainId); ! ! // encounterVertex adds value and returns true if value vertex ! Terminated trainTerminated = Terminated.NotYet; ! boolean valueStation = encounterVertex(trainId, vertexId, true); ! if (valueStation) { ! // check usual train termination ! trainTerminated = trainTerminated(trainId); ! if (trainTerminated == Terminated.WithoutEvaluation || ! // trainTerminated == Terminated.NotYet && ! useRevenuePrediction && predictRevenues(trainId)) { // cannot beat current best value => leave immediately encounterVertex(trainId, vertexId, false); log.debug("RC: finished startVertex " + vertexId + " for train " +trainId); continue; } } ! ! // and all edges of it ! if (trainTerminated == Terminated.NotYet) { ! for (int j = 0; j < vertexNbNeighbors[vertexId]; j++) { ! int neighborId = vertexNeighbors[vertexId][j]; ! log.debug("RC: Testing Neighbor Nr. " + j + " of startVertex is " + neighborId); ! if (travelEdge(vertexId, neighborId, true)) { ! trainStartEdge[trainId] = j; // store edge ! nextVertex(trainId, neighborId, vertexId); ! } } } // no more edges to find - finalizeVertex(trainId, vertexId); encounterVertex(trainId, vertexId, false); // keep them on the visited vertex list to avoid route duplication --- 321,349 ---- int vertexId = startVertexes[i]; log.debug("RC: Using startVertex nr. " + i + " for train " + trainId); ! boolean stationVertex = encounterVertex(trainId, vertexId, true); ! if (stationVertex) { ! // train cannot terminate at start vertex ! if (useRevenuePrediction && predictRevenues(trainId)) { // cannot beat current best value => leave immediately encounterVertex(trainId, vertexId, false); + // but keep them on the visited vertex list to avoid route duplication + trainVisited[trainId][vertexId] = true; log.debug("RC: finished startVertex " + vertexId + " for train " +trainId); continue; } } ! ! // then try all edges of it ! for (int j = 0; j < vertexNbNeighbors[vertexId]; j++) { ! int neighborId = vertexNeighbors[vertexId][j]; ! log.debug("RC: Testing Neighbor Nr. " + j + " of startVertex is " + neighborId); ! int edgeId = vertexEdges[vertexId][j]; ! if (travelEdge(trainId, edgeId, true)) { ! trainStartEdge[trainId] = j; // store start edge ! nextVertex(trainId, neighborId, edgeGreedy[edgeId]); } } // no more edges to find encounterVertex(trainId, vertexId, false); // keep them on the visited vertex list to avoid route duplication *************** *** 346,349 **** --- 352,356 ---- } + // finished all tries for (int i=0; i < startVertexes.length; i++) { // remove all of them from the visited vertex list *************** *** 351,354 **** --- 358,364 ---- } + // allow that the train does not run at all + finalizeVertex(trainId, -1); + log.debug("RC: finishTrain " + trainId); } *************** *** 371,380 **** continue; } ! if (travelEdge(vertexId, neighborId, true)) { ! nextVertex(trainId, neighborId, vertexId); } } - // no more edges to find - // finalizeVertex(trainId); trainStackPos[trainId]--; // pull from stack --- 381,389 ---- continue; } ! int edgeId = vertexEdges[vertexId][j]; ! if (travelEdge(trainId, edgeId, true)) { ! nextVertex(trainId, neighborId, edgeGreedy[edgeId]); } } trainStackPos[trainId]--; // pull from stack *************** *** 386,399 **** * arrives at an unvisited vertex */ ! private void nextVertex(int trainId, int vertexId, int previousId) { // 1. encounterVertex adds value and returns true if value vertex Terminated trainTerminated = Terminated.NotYet; ! boolean valueStation = encounterVertex(trainId, vertexId, true); ! if (valueStation) { // check usual train termination trainTerminated = trainTerminated(trainId); if (trainTerminated == Terminated.WithoutEvaluation || - // trainTerminated == Terminated.NotYet && useRevenuePrediction && predictRevenues(trainId)) { // cannot beat current best value => leave immediately --- 395,407 ---- * arrives at an unvisited vertex */ ! private void nextVertex(int trainId, int vertexId, boolean previousGreedy) { // 1. encounterVertex adds value and returns true if value vertex Terminated trainTerminated = Terminated.NotYet; ! boolean stationVertex = encounterVertex(trainId, vertexId, true); ! if (stationVertex) { // check usual train termination trainTerminated = trainTerminated(trainId); if (trainTerminated == Terminated.WithoutEvaluation || useRevenuePrediction && predictRevenues(trainId)) { // cannot beat current best value => leave immediately *************** *** 413,422 **** continue; } ! if (travelEdge(vertexId, neighborId, edgeGreedy[previousId][vertexId])) { ! nextVertex(trainId, neighborId, vertexId); } } // 2b. restart at startVertex for bottom part ! if (valueStation && trainBottomPos[trainId] == 0){ runBottom(trainId); } --- 421,431 ---- continue; } ! int edgeId = vertexEdges[vertexId][j]; ! if (travelEdge(trainId, edgeId, previousGreedy)) { ! nextVertex(trainId, neighborId, edgeGreedy[edgeId]); } } // 2b. restart at startVertex for bottom part ! if (stationVertex && trainBottomPos[trainId] == 0){ runBottom(trainId); } *************** *** 424,428 **** // 3. no more edges to visit from here => evaluate or start new train ! if (valueStation) finalizeVertex(trainId, vertexId); --- 433,437 ---- // 3. no more edges to visit from here => evaluate or start new train ! if (stationVertex) finalizeVertex(trainId, vertexId); *************** *** 439,474 **** trainVisited[trainId][vertexId] = arrive; ! boolean valueVertex; if (arrive) { ! if (vertexValueByTrain[vertexId][trainId] == 0) { ! valueVertex = false; ! } else { ! valueVertex = true; ! trainCurrentValue[trainId] += vertexValueByTrain[vertexId][trainId]; ! } ! if (vertexMajor[vertexId]) trainMajors[trainId]--; ! if (vertexMinor[vertexId]) { trainMinors[trainId]--; } trainVertexStack[trainId][trainStackPos[trainId]++] = vertexId; // push to stack countVisits++; } else { ! if (vertexValueByTrain[vertexId][trainId] == 0) { ! valueVertex = false; ! } else { ! valueVertex = true; ! trainCurrentValue[trainId] -= vertexValueByTrain[vertexId][trainId]; ! } ! if (vertexMajor[vertexId]) trainMajors[trainId]++; ! if (vertexMinor[vertexId]) trainMinors[trainId]++; trainStackPos[trainId]--; // pull from stack countVisits--; } ! // check blocks ! for (int j=0; j < vertexNbBlocks[vertexId]; j++) { if (vertexVisitSets[vertexId][j] != -1) { trainVisited[trainId][vertexVisitSets[vertexId][j]] = arrive; --- 448,478 ---- trainVisited[trainId][vertexId] = arrive; ! boolean stationVertex = false; if (arrive) { ! trainCurrentValue[trainId] += vertexValueByTrain[vertexId][trainId]; ! if (vertexMajor[vertexId]) { trainMajors[trainId]--; ! stationVertex = true; ! } else if (vertexMinor[vertexId]) { trainMinors[trainId]--; + stationVertex = !trainIgnoreMinors[trainId]; } trainVertexStack[trainId][trainStackPos[trainId]++] = vertexId; // push to stack countVisits++; } else { ! trainCurrentValue[trainId] -= vertexValueByTrain[vertexId][trainId]; ! if (vertexMajor[vertexId]) { trainMajors[trainId]++; ! stationVertex = true; ! } else if (vertexMinor[vertexId]) { trainMinors[trainId]++; + stationVertex = !trainIgnoreMinors[trainId]; + } trainStackPos[trainId]--; // pull from stack countVisits--; } ! // check vertex sets ! for (int j=0; j < vertexNbVisitSets[vertexId]; j++) { if (vertexVisitSets[vertexId][j] != -1) { trainVisited[trainId][vertexVisitSets[vertexId][j]] = arrive; *************** *** 478,497 **** log.debug("RC: Count Visits = " + countVisits); ! return valueVertex; } ! private boolean travelEdge(int startVertex, int endVertex, boolean previousGreedy) { ! if (edgeUsed[startVertex][endVertex]) { ! log.debug("RC: Edge from " + startVertex + " to " + endVertex + " already used" ); return false; ! } else if (previousGreedy || edgeGreedy[startVertex][endVertex]) { ! log.debug("RC: Travel edge from " + startVertex + " to " + endVertex ); ! edgeUsed[startVertex][endVertex] = true; ! edgeUsed[endVertex][startVertex] = true; ! countEdges++; nbEdges++; log.debug("RC: Count Edges = " + countEdges); return true; } else { ! log.debug("RC: Cannot travel from " + startVertex + " to " + endVertex + ", because of greedy rule"); return false; } --- 482,501 ---- log.debug("RC: Count Visits = " + countVisits); ! return stationVertex; } ! private boolean travelEdge(int trainId, int edgeId, boolean previousGreedy) { ! if (edgeUsed[edgeId]) { ! log.debug("RC: Edge id " + edgeId + " already used" ); return false; ! } else if (previousGreedy || edgeGreedy[edgeId]) { ! log.debug("RC: Travel edge id " + edgeId); ! edgeUsed[edgeId] = true; ! trainEdgeStack[trainId][trainStackPos[trainId]] = edgeId; ! countEdges++; nbEdgesTravelled++; log.debug("RC: Count Edges = " + countEdges); return true; } else { ! log.debug("RC: Cannot travel edge id " + edgeId + ", because of greedy rule"); return false; } *************** *** 511,525 **** } ! int startVertex = trainVertexStack[trainId][stackPos]; ! int endVertex = trainVertexStack[trainId][stackPos - 1]; ! if (edgeUsed[startVertex][endVertex]) { ! edgeUsed[startVertex][endVertex] = false; ! edgeUsed[endVertex][startVertex] = false; countEdges--; ! log.debug("RC: Cleared edge from " + startVertex + " to " + endVertex); log.debug("RC: Count Edges = " + countEdges); } else { ! log.debug ("RC: Error return edge not used: " + startVertex + " to " + endVertex); } } --- 515,527 ---- } ! int edgeId = trainEdgeStack[trainId][stackPos]; ! if (edgeUsed[edgeId]) { ! edgeUsed[edgeId] = false; countEdges--; ! log.debug("RC: Cleared edge id " + edgeId); log.debug("RC: Count Edges = " + countEdges); } else { ! log.debug ("RC: Error return edge id used: " + edgeId); } } *************** *** 545,549 **** private void finalizeVertex(int trainId, int vertexId) { ! log.debug("RC: No more edges found at " + vertexId + " for train " + trainId); if (trainId == finalTrain) { --- 547,551 ---- private void finalizeVertex(int trainId, int vertexId) { ! log.debug("RC: Finalize Vertex id " + vertexId + " for train " + trainId); if (trainId == finalTrain) { *************** *** 558,568 **** int totalValue = 0; for (int j = startTrain; j <= finalTrain; j++) { ! if (trainIgnoreMinors[j]) { ! if (trainMaxMajors[j] - trainMajors[j] >= 2) ! totalValue += trainCurrentValue[j]; ! } else { ! if (trainMaxMajors[j] + trainMaxMinors[j] - trainMajors[j] - trainMinors[j] >= 2) ! totalValue += trainCurrentValue[j]; ! } } --- 560,571 ---- int totalValue = 0; for (int j = startTrain; j <= finalTrain; j++) { ! totalValue += trainCurrentValue[j]; ! // if (trainIgnoreMinors[j]) { ! // if (trainMaxMajors[j] - trainMajors[j] >= 2) ! // totalValue += trainCurrentValue[j]; ! // } else { ! // if (trainMaxMajors[j] + trainMaxMinors[j] - trainMajors[j] - trainMinors[j] >= 2) ! // totalValue += trainCurrentValue[j]; ! // } } *************** *** 583,590 **** } } log.info("RC: Found better run with " + totalValue); // inform revenue listener via adapter notifyRevenueAdapter(currentBestValue, false); - } } } --- 586,593 ---- } } + } log.info("RC: Found better run with " + totalValue); // inform revenue listener via adapter notifyRevenueAdapter(currentBestValue, false); } } *************** *** 618,628 **** // and add the past trains: current realized values for (int j = startTrain; j < trainId; j++) { ! if (trainIgnoreMinors[j]) { ! if (trainMaxMajors[j] - trainMajors[j] >= 2) ! totalValue += trainCurrentValue[j]; ! } else { ! if (trainMaxMajors[j] + trainMaxMinors[j] - trainMajors[j] - trainMinors[j] >= 2) ! totalValue += trainCurrentValue[j]; ! } } --- 621,632 ---- // and add the past trains: current realized values for (int j = startTrain; j < trainId; j++) { ! totalValue += trainCurrentValue[j]; ! // if (trainIgnoreMinors[j]) { ! // if (trainMaxMajors[j] - trainMajors[j] >= 2) ! // totalValue += trainCurrentValue[j]; ! // } else { ! // if (trainMaxMajors[j] + trainMaxMinors[j] - trainMajors[j] - trainMinors[j] >= 2) ! // totalValue += trainCurrentValue[j]; ! // } } *************** *** 643,649 **** buffer.append("vertexMajor:" + Arrays.toString(vertexMajor) + "\n"); buffer.append("vertexMinor:" + Arrays.toString(vertexMinor) + "\n"); ! buffer.append("vertexEdges:" + Arrays.deepToString(vertexNeighbors) + "\n"); ! // buffer.append("edgeGreedy:" + Arrays.deepToString(edgeGreedy)); ! // buffer.append("edgeDistance:" + Arrays.deepToString(edgeDistance)); buffer.append("startVertexes:" + Arrays.toString(startVertexes) + "\n"); buffer.append("trainMaxMajors:" + Arrays.toString(trainMaxMajors) + "\n"); --- 647,654 ---- buffer.append("vertexMajor:" + Arrays.toString(vertexMajor) + "\n"); buffer.append("vertexMinor:" + Arrays.toString(vertexMinor) + "\n"); ! buffer.append("vertexNeighbors:" + Arrays.deepToString(vertexNeighbors) + "\n"); ! buffer.append("vertexEdges:" + Arrays.deepToString(vertexEdges) + "\n"); ! buffer.append("edgeGreedy:" + Arrays.toString(edgeGreedy) + "\n"); ! buffer.append("edgeDistance:" + Arrays.toString(edgeDistance) + "\n"); buffer.append("startVertexes:" + Arrays.toString(startVertexes) + "\n"); buffer.append("trainMaxMajors:" + Arrays.toString(trainMaxMajors) + "\n"); Index: RevenueAdapter.java =================================================================== RCS file: /cvsroot/rails/18xx/rails/algorithms/RevenueAdapter.java,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -d -r1.11 -r1.12 *** RevenueAdapter.java 12 May 2010 09:18:10 -0000 1.11 --- RevenueAdapter.java 12 May 2010 18:50:26 -0000 1.12 *************** *** 140,144 **** graph.edgesOf(vertex).size()); log.info("maxNeighbors = " + maxNeighbors); ! this.rc = new RevenueCalculator(this, vertexes.size(), maxNeighbors, maxBlocks, trains.size()); } } --- 140,144 ---- graph.edgesOf(vertex).size()); log.info("maxNeighbors = " + maxNeighbors); ! this.rc = new RevenueCalculator(this, vertexes.size(), edges.size(), maxNeighbors, maxBlocks, trains.size()); } } *************** *** 217,221 **** // sort by value order Arrays.sort(neighborsArray, 0, j); ! rc.setVertexNeighbors(id, neighborsArray); } // set blocks --- 217,227 ---- // sort by value order Arrays.sort(neighborsArray, 0, j); ! // define according edges ! int[] edgesArray = new int[j]; ! for (int e=0; e < j; e++) { ! NetworkVertex n = vertexes.get(neighborsArray[e]); ! edgesArray[e] = edges.indexOf(graph.getEdge(v, n)); ! } ! rc.setVertexNeighbors(id, neighborsArray, edgesArray); } // set blocks *************** *** 241,252 **** // prepare values NetworkEdge e = edges.get(id); - int vA = vertexes.lastIndexOf(e.getSource()); - int vB = vertexes.lastIndexOf(e.getTarget()); boolean greedy = e.isGreedy(); int distance = e.getDistance(); ! rc.setEdge(vA, vB, ! greedy, distance); ! rc.setEdge(vB, vA, ! greedy, distance); } --- 247,253 ---- // prepare values NetworkEdge e = edges.get(id); boolean greedy = e.isGreedy(); int distance = e.getDistance(); ! rc.setEdge(id, greedy, distance); } |