Skip to content

Commit

Permalink
Merge pull request #1147 from GIScience/prop_tests_CH_RPHAST
Browse files Browse the repository at this point in the history
Add Comparison test for CH and RPHAST, but leave commented out
  • Loading branch information
takb authored Mar 30, 2022
2 parents c3e8fb5 + 6e1a6e4 commit 24d777e
Show file tree
Hide file tree
Showing 7 changed files with 488 additions and 13 deletions.
42 changes: 38 additions & 4 deletions openrouteservice/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -243,10 +243,14 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.0</version>
<version>2.22.2</version>
<configuration>
<!--suppress UnresolvedMavenProperty -->
<argLine>-Duser.language=en -Duser.region=US -Dillegal-access=permit ${surefireArgLine}</argLine>
<includes>
<include>**/*Tests.java</include>
<include>**/*Properties.java</include>
</includes>
</configuration>
</plugin>

Expand Down Expand Up @@ -296,7 +300,23 @@
<enabled>true</enabled>
</releases>
</repository>
<repository>
<!--This will resolve jqwik snapshots-->
<id>Sonatype Snapshots</id>
<url>https://s01.oss.sonatype.org/content/repositories/snapshots</url>
</repository>
</repositories>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.junit</groupId>
<artifactId>junit-bom</artifactId>
<version>5.8.2</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<!-- Java 11 upgrade -->
Expand Down Expand Up @@ -457,9 +477,23 @@
</dependency>

<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.1</version>
<groupId>net.jqwik</groupId>
<artifactId>jqwik</artifactId>
<version>1.6.5</version>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>3.22.0</version>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
<scope>test</scope>
</dependency>

<dependency>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,8 @@ public MatrixResult compute(MatrixLocations srcData, MatrixLocations dstData, in
int[] srcIds = getValidNodeIds(srcData.getNodeIds());
int[] destIds = getValidNodeIds(dstData.getNodeIds());

mtxResult.setGraphDate(graphHopper.getGraphHopperStorage().getProperties().get("datareader.import.date"));
if(graphHopper != null)
mtxResult.setGraphDate(graphHopper.getGraphHopperStorage().getProperties().get("datareader.import.date"));

algorithm.prepare(srcIds, destIds);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ private boolean upwardSearch() {
return false;

currFrom = prioQueue.poll();
upwardEdgeFilter.updateHighestNode(currFrom.getAdjNode());
fillEdgesUpward(currFrom, prioQueue, bestWeightMap, outEdgeExplorer);
visitedCountFrom++;

Expand Down Expand Up @@ -217,7 +218,6 @@ private void fillEdgesUpward(MultiTreeSPEntry currEdge, PriorityQueue<MultiTreeS
if (!upwardEdgeFilter.accept(iter))
continue;

upwardEdgeFilter.updateHighestNode(iter);
edgeWeight = iter.getWeight(false);
// edgeWeight = weighting.calcEdgeWeight(iter, false, 0);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,17 +49,15 @@ public void setBaseNode(int nodeId) {
baseNodeLevel = graph.getLevel(nodeId);
}

public void updateHighestNode(RoutingCHEdgeIteratorState edgeIterState) {
int adjNode = edgeIterState.getAdjNode();

if (adjNode < maxNodes) {
if (highestNode == -1 || highestNodeLevel < graph.getLevel(adjNode)) {
highestNode = adjNode;
public void updateHighestNode(int node) {
if (node < maxNodes) {
if (highestNode == -1 || highestNodeLevel < graph.getLevel(node)) {
highestNode = node;
highestNodeLevel = graph.getLevel(highestNode);
}
} else {
if (highestNode == -1)
highestNode = adjNode;
highestNode = node;
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
package org.heigit.ors.pbt;

import com.graphhopper.routing.Path;
import com.graphhopper.routing.RoutingAlgorithm;
import com.graphhopper.routing.ch.CHRoutingAlgorithmFactory;
import com.graphhopper.routing.ch.PrepareContractionHierarchies;
import com.graphhopper.routing.util.TraversalMode;
import com.graphhopper.routing.weighting.ShortestWeighting;
import com.graphhopper.routing.weighting.Weighting;
import com.graphhopper.storage.*;
import com.graphhopper.util.PMap;
import net.jqwik.api.domains.Domain;
import net.jqwik.api.lifecycle.AfterProperty;
import net.jqwik.api.lifecycle.BeforeProperty;
import org.heigit.ors.common.DistanceUnit;
import org.heigit.ors.matrix.MatrixLocations;
import org.heigit.ors.matrix.MatrixMetricsType;
import org.heigit.ors.matrix.MultiTreeMetricsExtractor;
import org.heigit.ors.routing.algorithms.RPHASTAlgorithm;
import org.heigit.ors.routing.graphhopper.extensions.storages.MultiTreeSPEntry;

import java.util.HashMap;
import java.util.Map;

import static org.heigit.ors.pbt.GraphHopperDomain.carEncoder;
import static org.junit.Assert.assertEquals;

@Domain(GraphHopperDomain.class)
class AlgorithmComparisonTest {
private static Directory dir;
private Weighting weighting = new ShortestWeighting(carEncoder);
private CHConfig chConfig = new CHConfig("c", weighting, false, CHConfig.TYPE_CORE);
private RoutingCHGraph routingCHGraph;

@BeforeProperty
public void setUp() {
// This should be done globally only once
System.setProperty("ors_config", "target/test-classes/ors-config-test.json");
dir = new GHDirectory("", DAType.RAM_INT);
}

private PrepareContractionHierarchies createPrepareContractionHierarchies(GraphHopperStorage g) {
return createPrepareContractionHierarchies(g, chConfig);
}

private PrepareContractionHierarchies createPrepareContractionHierarchies(GraphHopperStorage g, CHConfig p) {
g.freeze();
return PrepareContractionHierarchies.fromGraphHopperStorage(g, p);
}


@AfterProperty
public void cleanUp() {
dir.clear();
}

// TODO Uncomment this and resolve differences to enable this test

// @Property(tries = 2000)// , seed="-2270368960184993644") // reproduces a failure
// // @Report(Reporting.GENERATED)
// void compare_distance_computation_between_CoreMatrix_and_CoreALT(
// @ForAll @MaxNodes(2000) Tuple3<GraphHopperStorage, MatrixLocations, MatrixLocations> matrixScenario
// ) throws Exception {
//
// GraphHopperStorage sampleGraph = matrixScenario.get1();
// FlagEncoder encoder = sampleGraph.getEncodingManager().getEncoder("car");
// weighting = new ShortestWeighting(encoder);
// chConfig = sampleGraph.getCHConfig();
// PrepareContractionHierarchies prepare = createPrepareContractionHierarchies(sampleGraph);
// prepare.doWork();
// routingCHGraph = sampleGraph.getRoutingCHGraph("c");
//
// MatrixLocations sources = matrixScenario.get2();
// MatrixLocations destinations = matrixScenario.get3();
// try {
// float[] matrixDistances = computeDistancesFromRPHAST(sampleGraph, sources, destinations);
// float[] coreDistances = computeDistancesFromCH(sources, destinations);
//
//// System.out.println(Arrays.toString(matrixDistances));
//// System.out.println(Arrays.toString(coreDistances));
//
// assertDistancesAreEqual(matrixDistances, coreDistances, sources, destinations);
// } finally {
// sampleGraph.close();
// }
// }

private void assertDistancesAreEqual(
float[] matrixDistances,
float[] coreDistances,
MatrixLocations sources,
MatrixLocations destinations
) {
Map<Integer, String> edgesByIndex = buildEdgesIndex(sources, destinations);
assertEquals("number of distances", coreDistances.length, matrixDistances.length);
for (int i = 0; i < coreDistances.length; i++) {
String edge = edgesByIndex.get(i);
String errorMessage = String.format("Length mismatch for edge %s: ", edge);
assertEquals(errorMessage, coreDistances[i], matrixDistances[i], 0.1);
}
}

private Map<Integer, String> buildEdgesIndex(MatrixLocations sources, MatrixLocations destinations) {
Map<Integer, String> edgesByIndex = new HashMap<>();
int index = 0;
for (int sourceId : sources.getNodeIds()) {
for (int destinationId : destinations.getNodeIds()) {
edgesByIndex.put(index, String.format("%s->%s", sourceId, destinationId));
index += 1;
}
}
return edgesByIndex;
}

private float[] computeDistancesFromCH(MatrixLocations sources, MatrixLocations destinations) {
float[] coreDistances = new float[sources.size() * destinations.size()];
int index = 0;
for (int sourceId : sources.getNodeIds()) {
for (int destinationId : destinations.getNodeIds()) {
RoutingAlgorithm algo = new CHRoutingAlgorithmFactory(routingCHGraph).createAlgo(new PMap());
Path path = algo.calcPath(sourceId, destinationId);
coreDistances[index] = (float) path.getWeight();
// Matrix algorithm returns -1.0 instead of Infinity
if (Float.isInfinite(coreDistances[index])) {
coreDistances[index] = -1.0f;
}
index += 1;
}
}
return coreDistances;
}

private float[] computeDistancesFromRPHAST(GraphHopperStorage sampleGraph, MatrixLocations sources, MatrixLocations destinations) throws Exception {
RPHASTAlgorithm matrixAlgorithm = createAndPrepareRPHAST(sampleGraph.getRoutingCHGraph());
matrixAlgorithm.prepare(sources.getNodeIds(), destinations.getNodeIds());
MultiTreeSPEntry[] destTrees = matrixAlgorithm.calcPaths(sources.getNodeIds(), destinations.getNodeIds());
return extractValues(sampleGraph, sources, destinations, destTrees);
}

private float[] extractValues(GraphHopperStorage sampleGraph, MatrixLocations sources, MatrixLocations destinations, MultiTreeSPEntry[] destTrees) throws Exception {
MultiTreeMetricsExtractor pathMetricsExtractor = new MultiTreeMetricsExtractor(MatrixMetricsType.DISTANCE, sampleGraph.getRoutingCHGraph(), carEncoder, weighting, DistanceUnit.METERS);
int tableSize = sources.size() * destinations.size();

float[] distances = new float[tableSize];
float[] times = new float[tableSize];
float[] weights = new float[tableSize];
MultiTreeSPEntry[] originalDestTrees = new MultiTreeSPEntry[destinations.size()];

int j = 0;
for (int i = 0; i < destinations.size(); i++) {
if (destinations.getNodeIds()[i] != -1) {
originalDestTrees[i] = destTrees[j];
++j;
} else {
originalDestTrees[i] = null;
}
}

pathMetricsExtractor.calcValues(originalDestTrees, sources, destinations, times, distances, weights);
return distances;

}

private RPHASTAlgorithm createAndPrepareRPHAST(RoutingCHGraph routingCHGraph) {
return new RPHASTAlgorithm(routingCHGraph, weighting, TraversalMode.NODE_BASED);
}
}
Loading

0 comments on commit 24d777e

Please sign in to comment.