@@ -211,149 +211,4 @@ TEST_CASE("[AStar3D] Add/Remove") {
211211 }
212212 // It's been great work, cheers. \(^ ^)/
213213}
214-
215- TEST_CASE (" [Stress][AStar3D] Find paths" ) {
216- // Random stress tests with Floyd-Warshall.
217- constexpr int N = 30 ;
218- Math::seed (0 );
219-
220- for (int test = 0 ; test < 1000 ; test++) {
221- AStar3D a;
222- Vector3 p[N];
223- bool adj[N][N] = { { false } };
224-
225- // Assign initial coordinates.
226- for (int u = 0 ; u < N; u++) {
227- p[u].x = Math::rand () % 100 ;
228- p[u].y = Math::rand () % 100 ;
229- p[u].z = Math::rand () % 100 ;
230- a.add_point (u, p[u]);
231- }
232- // Generate a random sequence of operations.
233- for (int i = 0 ; i < 1000 ; i++) {
234- // Pick two different vertices.
235- int u, v;
236- u = Math::rand () % N;
237- v = Math::rand () % (N - 1 );
238- if (u == v) {
239- v = N - 1 ;
240- }
241- // Pick a random operation.
242- int op = Math::rand ();
243- switch (op % 9 ) {
244- case 0 :
245- case 1 :
246- case 2 :
247- case 3 :
248- case 4 :
249- case 5 :
250- // Add edge (u, v); possibly bidirectional.
251- a.connect_points (u, v, op % 2 );
252- adj[u][v] = true ;
253- if (op % 2 ) {
254- adj[v][u] = true ;
255- }
256- break ;
257- case 6 :
258- case 7 :
259- // Remove edge (u, v); possibly bidirectional.
260- a.disconnect_points (u, v, op % 2 );
261- adj[u][v] = false ;
262- if (op % 2 ) {
263- adj[v][u] = false ;
264- }
265- break ;
266- case 8 :
267- // Remove point u and add it back; clears adjacent edges and changes coordinates.
268- a.remove_point (u);
269- p[u].x = Math::rand () % 100 ;
270- p[u].y = Math::rand () % 100 ;
271- p[u].z = Math::rand () % 100 ;
272- a.add_point (u, p[u]);
273- for (v = 0 ; v < N; v++) {
274- adj[u][v] = adj[v][u] = false ;
275- }
276- break ;
277- }
278- }
279- // Floyd-Warshall.
280- float d[N][N];
281- for (int u = 0 ; u < N; u++) {
282- for (int v = 0 ; v < N; v++) {
283- d[u][v] = (u == v || adj[u][v]) ? p[u].distance_to (p[v]) : Math::INF;
284- }
285- }
286- for (int w = 0 ; w < N; w++) {
287- for (int u = 0 ; u < N; u++) {
288- for (int v = 0 ; v < N; v++) {
289- if (d[u][v] > d[u][w] + d[w][v]) {
290- d[u][v] = d[u][w] + d[w][v];
291- }
292- }
293- }
294- }
295- // Display statistics.
296- int count = 0 ;
297- for (int u = 0 ; u < N; u++) {
298- for (int v = 0 ; v < N; v++) {
299- if (adj[u][v]) {
300- count++;
301- }
302- }
303- }
304- print_verbose (vformat (" Test #%4d: %3d edges, " , test + 1 , count));
305- count = 0 ;
306- for (int u = 0 ; u < N; u++) {
307- for (int v = 0 ; v < N; v++) {
308- if (!Math::is_inf (d[u][v])) {
309- count++;
310- }
311- }
312- }
313- print_verbose (vformat (" %3d/%d pairs of reachable points\n " , count - N, N * (N - 1 )));
314-
315- // Check A*'s output.
316- bool match = true ;
317- for (int u = 0 ; u < N; u++) {
318- for (int v = 0 ; v < N; v++) {
319- if (u != v) {
320- Vector<int64_t > route = a.get_id_path (u, v);
321- if (!Math::is_inf (d[u][v])) {
322- // Reachable.
323- if (route.size () == 0 ) {
324- print_verbose (vformat (" From %d to %d: A* did not find a path\n " , u, v));
325- match = false ;
326- goto exit;
327- }
328- float astar_dist = 0 ;
329- for (int i = 1 ; i < route.size (); i++) {
330- if (!adj[route[i - 1 ]][route[i]]) {
331- print_verbose (vformat (" From %d to %d: edge (%d, %d) does not exist\n " ,
332- u, v, route[i - 1 ], route[i]));
333- match = false ;
334- goto exit;
335- }
336- astar_dist += p[route[i - 1 ]].distance_to (p[route[i]]);
337- }
338- if (!Math::is_equal_approx (astar_dist, d[u][v])) {
339- print_verbose (vformat (" From %d to %d: Floyd-Warshall gives %.6f, A* gives %.6f\n " ,
340- u, v, d[u][v], astar_dist));
341- match = false ;
342- goto exit;
343- }
344- } else {
345- // Unreachable.
346- if (route.size () > 0 ) {
347- print_verbose (vformat (" From %d to %d: A* somehow found a nonexistent path\n " , u, v));
348- match = false ;
349- goto exit;
350- }
351- }
352- }
353- }
354- }
355- exit:
356- CHECK_MESSAGE (match, " Found all paths." );
357- }
358- }
359214} // namespace TestAStar
0 commit comments