Skip to content

Commit 0b7bf8f

Browse files
authored
Refactored JPS implementations, release 0.5.0
Release/0.5.0
2 parents 6c195a0 + 9d9c638 commit 0b7bf8f

47 files changed

Lines changed: 4267 additions & 5213 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.clang-format

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ PointerAlignment: Left
77
UseTab: ForIndentation
88
IndentWidth: 4
99
TabWidth: 4
10+
# ColumnLimit: 120
1011
Cpp11BracedListStyle: true
1112
AlwaysBreakTemplateDeclarations: Yes
1213
AlwaysBreakAfterReturnType: All

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
build/

CMakeLists.txt

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,17 @@
11
cmake_minimum_required(VERSION 3.13)
22

33
project(WarthogJPS
4-
VERSION 0.2.0
4+
VERSION 0.5.0
55
LANGUAGES CXX C)
66

7+
set_property(GLOBAL PROPERTY WARTHOG_warthog-jps ON)
8+
79
set(CMAKE_CXX_STANDARD 20)
810
set(CMAKE_CXX_STANDARD_REQUIRED TRUE)
911

10-
include(cmake/submodule.cmake)
12+
include(cmake/warthog.cmake)
13+
warthog_module_declare(warthog-core v0.5.0)
14+
warthog_module(warthog-core)
1115

1216
add_library(warthog_libjps)
1317
add_library(warthog::libjps ALIAS warthog_libjps)
@@ -26,4 +30,3 @@ target_link_libraries(warthog_jps PUBLIC warthog::libjps)
2630
add_subdirectory(src)
2731
add_subdirectory(apps)
2832

29-
warthog_submodule(warthog-core)

LICENSE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
MIT License
22

3-
Copyright (c) 2024 Shortest Path Lab @ Monash University
3+
Copyright (c) 2024-2025 Shortest Path Lab @ Monash University
44

55
Permission is hereby granted, free of charge, to any person obtaining a copy
66
of this software and associated documentation files (the "Software"), to deal

README.md

Lines changed: 70 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,73 @@
22

