wave11: 488/227 — ROS2/OpenCV/Open3D/metaflow/kubeflow/optuna/openssl/mbedtls/wolfssl + Kafka Streams/Pulsar
This commit is contained in:
parent
6276aea2e5
commit
19333b378e
36 changed files with 4634 additions and 5 deletions
247
defects/open3d/unit/PoseGraphConnectivityAlgorithm.java
Normal file
247
defects/open3d/unit/PoseGraphConnectivityAlgorithm.java
Normal file
|
|
@ -0,0 +1,247 @@
|
|||
package unit;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Unit test for open3d-0001: ValidatePoseGraphConnectivity O(V²×E) → O(V×E)
|
||||
*
|
||||
* Simulates Open3D GlobalOptimization.cpp connectivity BFS:
|
||||
* Defective: std::find on component vector inside while-loop × edge scan
|
||||
* Fixed: unordered_set membership O(1) replaces the O(V) linear scan
|
||||
*
|
||||
* Compile: javac -d . PoseGraphConnectivityAlgorithm.java
|
||||
* Run: java -ea unit.PoseGraphConnectivityAlgorithm
|
||||
*/
|
||||
public class PoseGraphConnectivityAlgorithm {
|
||||
|
||||
static class PoseGraphEdge {
|
||||
final int source;
|
||||
final int target;
|
||||
final boolean uncertain;
|
||||
PoseGraphEdge(int src, int tgt, boolean uncertain) {
|
||||
source = src; target = tgt; this.uncertain = uncertain;
|
||||
}
|
||||
}
|
||||
|
||||
static class PoseGraph {
|
||||
final int nNodes;
|
||||
final List<PoseGraphEdge> edges;
|
||||
PoseGraph(int nNodes, List<PoseGraphEdge> edges) {
|
||||
this.nNodes = nNodes; this.edges = edges;
|
||||
}
|
||||
}
|
||||
|
||||
// ── defective implementation ──────────────────────────────────────────────
|
||||
|
||||
static boolean defectiveValidateConnectivity(PoseGraph pg, boolean ignoreUncertain) {
|
||||
int nNodes = pg.nNodes;
|
||||
if (nNodes == 0) return true;
|
||||
|
||||
List<Integer> toExplore = new ArrayList<>();
|
||||
List<Integer> component = new ArrayList<>(); // O(V) membership
|
||||
toExplore.add(0);
|
||||
component.add(0);
|
||||
|
||||
while (!toExplore.isEmpty()) {
|
||||
int i = toExplore.remove(toExplore.size() - 1);
|
||||
for (PoseGraphEdge e : pg.edges) {
|
||||
if (ignoreUncertain && e.uncertain) continue;
|
||||
int adj = -1;
|
||||
if (e.source == i) adj = e.target;
|
||||
else if (e.target == i) adj = e.source;
|
||||
if (adj != -1) {
|
||||
// O(V) linear scan inside while-loop × edge-scan
|
||||
boolean found = false;
|
||||
for (int c : component) if (c == adj) { found = true; break; }
|
||||
if (!found) {
|
||||
toExplore.add(adj);
|
||||
component.add(adj);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return component.size() == nNodes;
|
||||
}
|
||||
|
||||
// ── fixed implementation ──────────────────────────────────────────────────
|
||||
|
||||
static boolean fixedValidateConnectivity(PoseGraph pg, boolean ignoreUncertain) {
|
||||
int nNodes = pg.nNodes;
|
||||
if (nNodes == 0) return true;
|
||||
|
||||
List<Integer> toExplore = new ArrayList<>();
|
||||
Set<Integer> componentSet = new HashSet<>(); // O(1) membership
|
||||
toExplore.add(0);
|
||||
componentSet.add(0);
|
||||
|
||||
while (!toExplore.isEmpty()) {
|
||||
int i = toExplore.remove(toExplore.size() - 1);
|
||||
for (PoseGraphEdge e : pg.edges) {
|
||||
if (ignoreUncertain && e.uncertain) continue;
|
||||
int adj = -1;
|
||||
if (e.source == i) adj = e.target;
|
||||
else if (e.target == i) adj = e.source;
|
||||
if (adj != -1) {
|
||||
if (componentSet.add(adj)) { // O(1) insert+dedup
|
||||
toExplore.add(adj);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return componentSet.size() == nNodes;
|
||||
}
|
||||
|
||||
// ── graph builders ────────────────────────────────────────────────────────
|
||||
|
||||
/** Linear chain: 0-1-2-...-n-1 */
|
||||
static PoseGraph buildChain(int n) {
|
||||
List<PoseGraphEdge> edges = new ArrayList<>();
|
||||
for (int i = 0; i < n - 1; i++) edges.add(new PoseGraphEdge(i, i + 1, false));
|
||||
return new PoseGraph(n, edges);
|
||||
}
|
||||
|
||||
/** Complete graph: all pairs connected */
|
||||
static PoseGraph buildComplete(int n) {
|
||||
List<PoseGraphEdge> edges = new ArrayList<>();
|
||||
for (int i = 0; i < n; i++)
|
||||
for (int j = i + 1; j < n; j++) edges.add(new PoseGraphEdge(i, j, false));
|
||||
return new PoseGraph(n, edges);
|
||||
}
|
||||
|
||||
/** Disconnected: two isolated cliques */
|
||||
static PoseGraph buildDisconnected(int n) {
|
||||
List<PoseGraphEdge> edges = new ArrayList<>();
|
||||
int half = n / 2;
|
||||
for (int i = 0; i < half - 1; i++) edges.add(new PoseGraphEdge(i, i + 1, false));
|
||||
for (int i = half; i < n - 1; i++) edges.add(new PoseGraphEdge(i, i + 1, false));
|
||||
return new PoseGraph(n, edges);
|
||||
}
|
||||
|
||||
/** Certain-edge-only graph: some edges marked uncertain */
|
||||
static PoseGraph buildMixed(int n, double uncertainFraction) {
|
||||
List<PoseGraphEdge> edges = new ArrayList<>();
|
||||
// Build a chain where every other edge is uncertain
|
||||
for (int i = 0; i < n - 1; i++) {
|
||||
boolean uncertain = (i % 2 == 1);
|
||||
edges.add(new PoseGraphEdge(i, i + 1, uncertain));
|
||||
}
|
||||
return new PoseGraph(n, edges);
|
||||
}
|
||||
|
||||
// ── tests ─────────────────────────────────────────────────────────────────
|
||||
|
||||
static int pass = 0, total = 0;
|
||||
|
||||
static void assertTrue(String name, boolean cond) {
|
||||
total++;
|
||||
if (cond) { pass++; System.out.println("PASS " + name); }
|
||||
else System.out.println("FAIL " + name);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
// Test 1: empty graph → connected (vacuously)
|
||||
{
|
||||
PoseGraph pg = new PoseGraph(0, Collections.emptyList());
|
||||
assertTrue("empty-defective", defectiveValidateConnectivity(pg, false));
|
||||
assertTrue("empty-fixed", fixedValidateConnectivity(pg, false));
|
||||
}
|
||||
|
||||
// Test 2: single node → connected
|
||||
{
|
||||
PoseGraph pg = new PoseGraph(1, Collections.emptyList());
|
||||
assertTrue("single-node-defective", defectiveValidateConnectivity(pg, false));
|
||||
assertTrue("single-node-fixed", fixedValidateConnectivity(pg, false));
|
||||
}
|
||||
|
||||
// Test 3: chain of 5 → connected
|
||||
{
|
||||
PoseGraph pg = buildChain(5);
|
||||
assertTrue("chain5-defective", defectiveValidateConnectivity(pg, false));
|
||||
assertTrue("chain5-fixed", fixedValidateConnectivity(pg, false));
|
||||
}
|
||||
|
||||
// Test 4: complete graph of 6 → connected
|
||||
{
|
||||
PoseGraph pg = buildComplete(6);
|
||||
assertTrue("complete6-defective", defectiveValidateConnectivity(pg, false));
|
||||
assertTrue("complete6-fixed", fixedValidateConnectivity(pg, false));
|
||||
}
|
||||
|
||||
// Test 5: disconnected → not connected
|
||||
{
|
||||
PoseGraph pg = buildDisconnected(6);
|
||||
assertTrue("disconnected6-defective", !defectiveValidateConnectivity(pg, false));
|
||||
assertTrue("disconnected6-fixed", !fixedValidateConnectivity(pg, false));
|
||||
}
|
||||
|
||||
// Test 6: mixed uncertain edges — chain connected via uncertain edges only
|
||||
{
|
||||
// 4 nodes: 0--1(certain) 1--2(uncertain) 2--3(certain)
|
||||
List<PoseGraphEdge> edges = Arrays.asList(
|
||||
new PoseGraphEdge(0, 1, false),
|
||||
new PoseGraphEdge(1, 2, true),
|
||||
new PoseGraphEdge(2, 3, false));
|
||||
PoseGraph pg = new PoseGraph(4, edges);
|
||||
// Ignoring uncertain: 0-1 certain, 2-3 certain, but 1-2 uncertain → not connected
|
||||
assertTrue("uncertain-ignore-defective", !defectiveValidateConnectivity(pg, true));
|
||||
assertTrue("uncertain-ignore-fixed", !fixedValidateConnectivity(pg, true));
|
||||
// Not ignoring uncertain: all connected
|
||||
assertTrue("uncertain-include-defective", defectiveValidateConnectivity(pg, false));
|
||||
assertTrue("uncertain-include-fixed", fixedValidateConnectivity(pg, false));
|
||||
}
|
||||
|
||||
// Test 7: both implementations agree on random graph
|
||||
{
|
||||
Random rng = new Random(42);
|
||||
int V = 30, extraEdges = 60;
|
||||
List<PoseGraphEdge> edges = new ArrayList<>();
|
||||
for (int i = 0; i < V - 1; i++) edges.add(new PoseGraphEdge(i, i + 1, false));
|
||||
for (int i = 0; i < extraEdges; i++) {
|
||||
int a = rng.nextInt(V), b = rng.nextInt(V);
|
||||
edges.add(new PoseGraphEdge(a, b, rng.nextBoolean()));
|
||||
}
|
||||
PoseGraph pg = new PoseGraph(V, edges);
|
||||
boolean d = defectiveValidateConnectivity(pg, false);
|
||||
boolean f = fixedValidateConnectivity(pg, false);
|
||||
assertTrue("random-graph-agree", d == f);
|
||||
assertTrue("random-graph-connected", f); // chain ensures connectivity
|
||||
}
|
||||
|
||||
// Test 8: performance — component membership check isolated at V=1000
|
||||
// Builds a large component list, then simulates the find-or-add operation
|
||||
{
|
||||
int V = 2000;
|
||||
// Simulate: component grows to V, each element checked V times = O(V²)
|
||||
long t0 = System.nanoTime();
|
||||
for (int r = 0; r < 10; r++) {
|
||||
List<Integer> component = new ArrayList<>(V);
|
||||
for (int i = 0; i < V; i++) {
|
||||
// defective: linear scan to check if i already in component
|
||||
boolean found = false;
|
||||
for (int c : component) if (c == i) { found = true; break; }
|
||||
if (!found) component.add(i);
|
||||
}
|
||||
}
|
||||
long tDef = System.nanoTime() - t0;
|
||||
|
||||
t0 = System.nanoTime();
|
||||
for (int r = 0; r < 10; r++) {
|
||||
Set<Integer> componentSet = new HashSet<>(V * 2);
|
||||
List<Integer> componentList = new ArrayList<>(V);
|
||||
for (int i = 0; i < V; i++) {
|
||||
// fixed: O(1) set insert
|
||||
if (componentSet.add(i)) componentList.add(i);
|
||||
}
|
||||
}
|
||||
long tFix = System.nanoTime() - t0;
|
||||
|
||||
double ratio = (double) tDef / tFix;
|
||||
System.out.printf(" Perf component-dedup V=%d: defective=%.1fms fixed=%.1fms ratio=%.1fx%n",
|
||||
V, tDef / 1e6, tFix / 1e6, ratio);
|
||||
assertTrue("perf-speedup", ratio > 5.0);
|
||||
}
|
||||
|
||||
System.out.println(pass + "/" + total + " PASS");
|
||||
assert pass == total : pass + "/" + total + " passed";
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue