Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Comparison test for CH and RPHAST, but leave commented out #1147

Merged
merged 1 commit into from
Mar 30, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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