std::vector<Point> poisson_sample(double height, double width, int new_points_count, double octaves, double persistence, double scale, double low, double high, double seed) { double cellsize = high / sqrt(2.0); Grid<Point> grid(ceil(height / cellsize), ceil(width / cellsize)); RandomQueue<Point> processing_list; std::vector<Point> output_list; Point p, q; double min_dist; Point first(random_real(height), random_real(width)); processing_list.push(first); output_list.push_back(first); grid.add(image_to_grid(first, cellsize), first); while (!processing_list.empty()) { p = processing_list.pop(); for (int i = 0; i < new_points_count; ++i) { q = generateRandomPointAround(p, min_dist); min_dist = scaled_octave_noise(octaves, persistence, scale, low, high, q.x, q.y, seed); if (in_rectangle(height, width, q) && !in_neighborhood(grid, q, min_dist, cellsize, height, width)) { processing_list.push(q); output_list.push_back(q); grid.add(image_to_grid(q, cellsize), q); } } } return output_list; }
Pt generateRandomPointAround(Pt p, double min_dist) { double r1, r2, radius, angle; r1 = random_real(1.0, 2.0); r2 = random_real(0.0, 1.0); radius = min_dist * r1; angle = 2.0 * PI * r2; return Pt(p.y + sin(angle) * radius, p.x + cos(angle) * radius); }
int Random::poisson(double mean) /*Post: A random poisoson number with average mean.*/ { double limit = exp(-mean); double product = random_real(); int count = 0; while(product>limit){ count++; product *= random_real(); } return count; }
TEST(ShortestPaths, Astar) { for (int i = 0; i < 100; ++i) { int n = random_int(15, 25); double p = random_real(0.0, 1.0); Graph G = graphs::RandomWeighted(n, p); Vertex u = random_int(0, n); Vertex v = random_int(0, n); auto P = Dijkstra(G, u, v); auto Astar = AstarSearcher(G, u, v, [](Vertex w) { return 0; }); auto P2 = Astar.GetPath(); check_path(G, P2); ASSERT_EQ(TotalWeight(P), TotalWeight(P2)); if (Astar.Distances()[v] != INF) { ASSERT_EQ(TotalWeight(P), Astar.Distances()[v]); } } }
/* Program extracts from Appendix B of
int Random::random_integer(int low, int high) /*Post: A random integer number between [low, high)*/ { if(low>high) return random_integer(high,low); else return((int)((high-low+1)*random_real()))+low; }
int random_int(int n) { return (int) fastfloor(random_real(0.0, n)); }
double random_real(double high) { return random_real(0.0, high); }
bool Random::success_probability(double probability) { return random_real(0.0, 1.0) < probability; }