implement a random graph generator : layer by layer method#6
Open
huggingstar wants to merge 2765 commits into
Open
implement a random graph generator : layer by layer method#6huggingstar wants to merge 2765 commits into
huggingstar wants to merge 2765 commits into
Conversation
huggingstar
commented
Feb 11, 2018
* updated dependency versions * deleted deprecated code * fixed few javadoc issues * updated history * updated release doc Co-authored-by: Joris Kinable <kinable@amazon.com>
DijkstraManyToManyShortestPaths
* Fix warnings in tests Replace deprecated code in order to fix deprecation warnings: - use hamcreset.MatcherAssert.assertThat instead of junit.Assert.asserThat - use assertThrows instead of ExpectedException - and many more like new Integer(int) oder new ModifiableInteger() Use assertEquals(expected, actual) instead of assertTrue(actual==expected) and fix argument order in calls assertEquals (actual and expected was swapped) Fix unused warnings by either removing the unused method/variable or by adding an suppress warning annotation, if removal would disturb the code structure. * Revert fix that accidentally broke the tests
… part 1) (#1066) * [Checkstyle] update to version 8.41 and update DTD-file links * [CheckStyle] enforce Variable/Method/Type-name conventions for non API Add variable/method/type naming-convention checkstyle rules. Fix all variable/method/type naming-convention violations that do not require modifications of the public API. * [CheckStyle] suppress Variable/Method/Type-name rules in API elements Suppress all Variable/Method/Type name violations on API elements. Fixing those rules requires API modifications. In case of (static) fields, the fields are already deprecated and a replacement is provided. org.jgrapht.nio.DefaultAttribute : make static field 'NULL' final. This is actually an API break, but I assume it was never intended to make it modifiable and it was not-final by accident.
* [TSPLIBImporter] Consider multi-space delimiters (#1060) + adjust the tests to cover this case + use FileReader in GraphImporter * [TSPLIBImporter] ignore everything after whitespace for metadata values * Fix accidentally wrong input-data for tests * Replace trim() by strip() to remove all leading/trailing whitespace trim() only removes spaces, strip() removes all whitespace.
Allowed are the characters in the Unicode-blocks BASIC_LATIN (equal to ASCII) and LATIN_1_SUPPLEMENT.
* First version * Typos * Typos * Typos * Added size example * Added size example
Bumps [org.apache.commons:commons-text](https://github.com/apache/commons-text) from 1.14.0 to 1.15.0. - [Changelog](https://github.com/apache/commons-text/blob/master/RELEASE-NOTES.txt) - [Commits](apache/commons-text@rel/commons-text-1.14.0...rel/commons-text-1.15.0) --- updated-dependencies: - dependency-name: org.apache.commons:commons-text dependency-version: 1.15.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
#1327) Bumps [org.apache.maven.plugins:maven-release-plugin](https://github.com/apache/maven-release) from 3.1.1 to 3.3.1. - [Release notes](https://github.com/apache/maven-release/releases) - [Commits](apache/maven-release@maven-release-3.1.1...maven-release-3.3.1) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-release-plugin dependency-version: 3.3.1 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [org.xmlunit:xmlunit-core](https://github.com/xmlunit/xmlunit) from 2.10.3 to 2.11.0. - [Release notes](https://github.com/xmlunit/xmlunit/releases) - [Changelog](https://github.com/xmlunit/xmlunit/blob/main/RELEASE_NOTES.md) - [Commits](xmlunit/xmlunit@v2.10.3...v2.11.0) --- updated-dependencies: - dependency-name: org.xmlunit:xmlunit-core dependency-version: 2.11.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
* Bump com.google.guava:guava from 33.3.1-jre to 33.6.0-jre Bumps [com.google.guava:guava](https://github.com/google/guava) from 33.3.1-jre to 33.6.0-jre. - [Release notes](https://github.com/google/guava/releases) - [Commits](https://github.com/google/guava/commits) --- updated-dependencies: - dependency-name: com.google.guava:guava dependency-version: 33.6.0-jre dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> * Update pom.xml to remove failureaccess exclusion Removed exclusion for 'failureaccess' from dependencies. * Update pom.xml to add new exclusions Added exclusions for error_prone_annotations and jsap in pom.xml. --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: John Sichi <jsichi@gmail.com>
Bumps [com.puppycrawl.tools:checkstyle](https://github.com/checkstyle/checkstyle) from 13.4.0 to 13.4.2. - [Release notes](https://github.com/checkstyle/checkstyle/releases) - [Commits](checkstyle/checkstyle@checkstyle-13.4.0...checkstyle-13.4.2) --- updated-dependencies: - dependency-name: com.puppycrawl.tools:checkstyle dependency-version: 13.4.2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…#1330) Bumps [org.apache.maven.plugins:maven-source-plugin](https://github.com/apache/maven-source-plugin) from 3.3.1 to 3.4.0. - [Release notes](https://github.com/apache/maven-source-plugin/releases) - [Commits](apache/maven-source-plugin@maven-source-plugin-3.3.1...maven-source-plugin-3.4.0) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-source-plugin dependency-version: 3.4.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [org.sonatype.central:central-publishing-maven-plugin](https://github.com/sonatype/central-publishing-maven-plugin) from 0.9.0 to 0.10.0. - [Commits](https://github.com/sonatype/central-publishing-maven-plugin/commits) --- updated-dependencies: - dependency-name: org.sonatype.central:central-publishing-maven-plugin dependency-version: 0.10.0 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…5.0 (#1332) Bumps [org.apache.maven.plugins:maven-resources-plugin](https://github.com/apache/maven-resources-plugin) from 3.3.1 to 3.5.0. - [Release notes](https://github.com/apache/maven-resources-plugin/releases) - [Commits](apache/maven-resources-plugin@maven-resources-plugin-3.3.1...maven-resources-plugin-3.5.0) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-resources-plugin dependency-version: 3.5.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [org.apfloat:apfloat](https://github.com/mtommila/apfloat) from 1.15.0 to 1.16.0. - [Commits](mtommila/apfloat@1.15.0...1.16.0) --- updated-dependencies: - dependency-name: org.apfloat:apfloat dependency-version: 1.16.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…gable spur engines (#1338) Add a new exact Yen-family implementation, BoundedPrunedYenKShortestPath, alongside the existing YenKShortestPath, with two separable optimisations behind a single public class: 1. SpurShortestPathEngine abstraction with two adapter back-ends: - DijkstraSpurEngine: thin adapter delegating to DijkstraShortestPath via MaskSubgraph for ban handling. - AStarSpurEngine: thin adapter delegating to AStarShortestPath via MaskSubgraph + an AStarAdmissibleHeuristic built from a one-time reverse-distance precomputation. The heuristic is admissible by construction (reverse distances are computed on the original graph, and removing vertices/edges only increases shortest-path distances), so A* remains exact under bans. No shortest-path logic is duplicated. 2. BoundedPrunedYenKShortestPath: bounded-pruned Yen driver that defers each spur as a SpurTask keyed by an admissible lower bound and only materialises tasks that could still beat the cheapest known candidate. Includes an exact impossible-spur skip that eliminates doomed tasks before any spur shortest-path query is issued (resolves the path-chain pathology cleanly: every spur on a single-path chain has its only outgoing edge banned by the Yen rule, so all n-1 spurs are skipped). Defaults: the no-engine constructor uses DijkstraSpurEngine (mirrors the spur step of the existing YenKShortestPath); AStarSpurEngine is opt-in via the two-argument constructor and is recommended for dense graphs or larger k. The existing YenKShortestPath is unchanged. Tests (BoundedPrunedYenKShortestPathTest, 24 cases, JUnit 5): - hand-built edge cases: negative-k, k=0, unreachable sink, source==sink, zero-weight edges, single-edge graph, k larger than total paths, large-k stress, negative-weight rejection - explicit cross-engine smoke (Dijkstra + A* vs YenKShortestPath) - property-style fuzz suites (~115 random graph configurations across random DAGs, random cyclic digraphs, and grids), every case asserting the same ordered path-weight sequence as YenKShortestPath - impossible-spur skip behaviour assertions Benchmark: BoundedPrunedYenKShortestPathPerformance is a JMH benchmark at the canonical jgrapht-core/src/test/java/org/jgrapht/perf/shortestpath path, in the same style as KShortestPathsPerformance. On Gnp random digraphs, BoundedPrunedYenKShortestPath with AStarSpurEngine measures 10.9x faster than YenKShortestPath at n=500 and 27.3x faster at n=1500 (tight measurement: -f 2 -wi 2 -i 8, Cnt=16). The Dijkstra-backed bounded variant is slower on this workload, so the dense-random-graph win comes from the A* spur engine; the bounded scheduling layer is workload-conditional. References (in BoundedPrunedYenKShortestPath javadoc): - Yen, J. Y. (1971). Finding the k shortest loopless paths in a network. - Martins, E. Q. V., & Pascoal, M. M. B. (2003). A new implementation of Yen's ranking loopless paths algorithm. - Aljazzar, H., & Leue, S. (2011). K*: A heuristic search algorithm for finding the k shortest paths. Discussed on jgrapht-dev before opening this PR: https://groups.google.com/g/jgrapht-dev/c/JHFs5n7dMpI Co-authored-by: Claude Sonnet 4.7 <noreply@anthropic.com>
Bumps [nokogiri](https://github.com/sparklemotion/nokogiri) from 1.19.1 to 1.19.3. - [Release notes](https://github.com/sparklemotion/nokogiri/releases) - [Changelog](https://github.com/sparklemotion/nokogiri/blob/main/CHANGELOG.md) - [Commits](sparklemotion/nokogiri@v1.19.1...v1.19.3) --- updated-dependencies: - dependency-name: nokogiri dependency-version: 1.19.3 dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…1341) * perf(shortestpath): avoid unused pathVertices set and use ArrayDeque in AllDirectedPaths In AllDirectedPaths.generatePaths the per-pop pathVertices HashSet is only consulted by the simple-path self-intersection filter, but it was rebuilt unconditionally on every iteration of the main loop. In non-simple-paths mode the rebuild is wasted O(path length) work; guard it behind the simplePathsOnly check. Java short-circuit evaluation keeps the dereference safe. Also switch the incompletePaths queue from LinkedList to ArrayDeque to remove the per-node linked-list overhead. The queue is only used through the Deque interface (poll / addFirst / add / isEmpty), which ArrayDeque supports identically with better allocation behavior. Pure refactor; no behavioral difference. Already covered by testCycleBehavior on AllDirectedPathsTest, which exercises both simplePathsOnly modes on a cyclic toy graph. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * perf(shortestpath): add JMH bench for AllDirectedPaths non-simple mode * test(shortestpath): expand AllDirectedPaths non-simple-mode coverage with brute-force oracle --------- Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
…(V) to run one source search (#1340) * perf(shortestpath): use one Dijkstra in DijkstraManyToManyShortestPaths.getPaths Override getPaths(V) on DijkstraManyToManyShortestPaths to run a single DijkstraClosestFirstIterator over the source via getShortestPathsTree, instead of inheriting the BaseManyToManyShortestPaths fallback that calls getPath(source, v) once per vertex of the graph (which re-runs Dijkstra from the same source via getManyToManyPaths each time, an O(|V| * (V log V + E)) cost for what should be O(V log V + E)). The base-class fallback is preserved unchanged for DefaultManyToManyShortestPaths (which would otherwise bypass the user-supplied algorithm function) and CHManyToManyShortestPaths (which would otherwise bypass its contraction-hierarchy preprocessing). Adds regression tests: - DijkstraManyToManyShortestPathsTest: oracle agreement vs DijkstraShortestPath on reachable/unreachable targets; precondition. - DefaultManyToManyShortestPathsTest: function-spy proving the user-supplied algorithm function is consulted on getPaths(source). - CHManyToManyShortestPathsTest: oracle agreement on getPaths(source) for every vertex of the test graph. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * perf(shortestpath): add JMH bench for DijkstraManyToManyShortestPaths.getPaths * test(shortestpath): expand DijkstraManyToManyShortestPaths.getPaths coverage with fuzz + edge cases * test(shortestpath): factor SingleSourcePaths assertCorrectPaths into shared base Per code review on #1340: extract the SingleSourcePaths oracle-agreement check into a new BaseManyToManyShortestPathsTest .assertCorrectPaths(graph, paths, source, targets) helper, alongside the existing ManyToManyShortestPaths variant. Replaces the inline DijkstraShortestPath oracle loops in: - CHManyToManyShortestPathsTest.testGetPathsMatchesDijkstraOracle - DefaultManyToManyShortestPathsTest .testGetPathsConsultsProvidedAlgorithmFunction - DijkstraManyToManyShortestPathsTest: * testGetPathsSingleSourceMatchesDijkstra * testGetPathsSingleVertexGraph * testGetPathsSourceHasNoOutgoingEdges * testGetPathsDisconnectedGraph * testGetPathsCyclicGraphWithSelfLoopOnSource * testGetPathsFuzzAgainstDijkstraOracle The helper handles the unreachable-target contract (null path / +Inf weight) so callers no longer hand-roll the per-target null/non-null branches. testGetPathsCalledTwiceReturnsConsistentResults keeps its bespoke pair-of-calls comparison since it does not verify against an oracle. Pure refactor. 40/40 m2m tests still pass; full jgrapht-core suite 6885/6885 green; checkstyle + javadoc clean. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
* perf(shortestpath): add forward-pruning preprocessing to AllDirectedPaths
Before this change, `edgeMinDistancesBackwards` walked back from every target
and decorated every edge whose head was backward-reachable to a target within
the budget, including edges whose tail is not forward-reachable from any source
within the budget. Such edges cannot lie on any feasible source -> target walk
and would never be traversed by the forward enumeration in `generatePaths` in
either simple or non-simple mode, so decorating them is wasted preprocessing
work that the subsequent enumeration pays for again per outgoing edge.
This change adds a forward BFS from the source set (`vertexMinDistancesForwards`)
and threads its result into `edgeMinDistancesBackwards`. An edge (u, v) is
retained only when u is forward-reachable from some source and the sandwich
inequality holds:
dF(u) + 1 + dB(v) <= maxPathLength
where dF(u) is the forward BFS distance from the source set to u and 1 + dB(v)
is the backward BFS distance from v to a target through this edge. Edges that
fail the sandwich cannot appear on any feasible source -> target walk within
the budget. The inequality is written as
`forwardOfSource > maxPathLength - childDistance` to avoid integer overflow at
extreme `maxPathLength` values; the BFS bounds guarantee
`childDistance <= maxPathLength` when `maxPathLength` is set, so the right-hand
side is non-negative.
The optimisation is enabled by default. A setter on the existing instance
exposes the toggle:
public void setForwardPruning(boolean forwardPruning)
public boolean isForwardPruning()
The two existing public constructors, `AllDirectedPaths(Graph)` and
`AllDirectedPaths(Graph, PathValidator)`, are unchanged. Callers that want the
historical backward-only preprocessing behaviour exactly can recover it with
`setForwardPruning(false)`. The prune is exact - it never drops an edge that
could lie on a feasible walk - so the produced path set is identical in both
modes. On graphs where the prune never fires (e.g. small dense strongly-
connected digraphs), enabling it adds the cost of one extra O(V + E) BFS per
`getAllPaths` call, which is dominated by the enumeration itself.
The class-level Javadoc is expanded to describe the two-phase preprocessing /
enumeration design and the forward-pruning preprocessing, so the IDE-visible
documentation explains when the toggle is useful without requiring the reader
to find the setter first.
Tests in `AllDirectedPathsTest` are extended with cases that exercise both
`forwardPruning=true` and `forwardPruning=false`:
- `testTargetReachableButSourceUnreachableBranchIsIgnored` -
canonical garden-vertex case
- `testMultipleSourcesPartialGarden` - one source reaches target,
another is isolated
- `testUnboundedSimplePathsWithUnreachableGarden` -
`maxPathLength=null` boundary
- `testSourceEqualsTargetInDisconnectedGraph` - trivial zero-length walk
- `testDenseStronglyConnectedLossCase` - bounded overhead, identical results
- `testFuzzAgainstBruteForce` - 8 seeded random graphs, both modes, simple
and non-simple, compared as path sets against a brute-force enumeration
Refs: https://groups.google.com/g/jgrapht-dev/c/fhhJk9FVFoo
Co-Authored-By: Claude <noreply@anthropic.com>
* perf(shortestpath): add JMH bench for AllDirectedPaths forward pruning
Two cell families, each parameterised over `forwardPruning` so the cost of
the optimisation is directly comparable to the historical preprocessing
path in the same JVM:
- Win case: forward chain of `chainLen` vertices 0 -> 1 -> ... -> T plus a
`gardenSize`-vertex source-disconnected garden whose every vertex has an
edge into T. Simple-paths mode, `maxPathLength = chainLen + 5`. The
garden is reachable backwards from T but no garden vertex is reachable
forwards from the source, so when forward pruning is off the backward
sweep marks every garden vertex.
- Loss case: small dense strongly-connected digraph where F = B = V, so
the forward BFS is pure overhead and the prune never drops anything.
Bounds the regression cost when forward pruning is enabled on a graph
it cannot help.
Sample numbers on JDK 21.0.10 (8 measurement iterations, 2s each):
Win case (chainLen=20):
gardenSize off (ms/op) on (ms/op) speedup
500 0.043 +/- 0.001 0.011 +/- 0.001 3.9x
1000 0.080 +/- 0.002 0.015 +/- 0.001 5.3x
2000 0.171 +/- 0.014 0.022 +/- 0.001 7.8x
Loss case (n=20, maxPathLength=3):
off: 0.137 +/- 0.008 ms/op on: 0.141 +/- 0.003 ms/op (within noise)
Co-Authored-By: Claude <noreply@anthropic.com>
---------
Co-authored-by: Claude <noreply@anthropic.com>
Bumps [faraday](https://github.com/lostisland/faraday) from 2.14.1 to 2.14.2. - [Release notes](https://github.com/lostisland/faraday/releases) - [Changelog](https://github.com/lostisland/faraday/blob/main/CHANGELOG.md) - [Commits](lostisland/faraday@v2.14.1...v2.14.2) --- updated-dependencies: - dependency-name: faraday dependency-version: 2.14.2 dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps `junit.version` from 6.0.3 to 6.1.0. Updates `org.junit.jupiter:junit-jupiter` from 6.0.3 to 6.1.0 - [Release notes](https://github.com/junit-team/junit-framework/releases) - [Commits](junit-team/junit-framework@r6.0.3...r6.1.0) Updates `org.junit.platform:junit-platform-suite` from 6.0.3 to 6.1.0 - [Release notes](https://github.com/junit-team/junit-framework/releases) - [Commits](junit-team/junit-framework@r6.0.3...r6.1.0) --- updated-dependencies: - dependency-name: org.junit.jupiter:junit-jupiter dependency-version: 6.1.0 dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: org.junit.platform:junit-platform-suite dependency-version: 6.1.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
* chore(perf-bench): add generic graph-loading utilities for benchmarks
Adds a small package of reusable test-scope utilities for spinning up JMH
benchmarks against external graphs:
- WeightedEdgeListCsvReader: src,dst,weight CSV (gzip/plain) into a target
Graph, with custom vertex parsers, header/delimiter options, and an
add-missing-vertices toggle for callers that pre-add the vertex set.
- CoordinatesCsvReader: id,lat,lon CSV into Map<V, double[]> for use with
geographic A* heuristics.
- HaversineHeuristic: generic AStarAdmissibleHeuristic over a coordinate
lookup, with configurable sphere radius.
- JmhBenchRunner: helper that runs a JMH bench class with forks=0 so it
inherits the surefire JVM module path / argLine, and writes the text
summary to a caller-supplied path.
Each utility ships with JUnit 5 tests; pom.xml adds --add-exports for the
new perf.util package so surefire can resolve the tests.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* chore(perf-bench): add Andorra OSM loader and example benches (data not bundled)
Ships the Java side of the Andorra road-graph benchmark template:
- AndorraGraphLoader: thin wrapper over WeightedEdgeListCsvReader and
CoordinatesCsvReader; returns the loaded graph plus a coordinate map
that pairs with HaversineHeuristic. Adds isFixtureAvailable() and a
helpful IllegalStateException pointing at the README when fixtures
are missing.
- AndorraGraphLoaderSmokeTest: skips via Assumptions.assumeTrue when
fixtures are absent, so the suite stays green on clean checkouts.
- AndorraDijkstraManyToManyShortestPathsBench: AverageTime template for
DijkstraManyToManyShortestPaths on the Andorra graph.
- AndorraAllDirectedPathsNonSimpleBench: bounded-walk enumeration over
a BFS ball around Andorra la Vella.
- AndorraBenchSuite: surefire entry points dispatched via JmhBenchRunner.
- scripts/andorra_to_csv.py: GPKG -> CSV preprocessor, also documented
for use against any Geofabrik free-tier OSM extract.
- src/test/resources/perf/osm/README.md: download + preprocess
instructions; the raw 700KB CSV.gz fixtures are not bundled because
the data is freely re-derivable from Geofabrik (OpenStreetMap) and
changes upstream daily.
pom.xml adds --add-exports / --add-opens for the perf.shortestpath.osm
package; .gitignore needs no allow-list because no binaries land in
src/test/resources/perf/.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* chore(perf-bench): replace Python GPKG preprocessor with Java port
Drops scripts/andorra_to_csv.py in favour of an in-repo Java preprocessor
that fits the JGraphT toolchain. The new class lives next to the generic
readers under org.jgrapht.perf.util and is invoked through Maven /
java -cp like every other test asset; no Python interpreter required.
- GpkgRoadGraphPreprocessor: reads a Geofabrik free-tier GPKG via
sqlite-jdbc, parses the GPKG-wrapped WKB LINESTRING blobs by hand
(the only geometry type the road layer uses), assigns dense vertex
ids by coordinate snapping at 1e-7 deg, runs Kosaraju to pick the
largest SCC, deduplicates parallel edges keeping the shortest weight,
and writes the two CSVs in the exact schema the loader expects.
- pom.xml additions: sqlite-jdbc 3.50.3.0 in parent dependencyManagement
(test scope), referenced in jgrapht-core. java.sql is added to test
compile / test runtime via maven-compiler-plugin testCompilerArgs and
surefire argLine respectively so the production module-info stays
java.sql-free.
- README.md update: invocation example switched from python ... to
mvn exec:java / java -cp.
- AndorraGraphLoader javadoc: cross-reference updated to
GpkgRoadGraphPreprocessor.
Verified by running the Java preprocessor against the Andorra GPKG and
feeding its output through AndorraGraphLoaderSmokeTest: 36,618 vertices
/ 67,354 edges in the largest SCC, identical to the Python preprocessor
output, Dijkstra route 0 -> last vertex succeeds, Haversine heuristic
admissible.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* chore(osm): refactor OSM integration into new jgrapht-osm module
Restructures the OSM preprocessor / loader / heuristic into a new
top-level jgrapht-osm module so the OSM integration is application-
facing production code rather than jgrapht-core test infrastructure,
per dev-list feedback (John Sichi, 2026-05-23).
What moves:
- org.jgrapht.osm.GpkgRoadGraphPreprocessor (was perf.util in core)
- org.jgrapht.osm.HaversineHeuristic (was perf.util in core)
- org.jgrapht.osm.AndorraGraphLoader (was perf.shortestpath.osm in core)
- org.jgrapht.osm.AndorraGraphLoaderSmokeTest (same)
- org.jgrapht.osm.perf.AndorraDijkstraManyToManyShortestPathsBench
- org.jgrapht.osm.perf.AndorraAllDirectedPathsNonSimpleBench
- org.jgrapht.osm.perf.AndorraBenchSuite
- org.jgrapht.osm.perf.JmhBenchRunner
Production scope now: GpkgRoadGraphPreprocessor, HaversineHeuristic,
OsmCsvGraphLoader, OsmCoordinatesReader. Test scope: the Andorra
fixture helper + smoke test + the JMH bench templates.
What drops:
- WeightedEdgeListCsvReader (replaced by jgrapht-io CSVImporter; the
preprocessor now writes headerless CSVs that CSVImporter consumes
directly with CSVFormat.EDGE_LIST + EDGE_WEIGHTS=true).
- CoordinatesCsvReader (replaced by OsmCoordinatesReader, which is
geographic-specific and lives in the OSM module).
What disappears from jgrapht-core:
- sqlite-jdbc dependency (only jgrapht-osm needs it; now compile scope
there, not test scope in core).
- --add-modules java.sql / --add-reads org.jgrapht.core=java.sql in
testCompile and surefire argLine -- the new module declares
requires java.sql properly in its module-info.
- perf.shortestpath.osm and perf.util add-exports / add-opens from the
surefire argLine.
The parent pom adds jgrapht-osm to the module list and
dependencyManagement. sqlite-jdbc is no longer test-scoped in
dependencyManagement so the new module can use it at compile time.
The committed test resources directory under
jgrapht-core/src/test/resources/perf/osm/ is removed; its README and
fixture-loading conventions move to jgrapht-osm/src/test/resources/perf/osm/.
Andorra CSV fixtures remain not bundled and are re-derived from
Geofabrik via the Java preprocessor.
Validation:
- mvn -pl jgrapht-osm test: 16/16 pass (Andorra smoke + 3 unit suites).
- mvn -pl jgrapht-core test: 6914/6914 pass (15 unrelated skips).
- AndorraDijkstraManyToManyShortestPathsBench smoke via JMH command
line runs end-to-end through the new module.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* chore(osm): bundle tiny sample fixture so smoke test always runs
Per dev-list feedback (John Sichi, 2026-05-24): include a tiny sample
fixture in the module instead of skipping the smoke test when the
contributor-fetched Andorra CSVs are absent.
Adds two ~50-byte gzipped CSVs under
jgrapht-osm/src/test/resources/perf/osm/:
- sample-edges.csv.gz: 10 directed edges between 5 vertices, all of
weight 111.1949 m (one 0.001-degree step).
- sample-nodes.csv.gz: 5 vertices placed at the equator on 0.001-degree
grid points so the Haversine math comes out to clean values.
The graph topology is:
2 (0.001, 0.001)
|
4 -- 0 -- 1 -- 2
|
3 (0.001, 0)
Adds SampleGraphSmokeTest: loads the fixture via OsmCsvGraphLoader and
OsmCoordinatesReader, asserts the expected counts, asserts every edge
weight matches 111.1949 m within 1e-4 tolerance, runs Dijkstra 0 -> 2
and asserts the two-hop shortest-path weight (2 * 111.1949), and
asserts the Haversine heuristic produces the expected ~157.25 m
diagonal and is admissible against the routed path. The test runs on
every checkout with no external setup.
AndorraGraphLoaderSmokeTest still skips via Assumptions.assumeTrue
when the Andorra CSVs are absent; it remains the opt-in scale check
for contributors who have fetched the Geofabrik extract.
.gitignore: adds an allow-list entry so the sample-*.csv.gz files
pass the default *.gz block, scoped to the sample-* naming convention
so the larger andorra-*.csv.gz fixtures stay gitignored.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* fix(osm): drop brittle exact-count assertions in Andorra smoke test
Reported by John Sichi against PR #1344: the smoke test failed for him
because Geofabrik refreshes the upstream OSM extract daily, so the
exact largest-SCC vertex and edge counts drift between contributors
who download the GPKG on different days. The original assertions
pinned the snapshot I generated against on 2026-05-10.
Replaces the brittle exact-count checks with:
- A sanity floor on vertex count (>= 10_000) that still catches a
loader silently dropping most of the graph but tolerates upstream
drift around the typical 36-37k.
- A relationship check: directed edge count >= vertex count (every
bidirectional OSM road segment produces two directed edges, so this
is a structural invariant for a road graph).
- coords.size() == graph.vertexSet().size() and
coords.keySet().containsAll(graph.vertexSet()), which are real
loader-correctness invariants regardless of snapshot.
The Dijkstra-route-through and Haversine-admissibility assertions are
kept unchanged.
Also softens the javadoc in AndorraDijkstraManyToManyShortestPathsBench
to "~36-37k vertices / ~67k edges depending on the upstream Geofabrik
snapshot" so the docs do not promise the same numbers either.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* chore(osm): wire dist + README + scope sqlite-jdbc to jgrapht-osm
Maintainer review feedback on PR #1344:
1. Move sqlite-jdbc dependency declaration off the root parent pom and
into jgrapht-osm only. The parent pom's dependencyManagement no
longer references sqlite-jdbc; the jgrapht-osm pom declares both
the version property and the dependency inline. This keeps the
dependency footprint of the parent build minimal and matches the
pattern for module-specific deps in this repo.
2. Add a jgrapht-osm dependency to jgrapht-dist so that
jgrapht-osm-x.y.z.jar (and sqlite-jdbc transitively) lands in the
release zip and tar.gz archives under lib/.
3. Update the top-level README:
- "Release Contents" section lists the new jgrapht-osm jar and the
sqlite-jdbc dependency jar.
- "Dependencies" section describes sqlite-jdbc and the modules that
require it.
Verified by running mvn -pl jgrapht-dist -am package and confirming
both lib/jgrapht-osm-1.6.0-SNAPSHOT.jar and
lib/sqlite-jdbc-3.50.3.0.jar are present inside
jgrapht-1.6.0-SNAPSHOT.zip.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* chore(osm): apply DRY review feedback on PR #1344
Three small cleanups requested by John Sichi during review:
1. Haversine math now lives in a single place. HaversineHeuristic
exposes a public static distanceMeters(lat1, lon1, lat2, lon2[,
radiusMeters]); getCostEstimate delegates to it. The private
haversineMeters duplicate inside GpkgRoadGraphPreprocessor is gone,
along with the now-redundant EARTH_RADIUS_M re-export.
2. The three `new long[] { src, dst, Double.doubleToRawLongBits(weight) }`
inline calls in the segment-ingestion lambda collapse to a single
private static packEdge(int, int, double) helper.
3. The gzipOf test helper that was duplicated as a private static in
OsmCsvGraphLoaderTest and OsmCoordinatesReaderTest moves to a
package-private TestStreams class shared by both. Each test imports
the helper via `import static org.jgrapht.osm.TestStreams.*`.
Behaviour unchanged. mvn -pl jgrapht-osm -am test still green
(17/17 osm tests + 6914/6914 core + io).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
Bumps [org.xerial:sqlite-jdbc](https://github.com/xerial/sqlite-jdbc) from 3.50.3.0 to 3.53.1.0. - [Release notes](https://github.com/xerial/sqlite-jdbc/releases) - [Changelog](https://github.com/xerial/sqlite-jdbc/blob/master/CHANGELOG) - [Commits](xerial/sqlite-jdbc@3.50.3.0...3.53.1.0) --- updated-dependencies: - dependency-name: org.xerial:sqlite-jdbc dependency-version: 3.53.1.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps `maven-surefire-plugin.version` from 3.5.5 to 3.5.6. Updates `org.apache.maven.surefire:surefire-junit-platform` from 3.5.5 to 3.5.6 Updates `org.apache.maven.plugins:maven-surefire-plugin` from 3.5.5 to 3.5.6 - [Release notes](https://github.com/apache/maven-surefire/releases) - [Commits](apache/maven-surefire@surefire-3.5.5...surefire-3.5.6) Updates `org.apache.maven.plugins:maven-failsafe-plugin` from 3.5.5 to 3.5.6 - [Release notes](https://github.com/apache/maven-surefire/releases) - [Commits](apache/maven-surefire@surefire-3.5.5...surefire-3.5.6) --- updated-dependencies: - dependency-name: org.apache.maven.surefire:surefire-junit-platform dependency-version: 3.5.6 dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: org.apache.maven.plugins:maven-surefire-plugin dependency-version: 3.5.6 dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: org.apache.maven.plugins:maven-failsafe-plugin dependency-version: 3.5.6 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [org.xmlunit:xmlunit-core](https://github.com/xmlunit/xmlunit) from 2.11.0 to 2.12.0. - [Release notes](https://github.com/xmlunit/xmlunit/releases) - [Changelog](https://github.com/xmlunit/xmlunit/blob/main/RELEASE_NOTES.md) - [Commits](xmlunit/xmlunit@v2.11.0...v2.12.0) --- updated-dependencies: - dependency-name: org.xmlunit:xmlunit-core dependency-version: 2.12.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [com.puppycrawl.tools:checkstyle](https://github.com/checkstyle/checkstyle) from 13.4.2 to 13.5.0. - [Release notes](https://github.com/checkstyle/checkstyle/releases) - [Commits](checkstyle/checkstyle@checkstyle-13.4.2...checkstyle-13.5.0) --- updated-dependencies: - dependency-name: com.puppycrawl.tools:checkstyle dependency-version: 13.5.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
* feat(hamiltonian): add Hamiltonian path API and backtracking solver
Introduce org.jgrapht.alg.hamiltonian and HamiltonianPathAlgorithm<V,E>,
the path-specific counterpart of HamiltonianCycleAlgorithm. Add
BacktrackingHamiltonianPath, an exact DFS-based solver for directed and
undirected graphs that applies several correctness-preserving prunes:
cheap structural prechecks (connectivity, leaf count, cut-vertex block
degree), per-step forward reachability, and minimum-remaining-values
candidate ordering. Returns a GraphWalk or null when the exhaustive
search proves no Hamiltonian path exists.
Includes a shared HamiltonianPathValidator test helper, 16 deterministic
unit tests, and a brute-force-oracle randomized cross-check over ~1200
small random graphs across directed and undirected families.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* feat(hamiltonian): add Held-Karp dynamic-programming solver
Add HeldKarpHamiltonianPath<V,E>, an exact O(n^2 * 2^n) time and
O(n * 2^n) memory DP that decides Hamiltonian path existence on
directed and undirected graphs by tracking the predecessor of the
current endpoint across vertex subsets. Refuses graphs with more
than 20 vertices to keep memory and runtime within practical limits.
Cross-validated against BacktrackingHamiltonianPath on ~600 small
random directed and undirected graphs.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* feat(hamiltonian): add polynomial DAG-specific solver
Add DagHamiltonianPath<V,E>, a linear-time exact solver for directed
acyclic graphs. Computes a topological order and the longest directed
path via DP over topological positions; if its length reaches |V|, the
reconstructed path is the Hamiltonian path. Throws when given a
non-DAG so callers must dispatch consciously to the general solvers.
Cross-validated against BacktrackingHamiltonianPath on ~600 random
small DAGs.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* perf(hamiltonian): add JMH baseline benchmarks
Add HamiltonianPathPerformanceTest covering BacktrackingHamiltonianPath
and HeldKarpHamiltonianPath on path, cycle, complete, and sparse random
graph families at n in {8, 12}. Provides a tiny testSmoke driver for
sanity-checking the benchmark wiring before the broader testBaseline
driver runs. JMH parameters are intentionally small and cell budgets
are bounded so that runaway exponential cells cannot stall the run.
Add the new perf package to the surefire --add-exports list in
jgrapht-core/pom.xml so the benchmark fork can access JMH's generated
runner classes on the Java module path.
Baseline numbers (one local run, 1 fork x 1 warmup x 2 measurement at
1s each):
family n backtracking heldKarp
PATH 8 0.007 ms 0.008 ms
PATH 12 0.010 ms 0.262 ms
CYCLE 8 0.005 ms 0.008 ms
CYCLE 12 0.006 ms 0.241 ms
COMPLETE 8 0.009 ms 0.019 ms
COMPLETE 12 0.016 ms 1.306 ms
SPARSE 8 0.006 ms 0.010 ms
SPARSE 12 0.001 ms 0.239 ms
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* docs(demo): add HamiltonianPathDemo
Three small end-to-end examples covering the new Hamiltonian path API:
an undirected backtracking solve, the polynomial DAG-specific solver
on a directed acyclic workflow graph, and the Held-Karp DP solver on a
small undirected cycle. The demo prints each computed path and its
weight, or a clear message when no Hamiltonian path exists.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* perf(hamiltonian): SCC precheck, states counter, extra bench families
* Add a directed-graph precheck in BacktrackingHamiltonianPath that
computes the strongly connected component condensation and rejects
the graph when the condensation DAG itself has no Hamiltonian path.
Mirrors the existing undirected cut-vertex check; covered by two new
unit tests (disjoint and chained SCC fixtures) plus the existing
randomised cross-checks.
* Expose getStatesExpanded() on BacktrackingHamiltonianPath, an
invocation-scoped DFS-state counter for benchmarking and diagnostic
use. Not part of the algorithmic contract; reset on each getPath
call.
* Extend the JMH benchmark with STAR_NEG, MODULAR_BRIDGES, and
DAG_POS graph families; factor the builders out into GraphBuilders
so the new HamiltonianPathStateCountTest can share them. The
state-count harness prints a per-family table to stdout showing
states explored and wall time for backtracking and Held-Karp,
asserting only that the two solvers agree on existence.
State counts on the new families confirm the prechecks fire: STAR_NEG
and SPARSE-no-path both reject in 0 DFS states; MODULAR_BRIDGES and
PATH/CYCLE/COMPLETE find a path in exactly n states.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* docs(hamiltonian): polish for review feedback
* Add self-loop-on-cut-vertex and self-loops-on-multiple-cut-vertices
regression tests. They confirm BiconnectivityInspector does not
inflate cut-vertex block counts in the presence of self-loops, so
the cut-vertex precheck is correct without an explicit self-loop
filter. The tests lock that behaviour going forward.
* Mention multigraph semantics in the JavaDoc of all three solvers:
parallel edges between the same vertex pair collapse to a single
branch/transition, and the returned GraphPath uses an arbitrary
representative edge via Graph#getEdge rather than minimising weight
across parallel edges.
* Update HamiltonianPathPerformanceTest JavaDoc to reflect the seven
graph families it now exercises instead of the original four.
* Reword BacktrackingHamiltonianPath.getStatesExpanded() JavaDoc:
drop the contradictory "not part of the contract" framing and align
with AStarShortestPath.getNumberOfExpandedNodes() phrasing about
diagnostic intent and unstable counting semantics.
* Clarify in HamiltonianPathStateCountTest's class JavaDoc that the
harness lives in the perf package and is excluded from default CI
test runs by jgrapht-core's surefire **/perf/** exclude, so its
stdout table will not noise normal builds.
* Add HISTORY.md entry under the 1.6.0 (Under development) section.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* feat(hamiltonian): bridge-tree precheck and bounded-execution API
Two HLD items previously deferred land here.
Bridge-tree precheck (HLD section 6.1). In the bridge tree of an
undirected graph (nodes = 2-edge-connected components, edges = the
graph's bridges) every component must have at most two incident
bridges, since a Hamiltonian path enters and leaves each component at
most once. This rule catches structures the cut-vertex check misses,
in particular a cycle with three triangles attached via bridges to
three different cycle vertices; a regression test using Held-Karp as
the oracle locks the behaviour.
Bounded-execution API (HLD section 5.2). The new
HamiltonianPathSearchResult class exposes a tri-state outcome
(PATH_FOUND / PROVEN_ABSENT / ABORTED) so a caller of the new
searchWithStateLimit(graph, maxStates) method on
BacktrackingHamiltonianPath can distinguish a search that proved no
Hamiltonian path exists from one that was stopped early by the state
budget. Structural prechecks run before the bounded DFS and are not
counted against the budget, so graphs they reject are reported as
PROVEN_ABSENT. Ten new unit tests cover input validation, the easy
PATH_FOUND case, precheck-driven PROVEN_ABSENT, low-budget ABORTED on
a dense graph, exact-budget success, and ensuring a bounded call does
not leak its limit to a subsequent unbounded getPath() invocation on
the same algorithm instance.
Also adjusts the self-loop test comments to reflect the actual finding
that BiconnectivityInspector does not inflate cut-vertex block counts
for self-loops, rather than implying the production code applies a
self-loop filter.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* perf(hamiltonian): widen baseline bench to n in {8, 12, 16}
Add n=16 to the @Param of HamiltonianPathPerformanceTest and the
SIZES array of HamiltonianPathStateCountTest. The wider sweep makes
the asymptotic O(n^2 * 2^n) cost of Held-Karp visible and shows that
backtracking with pruning stays sub-millisecond on every family
through n=16 in this benchmark suite.
testBaseline now covers 7 families x 3 sizes x 2 algorithms = 42
cells. With one fork, one warmup iteration of 1 s, and two
measurement iterations of 1 s the run completes in about 4 min on
commodity hardware.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* fix(hamiltonian): tighten bounded-search state-limit contract
Two small but real bugs in the bounded-execution API.
Off-by-one in the state-limit check. The previous extend() incremented
the state counter and then tested it against the configured budget,
which let a search with maxStates = k report up to k + 1 states. Move
the check to before the increment so the invariant
result.getStatesExpanded() <= maxStates holds. The
smallLimitOnHardGraphReturnsAborted test now asserts the exact count,
and a new statesExpandedNeverExceedsMaxStates property test sweeps
budgets 1..20 against a K_10 graph as a regression guard.
Missing input validation in HamiltonianPathSearchResult factories.
This is a public, immutable value type; provenAbsent() and aborted()
now reject negative statesExpanded with an IllegalArgumentException
matching the existing null-check on found(). A new
factoriesRejectNegativeStateCounts test covers the new guards.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* refactor(tour): consolidate Hamiltonian path into alg.tour with shared base
Address maintainer feedback on the dev-list thread (move 1 of 1, DRY).
Per the maintainer's preference, fold the new Hamiltonian path classes
into the existing alg.tour package next to the cycle/tour code rather
than introducing a parallel alg.hamiltonian package. The interface
itself remains alongside HamiltonianCycleAlgorithm in alg.interfaces.
File moves use git rename so history is preserved. The JMH classes
move from perf.hamiltonian to perf.tour and the pom and module-info
follow.
Apply the DRY review pattern from PR #1340 (shared verification helper
in BaseManyToManyShortestPathsTest) to the production side as well.
Introduce HamiltonianPathAlgorithmBase, mirroring the existing
HamiltonianCycleAlgorithmBase in shape, with the helpers shared by
all three solvers:
- requireNotEmpty(graph)
- singletonPath(graph)
- vertexListToPath(vertices, graph)
- buildAdjacency(graph, indexToVertex, vertexToIndex, directed)
(collapses parallel edges and skips self-loops)
BacktrackingHamiltonianPath, HeldKarpHamiltonianPath, and
DagHamiltonianPath now extend the base instead of duplicating these
helpers; net deletion in the impl classes. Package documentation in
alg.tour now explicitly distinguishes the cycle/tour and path solver
families.
All 58 hamiltonian unit tests, the random oracle suite, and the full
jgrapht-core FastTestSuite (5253 tests) pass after the refactor; the
state-count diagnostic shows identical state counts per family, so
the algorithmic behaviour is unchanged.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* refactor(tour): apply PR #1346 review feedback
Addresses John Sichi's review on the Hamiltonian path PR.
- getPath now returns a tri-state HamiltonianPathSearchResult instead of
a nullable GraphPath. A fresh algorithm interface need not inherit the
old null convention, and for an NP-complete search null conflates
"proven absent" with "search aborted"; the result type
(PATH_FOUND / PROVEN_ABSENT / ABORTED) makes the distinction explicit.
- HamiltonianPathSearchResult extracted from a final class in alg.tour to
a companion interface in alg.interfaces, beside HamiltonianPathAlgorithm,
with a Status enum, accessors, and static found/provenAbsent/aborted
factories returning a private immutable Default implementation.
- DagHamiltonianPath drops the standalone CycleDetector pass and instead
catches the NotDirectedAcyclicGraphException that TopologicalOrderIterator
already throws on cyclic input, eliminating one O(V + E) traversal per
call. The now-unreachable self-loop guard in the longest-path loop is
removed (the iterator rejects self-loops at construction); a comment
records why no such guard is needed.
- HeldKarpHamiltonianPath's vertex ceiling becomes a constructor parameter
(default 20, validated against a hard cap of 30, the int-bitmask overflow
boundary) instead of a hardcoded constant.
- BacktrackingHamiltonianPath uses Graphs.getVertexToIntegerMapping instead
of hand-rolling the vertex-to-index map, matching HeldKarpHamiltonianPath.
- Added literature references to all three solvers' JavaDoc (Rubin 1974 and
Warnsdorff for backtracking; Held & Karp 1962 and Bellman 1962 for the DP;
CLRS and MIT 6.s078 lecture 17 for the DAG longest-path reduction).
- Reverted the HISTORY.md entry; committers maintain that file separately.
All three solvers now extend a shared HamiltonianPathAlgorithmBase, so the
result-type and mapping changes were made once. Full jgrapht-core
FastTestSuite (5255 tests) and the JMH baseline pass; the result-object
wrapper adds no measurable overhead.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* style(tour): add missing type params to HamiltonianPathSearchResult.Default javadoc
The nested Default implementation class was missing @param <V> and
@param <E> tags on its type Javadoc, which the checkstyle profile flags
as two JavadocType violations. Add them.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* docs(tour): second-round review polish on Hamiltonian path
Follow-up to the API-change commit, addressing reviewer polish notes.
- Replace stale "null is returned" language in BacktrackingHamiltonianPath
with the tri-state PROVEN_ABSENT wording now that getPath returns a
HamiltonianPathSearchResult.
- Soften the literature paragraph so it no longer implies the code is a
verbatim implementation of Rubin's algorithm: it is a straightforward
exact DFS/backtracking solver using standard pruning and
candidate-ordering ideas, with the references given as background.
- Correct the DagHamiltonianPath cyclic-input Javadoc: it now states that
cyclic input raises an IllegalArgumentException *wrapping* the
NotDirectedAcyclicGraphException thrown by TopologicalOrderIterator,
matching the catch-and-rethrow in the code.
- Make the result implementation genuinely non-public: move the former
nested HamiltonianPathSearchResult.Default (implicitly public as an
interface member) to a package-private top-level class
DefaultHamiltonianPathSearchResult in the same package. The interface
factories construct it; it is no longer part of the public API surface.
No behavioural change. jgrapht-core FastTestSuite (5255 tests) and the
checkstyle profile both pass.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
Bumps [org.xerial:sqlite-jdbc](https://github.com/xerial/sqlite-jdbc) from 3.53.1.0 to 3.53.2.0. - [Release notes](https://github.com/xerial/sqlite-jdbc/releases) - [Changelog](https://github.com/xerial/sqlite-jdbc/blob/master/CHANGELOG) - [Commits](xerial/sqlite-jdbc@3.53.1.0...3.53.2.0) --- updated-dependencies: - dependency-name: org.xerial:sqlite-jdbc dependency-version: 3.53.2.0 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.