33
Warthog is an optimised C++ library for pathfinding search.
44
Warthog-JPS is an extension to Warthog with JPS support.
5-
See [warthog-core](https://github.com/ShortestPathLab/warthog-core) for extended README.
5+
See [warthog-core](https://github.com/ShortestPathLab/warthog-core) for more details on Warthog setup.
6+
7+
If you find this work useful, please cite our paper as follows:
8+
9+
@article{Harabor_Grastien_2014,
10+
title={Improving Jump Point Search},
11+
volume={24},
12+
url={https://ojs.aaai.org/index.php/ICAPS/article/view/13633},
13+
DOI={10.1609/icaps.v24i1.13633},
14+
number={1},
15+
journal={Proceedings of the International Conference on Automated Planning and Scheduling},
16+
author={Harabor, Daniel and Grastien, Alban},
17+
year={2014},
18+
pages={128-135}
19+
}
20+
21+
# Using JPS
22+
23+
## Compile
24+
25+
Program `warthog-jps` uses cmake for the compile process.
26+
Simply run the following code below:
27+
28+
```
29+
cmake -DCMAKE_BUILD_TYPE=Release -B build
30+
cmake --build build
31+
./build/warthog-jps --alg jps --scen example/arena2.map.scen
32+
```
33+
34+
The example map is from the MovingAI benchmarks under Dragon Age Origins.
35+
Use the `build.sh` or `run.sh` for quick compile/usage of this scenario.
36+
37+
For more evaluation data, please refer to existing benchmarks from the community, which offer a range of different challenges across a variety of maps/domains; links found in the resource section.
38+
39+
JPS requires `warthog-core` repo to compile, and by default will fetch the repo.
40+
41+
## JPS Variants
42+
43+
JPS comes with several variants.
44+
All variants use block-based symmetry breaking for finding jump-point locations,
45+
making them at least JPS (B).
46+
The list is as follows:
47+
48+
- `jps` JPS (B) like original with block-based symmetry
49+
- `jpsP` or `jps2` JPS (B+P) with intercardinal pruning
50+
- `jps+` JPS+ (B) is original with offline jump points
51+
- `jpsP+` or `jps2+` JPS+ (B+P) offline with pruning
52+
53+
These jump points are found in namespace `jps::jump`, while `jps::search` uses provided `jps::jump` locators
54+
to produce successors used in warthog-core.
55+
56+
The algorithms provided to `--alg` parameter, along with their `jps::search` and `jps::jump` classes presented
57+
in the table below:
58+
59+
| `--alg` | `jps::search` | `jps::jump` |
60+
|--------------------|--------------------------------|------------------------|
61+
| `jps` | `jps_expansion_policy<>` | `jump_point_online` |
62+
| `jpsP` or `jps2` | `jps_prune_expansion_policy<>` | `jump_point_online` |
63+
| `jps+` | `jps_expansion_policy` | `jump_point_offline<>` |
64+
| `jpsP+` or `jps2+` | `jps_prune_expansion_policy<>` | `jump_point_offline<>` |
65+
66+
## Use in project
67+
68+
If elements of warthog is used in a project, follow guides from `warthog-core` to set up the project structure.
69+
70+
# Resources
71+
72+
- [Moving AI Lab](https://movingai.com/): pathfinding benchmark and tools
73+
- [Posthoc](https://posthoc-app.pathfinding.ai/): visualiser and debugger for pathfinding
74+
- [Pathfinding Benchmarks](https://benchmarks.pathfinding.ai/): git repo for benchmarks

apps/jps.cpp

Lines changed: 20 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,6 @@
88
//
99

1010
#include <jps/search/jps.h>
11-
#include <jps/search/jps2_expansion_policy.h>
12-
#include <jps/search/jps2plus_expansion_policy.h>
13-
#include <jps/search/jps4c_expansion_policy.h>
14-
#include <jps/search/jps_expansion_policy.h>
15-
#include <jps/search/jpsplus_expansion_policy.h>
1611
#include <warthog/constants.h>
1712
#include <warthog/domain/gridmap.h>
1813
#include <warthog/heuristic/octile_heuristic.h>
@@ -21,7 +16,10 @@
2116
#include <warthog/util/scenario_manager.h>
2217
#include <warthog/util/timer.h>
2318

24-
#include <jps/search/jps_expansion_policy2.h>
19+
#include <jps/jump/jump_point_offline.h>
20+
#include <jps/jump/jump_point_online.h>
21+
#include <jps/search/jps_expansion_policy.h>
22+
#include <jps/search/jps_prune_expansion_policy.h>
2523

2624
#include "cfg.h"
2725
#include <getopt.h>
@@ -70,8 +68,7 @@ help(std::ostream& out)
7068
<< "Invoking the program this way solves all instances in [scen "
7169
"file] with algorithm [alg]\n"
7270
<< "Currently recognised values for [alg]:\n"
73-
<< "\tjps, jps+, jps2, jps2+\n"
74-
<< "\tjpsV2, jpsV2-cardinal, jpsV2-prune\n";
71+
<< "\tjps, jpsP or jps2, jps+, jpsP+ or jps2+\n";
7572
// << ""
7673
// << "The following are valid parameters for GENERATING instances:\n"
7774
// << "\t --gen [map file (required)]\n"
@@ -90,20 +87,12 @@ check_optimality(
9087

9188
if(fabs(delta - epsilon) > epsilon)
9289
{
93-
std::stringstream strpathlen;
94-
strpathlen << std::fixed << std::setprecision(exp->precision());
95-
strpathlen << sol.sum_of_edge_costs_;
96-
97-
std::stringstream stroptlen;
98-
stroptlen << std::fixed << std::setprecision(exp->precision());
99-
stroptlen << exp->distance();
100-
101-
std::cerr << std::setprecision(exp->precision());
90+
std::cerr << std::setprecision(15);
10291
std::cerr << "optimality check failed!" << std::endl;
10392
std::cerr << std::endl;
104-
std::cerr << "optimal path length: " << stroptlen.str()
93+
std::cerr << "optimal path length: " << exp->distance()
10594
<< " computed length: ";
106-
std::cerr << strpathlen.str() << std::endl;
95+
std::cerr << sol.sum_of_edge_costs_ << std::endl;
10796
std::cerr << "precision: " << precision << " epsilon: " << epsilon
10897
<< std::endl;
10998
std::cerr << "delta: " << delta << std::endl;
@@ -253,39 +242,26 @@ main(int argc, char** argv)
253242
using namespace jps::search;
254243
if(alg == "jps")
255244
{
256-
return run_jps<jps_expansion_policy>(scenmgr, mapfile, alg);
257-
}
258-
else if(alg == "jps+")
259-
{
260-
return run_jps<jpsplus_expansion_policy>(scenmgr, mapfile, alg);
261-
}
262-
else if(alg == "jps2")
263-
{
264-
return run_jps<jps2_expansion_policy>(scenmgr, mapfile, alg);
265-
}
266-
else if(alg == "jps2+")
267-
{
268-
return run_jps<jps2plus_expansion_policy>(scenmgr, mapfile, alg);
245+
using jump_point = jps::jump::jump_point_online;
246+
return run_jps<jps_expansion_policy<jump_point>>(
247+
scenmgr, mapfile, alg);
269248
}
270-
else if(alg == "jpsV2")
249+
else if(alg == "jpsP" || alg == "jps2")
271250
{
272-
using jump_point
273-
= jps::jump::jump_point_online<jps::JpsFeature::DEFAULT>;
274-
return run_jps<jps_expansion_policy2<jump_point>>(
251+
using jump_point = jps::jump::jump_point_online;
252+
return run_jps<jps_prune_expansion_policy<jump_point>>(
275253
scenmgr, mapfile, alg);
276254
}
277-
else if(alg == "jpsV2-cardinal")
255+
else if(alg == "jps+")
278256
{
279-
using jump_point = jps::jump::jump_point_online<
280-
jps::JpsFeature::STORE_CARDINAL_JUMP>;
281-
return run_jps<jps_expansion_policy2<jump_point>>(
257+
using jump_point = jps::jump::jump_point_offline<>;
258+
return run_jps<jps_expansion_policy<jump_point>>(
282259
scenmgr, mapfile, alg);
283260
}
284-
else if(alg == "jpsV2-prune")
261+
else if(alg == "jpsP+" || alg == "jps2+")
285262
{
286-
using jump_point = jps::jump::jump_point_online<
287-
jps::JpsFeature::PRUNE_INTERCARDINAL>;
288-
return run_jps<jps_expansion_policy2<jump_point>>(
263+
using jump_point = jps::jump::jump_point_offline<>;
264+
return run_jps<jps_prune_expansion_policy<jump_point>>(
289265
scenmgr, mapfile, alg);
290266
}
291267
else

cmake/headers.cmake

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,16 @@ cmake_minimum_required(VERSION 3.13)
33
# find include/jps -type f -name '*.h' | sort
44
target_sources(warthog_libjps PUBLIC
55
include/jps/forward.h
6-
include/jps/jump/four_connected_jps_locator.h
7-
include/jps/jump/offline_jump_point_locator.h
8-
include/jps/jump/offline_jump_point_locator2.h
9-
include/jps/jump/online_jump_point_locator.h
10-
include/jps/jump/online_jump_point_locator2.h
116

12-
include/jps/search/jps2_expansion_policy.h
13-
include/jps/search/jps.h
14-
include/jps/search/jps2plus_expansion_policy.h
15-
include/jps/search/jps4c_expansion_policy.h
7+
include/jps/domain/rotate_gridmap.h
8+
9+
include/jps/jump/block_online.h
10+
include/jps/jump/jump.h
11+
include/jps/jump/jump_point_offline.h
12+
include/jps/jump/jump_point_online.h
13+
14+
include/jps/search/jps_expansion_policy_base.h
1615
include/jps/search/jps_expansion_policy.h
17-
include/jps/search/jpsplus_expansion_policy.h
16+
include/jps/search/jps.h
17+
include/jps/search/jps_prune_expansion_policy.h
1818
)

cmake/submodule.cmake

Lines changed: 0 additions & 35 deletions
This file was deleted.

cmake/warthog.cmake

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
cmake_minimum_required(VERSION 3.13)
2+
3+
# include this file to check submodule include
4+
5+
# set here as only
6+
set(warthog_https_warthog-core "https://github.com/ShortestPathLab/warthog-core.git" CACHE INTERNAL "")
7+
set(warthog_https_warthog-jps "https://github.com/ShortestPathLab/warthog-jps.git" CACHE INTERNAL "")
8+
9+
if(COMMAND warthog_module)
10+
return() # do not redefine
11+
endif()
12+
13+
include(FetchContent)
14+
15+
set(WARTHOG_MODULE_ROOT_ONLY ON CACHE BOOL "add submodule if present only allowed for root project")
16+
17+
function(warthog_top_level)
18+
set(_is_top OFF)
19+
if(${CMAKE_VERSION} VERSION_GREATER_EQUAL 3.21)
20+
if(${PROJECT_IS_TOP_LEVEL})
21+
set(_is_top ON)
22+
endif()
23+
else()
24+
if(${CMAKE_SOURCE_DIR} STREQUAL ${PROJECT_SOURCE_DIR})
25+
set(_is_top ON)
26+
endif()
27+
endif()
28+
set(_warthog_is_top ${_is_top} PARENT_SCOPE)
29+
endfunction()
30+
31+
# warthog_module module [override_top]
32+
# adds a module to warthog
33+
# has checks to insure module is only added once
34+
# if called from the top level project (or optional variable override_top is true)
35+
# then if extern/${module}/CMakeLists.txt exists, adds that version instead
36+
# intended for use with git module/subtree.
37+
# otherwise, fetchcontent ${module} is made available
38+
# user must add FetchContent_Declare
39+
function(warthog_module module)
40+
get_property(_module_added GLOBAL PROPERTY WARTHOG_${module} SET)
41+
if(${_module_added}) # module already added
42+
return()
43+
endif()
44+
if((${ARGC} GREATER 1) AND (${ARGV1}))
45+
set(is_top_level ON)
46+
else()
47+
warthog_top_level()
48+
set(is_top_level ${_warthog_is_top})
49+
endif()
50+
if(${is_top_level})
51+
if(EXISTS "${PROJECT_SOURCE_DIR}/extern/${module}/CMakeLists.txt")
52+
# module or subtree, include and exit
53+
add_subdirectory("${PROJECT_SOURCE_DIR}/extern/${module}")
54+
set_property(GLOBAL PROPERTY WARTHOG_${module} ON)
55+
return()
56+
endif()
57+
endif()
58+
# failed to add module, fetch if able
59+
warthog_module_declare(${module})
60+
FetchContent_MakeAvailable(${module})
61+
set_property(GLOBAL PROPERTY WARTHOG_${module} ON)
62+
endfunction()
63+
64+
function(warthog_module_declare module)
65+
if(NOT DEFINED warthog_https_${module})
66+
return()
67+
endif()
68+
if((${ARGC} GREATER 1))
69+
set(git_tag ${ARGV1})
70+
else()
71+
set(git_tag "main")
72+
endif()
73+
FetchContent_Declare(${module}
74+
GIT_REPOSITORY ${warthog_https_${module}}
75+
GIT_TAG ${git_tag})
76+
endfunction()

0 commit comments

Comments
 (0)