Compare commits
3 commits
a2cb9520cc
...
a9fd341b45
| Author | SHA1 | Date | |
|---|---|---|---|
| a9fd341b45 | |||
| cab977451c | |||
| 0b3d2db135 |
5 changed files with 136 additions and 8 deletions
23
README.md
23
README.md
|
|
@ -20,7 +20,7 @@ Reading the data from an OSM PDF file and converting it to a graph is done in
|
||||||
`src/bin/generate_grid.rs`.
|
`src/bin/generate_grid.rs`.
|
||||||
|
|
||||||
The implementation of the spherical point in polygon test is done in `src/polygon.rs`
|
The implementation of the spherical point in polygon test is done in `src/polygon.rs`
|
||||||
with the function `contains()`.
|
with the function `Polygon::contains`.
|
||||||
|
|
||||||
There is one polygon in the graph, for which no valid outside polygon can be found.
|
There is one polygon in the graph, for which no valid outside polygon can be found.
|
||||||
I did not have the time to investigate this further.
|
I did not have the time to investigate this further.
|
||||||
|
|
@ -29,8 +29,7 @@ I did not have the time to investigate this further.
|
||||||
|
|
||||||
The code uses the osmpbfreader crate.
|
The code uses the osmpbfreader crate.
|
||||||
Sadly this module uses ~10GB of memory to extract the data from the PBF file
|
Sadly this module uses ~10GB of memory to extract the data from the PBF file
|
||||||
with all the coastlines. So far I did not have time to look into what happens
|
with all the coastlines.
|
||||||
there.
|
|
||||||
|
|
||||||
### Point in Polygon
|
### Point in Polygon
|
||||||
|
|
||||||
|
|
@ -50,9 +49,9 @@ Import and Export from/to a file can be done with the `from_fmi_file` and `write
|
||||||
|
|
||||||
### Dijkstra Benchmarks
|
### Dijkstra Benchmarks
|
||||||
|
|
||||||
The dijkstras algorithm is implenented in `gridgraph.rs`.
|
Dijkstras algorithm is implenented in `gridgraph.rs` with `GridGraph::shortest_path`.
|
||||||
It uses a Heap to store the nodes.
|
It uses a Heap to store the nodes.
|
||||||
On details on how to run benchmarks see the benchmarks session at the end.
|
For details on how to run benchmarks see the benchmarks section at the end.
|
||||||
|
|
||||||
## Task 6
|
## Task 6
|
||||||
|
|
||||||
|
|
@ -76,6 +75,9 @@ I implemented ALT, as described in [1].
|
||||||
Additionally A\* is available with a simple, unoptimized haversine distance
|
Additionally A\* is available with a simple, unoptimized haversine distance
|
||||||
as the heuristic.
|
as the heuristic.
|
||||||
|
|
||||||
|
A\* is implemented in `src/astar.rs` and the heuristics for ALT are implemented
|
||||||
|
in `src/alt.rs`.
|
||||||
|
|
||||||
### Landmarks for ALT
|
### Landmarks for ALT
|
||||||
|
|
||||||
currently 3 different landmark generation methods are available
|
currently 3 different landmark generation methods are available
|
||||||
|
|
@ -94,7 +96,7 @@ generates landmarks for 4, 8, 16, 32 and 64 landmarks, both greedy and random.
|
||||||
# Running the benchmarks
|
# Running the benchmarks
|
||||||
|
|
||||||
First a set of queries is needed.
|
First a set of queries is needed.
|
||||||
This can be done with the `generate_benchmark_targets --graph <graph> > targets.json`.
|
These can be generated with `generate_benchmark_targets --graph <graph> > targets.json`.
|
||||||
This generates 1000 random, distinct source and destination pairs.
|
This generates 1000 random, distinct source and destination pairs.
|
||||||
The `--amount` parameter allows to adjust the number of pairs generated.
|
The `--amount` parameter allows to adjust the number of pairs generated.
|
||||||
|
|
||||||
|
|
@ -110,4 +112,11 @@ are used to answer the query.
|
||||||
The benchmark prints out how many nodes were popped from the heap for
|
The benchmark prints out how many nodes were popped from the heap for
|
||||||
each run and the average time per route.
|
each run and the average time per route.
|
||||||
|
|
||||||
[1] Computing the Shortest Path: A* meets Graph Theory, A. Goldberg and C. Harrelson, Microsoft Research, Technical Report MSR-TR-2004-24, 2004
|
`utils/run_benchmarks.py` is a wrapper script that runs the benchmarks for a
|
||||||
|
big set of parameters.
|
||||||
|
|
||||||
|
`utils/plot_results.py` generates several plots of the results.
|
||||||
|
|
||||||
|
# References
|
||||||
|
|
||||||
|
[1](Computing the Shortest Path: A\* meets Graph Theory, A. Goldberg and C. Harrelson, Microsoft Research, Technical Report MSR-TR-2004-24, 2004)
|
||||||
|
|
|
||||||
|
|
@ -137,7 +137,8 @@ impl LandmarkBestSet<'_> {
|
||||||
results.reverse();
|
results.reverse();
|
||||||
|
|
||||||
self.best_landmarks.clear();
|
self.best_landmarks.clear();
|
||||||
for result in results[..self.best_size].iter() {
|
|
||||||
|
for result in results[..(self.best_size.min(results.len()))].iter() {
|
||||||
self.best_landmarks.push(result.0);
|
self.best_landmarks.push(result.0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
90
utils/plot_results.py
Executable file
90
utils/plot_results.py
Executable file
|
|
@ -0,0 +1,90 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
from sys import argv, exit
|
||||||
|
import os
|
||||||
|
from csv import writer
|
||||||
|
from typing import Tuple, List
|
||||||
|
import re
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
|
||||||
|
if len(argv) != 2:
|
||||||
|
print(f"Usage: { argv[0] } <results_dir>")
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
path = argv[1]
|
||||||
|
|
||||||
|
files = [f for f in os.listdir(path) if os.path.isfile(f"{ path }/{f}")]
|
||||||
|
|
||||||
|
files = [f for f in files if re.match(r"greedy_64_.+", f) is not None ]
|
||||||
|
|
||||||
|
|
||||||
|
def parse_file(file: str) -> Tuple[float, List[int]]:
|
||||||
|
|
||||||
|
pops = list()
|
||||||
|
time = None
|
||||||
|
with open(file) as f:
|
||||||
|
for line in f.readlines():
|
||||||
|
m = re.match(r"popped\s(?P<pops>\d+)\s.*", line)
|
||||||
|
if m is not None:
|
||||||
|
pops.append(int(m.groupdict()["pops"]))
|
||||||
|
continue
|
||||||
|
|
||||||
|
m = re.match(r"It took\s(?P<time>\S+).*", line)
|
||||||
|
if m is not None:
|
||||||
|
time = float(m.groupdict()["time"])
|
||||||
|
|
||||||
|
if len(pops) == 0:
|
||||||
|
raise Exception(f"Parsing { file } failed, no heap pops found!")
|
||||||
|
|
||||||
|
return time, pops
|
||||||
|
|
||||||
|
results = dict()
|
||||||
|
|
||||||
|
with open("times.csv", "w+") as times_file:
|
||||||
|
times = writer(times_file)
|
||||||
|
|
||||||
|
with open("pops.csv", "w+") as pops_file:
|
||||||
|
pops = writer(pops_file)
|
||||||
|
|
||||||
|
for file in files:
|
||||||
|
name = file.split(".")[0]
|
||||||
|
full_path = f"{ path }/{ file }"
|
||||||
|
time, pop = parse_file(full_path)
|
||||||
|
|
||||||
|
total_pops = sum(pop)
|
||||||
|
|
||||||
|
results[name] = (total_pops, time)
|
||||||
|
|
||||||
|
times.writerow([name, time])
|
||||||
|
|
||||||
|
pops.writerow([name, *pop])
|
||||||
|
rel_pops = list()
|
||||||
|
rel_time = list()
|
||||||
|
labels = list()
|
||||||
|
|
||||||
|
# base_pops = results["dijkstra"][0]
|
||||||
|
# base_time = results["dijkstra"][1]
|
||||||
|
base_pops = results["greedy_64_1"][0]
|
||||||
|
base_time = results["greedy_64_1"][1]
|
||||||
|
|
||||||
|
for name, values in results.items():
|
||||||
|
pops, time = values
|
||||||
|
labels.append(name)
|
||||||
|
rel_pops.append(pops/base_pops)
|
||||||
|
rel_time.append(time/base_time)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
x = np.arange(len(labels)) # the label locations
|
||||||
|
width = 0.35 # the width of the bars
|
||||||
|
|
||||||
|
fig, ax = plt.subplots()
|
||||||
|
rects1 = ax.bar(x - width/2, rel_time , width, label='time')
|
||||||
|
rects2 = ax.bar(x + width/2, rel_pops, width, label='pops')
|
||||||
|
|
||||||
|
ax.legend()
|
||||||
|
ax.set_xticks(x, labels)
|
||||||
|
|
||||||
|
plt.show()
|
||||||
28
utils/run_benchmarks.py
Executable file
28
utils/run_benchmarks.py
Executable file
|
|
@ -0,0 +1,28 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
from os import system
|
||||||
|
from sys import argv, exit
|
||||||
|
|
||||||
|
if len(argv) != 4:
|
||||||
|
print(f"usage: {argv[0]} <graph> <landmark_prefix> <targets>")
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
graph = argv[1]
|
||||||
|
landmarks = argv[2]
|
||||||
|
targets = argv[3]
|
||||||
|
|
||||||
|
print("running A*")
|
||||||
|
system(f"cargo run --release --bin=performance -- --graph={graph} --astar --targets {targets} > results/astar.txt")
|
||||||
|
print("running Dijkstra")
|
||||||
|
system(f"cargo run --release --bin=performance -- --graph={graph} --dijkstra --targets {targets} > results/dijkstra.txt")
|
||||||
|
|
||||||
|
print("running ALT with 44 handpicked landmarks")
|
||||||
|
system(f"cargo run --release --bin=performance -- --graph={graph} --landmarks={landmarks}_handpicked_44.bin --targets {targets} > results/handpicked_44.txt")
|
||||||
|
for i in range(6, 7):
|
||||||
|
num = 2**i
|
||||||
|
|
||||||
|
for best in [12, 24, ]:
|
||||||
|
|
||||||
|
for lm_type in ["greedy", "random"]:
|
||||||
|
print(f"running ALT with {num} {lm_type} landmarks")
|
||||||
|
system(f"cargo run --release --bin=performance -- --graph={graph} --landmarks={landmarks}_{lm_type}_{ num }.bin --targets {targets} --alt-best-size { best} > results/{lm_type}_{num}_{ best }.txt")
|
||||||
Loading…
Add table
Add a link
Reference in a new issue