Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
ca_schelling_segregation_example.cc
Go to the documentation of this file.
1/*
2 Aleph_w
3
4 Data structures & Algorithms
5 version 2.0.0b
6 https://github.com/lrleon/Aleph-w
7
8 This file is part of Aleph-w library
9
10 Copyright (c) 2002-2026 Leandro Rabindranath Leon
11*/
12
36#include <algorithm>
37#include <array>
38#include <cstddef>
39#include <cstdint>
40#include <iomanip>
41#include <iostream>
42#include <random>
43#include <string>
44
45#include <ca-rng.H>
46#include <ca-traits.H>
47#include <tpl_ca_engine.H>
48#include <tpl_ca_lattice.H>
49#include <tpl_ca_neighborhood.H>
50#include <tpl_ca_storage.H>
52
53using namespace Aleph;
54using namespace Aleph::CA;
55
56namespace
57{
58
61
63{
64 std::mt19937 rng(rng_seed);
65 std::discrete_distribution<int> pick({0.10, 0.45, 0.45}); // empty, A, B
66 for (ca_size_t i = 0; i < lat.size(0); ++i)
67 for (ca_size_t j = 0; j < lat.size(1); ++j)
68 lat.set({static_cast<ca_index_t>(i), static_cast<ca_index_t>(j)},
69 pick(rng));
70}
71
72char glyph_for(int v)
73{
74 switch (static_cast<Schelling_Cell>(v))
75 {
76 case Schelling_Cell::EMPTY: return '.';
77 case Schelling_Cell::TYPE_A: return 'A';
78 case Schelling_Cell::TYPE_B: return 'B';
79 }
80 return '?';
81}
82
83void render(const Schelling_Lattice &lat, std::ostream &os)
84{
85 for (ca_size_t i = 0; i < lat.size(0); ++i)
86 {
87 for (ca_size_t j = 0; j < lat.size(1); ++j)
88 os << glyph_for(lat.at({static_cast<ca_index_t>(i),
89 static_cast<ca_index_t>(j)}));
90 os << '\n';
91 }
92}
93
98{
99 std::size_t same = 0;
100 std::size_t total = 0;
101 const ca_size_t n0 = lat.size(0);
102 const ca_size_t n1 = lat.size(1);
103 for (ca_size_t i = 0; i < n0; ++i)
104 for (ca_size_t j = 0; j < n1; ++j)
105 {
106 const int c = lat.at({static_cast<ca_index_t>(i),
107 static_cast<ca_index_t>(j)});
108 if (c == static_cast<int>(Schelling_Cell::EMPTY))
109 continue;
110
111 const int right
112 = lat.at({static_cast<ca_index_t>(i),
113 static_cast<ca_index_t>((j + 1) % n1)});
114 const int down
115 = lat.at({static_cast<ca_index_t>((i + 1) % n0),
116 static_cast<ca_index_t>(j)});
117
118 if (right != static_cast<int>(Schelling_Cell::EMPTY))
119 {
120 ++total;
121 if (right == c) ++same;
122 }
123 if (down != static_cast<int>(Schelling_Cell::EMPTY))
124 {
125 ++total;
126 if (down == c) ++same;
127 }
128 }
129 return total == 0 ? 0.0
130 : static_cast<double>(same) / static_cast<double>(total);
131}
132
133std::string bar(double v, std::size_t width = 40)
134{
135 const std::size_t k
136 = std::min(width, static_cast<std::size_t>(v * static_cast<double>(width)));
137 return std::string(k, '|') + std::string(width - k, ' ');
138}
139
141 double threshold,
142 std::uint64_t master_seed,
143 std::size_t total_steps)
144{
145 std::cout << "\n========================================\n";
146 std::cout << " Schelling threshold = "
147 << std::fixed << std::setprecision(2) << threshold
148 << std::defaultfloat
149 << " steps = " << total_steps
150 << " seed = 0x" << std::hex << master_seed << std::dec << '\n';
151 std::cout << "========================================\n";
152
153 Schelling_Rule<> rule(threshold, /*p_move=*/0.7, /*p_fill=*/0.7,
154 master_seed);
156 engine(seed, rule);
157
158 const double q0 = same_type_edge_fraction(engine.frame());
159 std::cout << " same-type edge fraction (initial) = "
160 << std::fixed << std::setprecision(3) << q0 << std::defaultfloat
161 << " [" << bar(q0) << "]\n";
162
163 engine.run(total_steps);
164
165 const double q1 = same_type_edge_fraction(engine.frame());
166 std::cout << " same-type edge fraction (final) = "
167 << std::fixed << std::setprecision(3) << q1 << std::defaultfloat
168 << " [" << bar(q1) << "]\n";
169
170 std::cout << "\nFinal configuration:\n";
171 render(engine.frame(), std::cout);
172}
173
174} // namespace
175
176int main()
177{
178 constexpr ca_size_t rows = 48;
179 constexpr ca_size_t cols = 48;
180 constexpr std::uint64_t master_seed = 0x5C4E11Aull;
181 constexpr std::size_t total_steps = 80;
182
183 std::cout << "Schelling-style local segregation on a 48x48 toroidal lattice\n";
184 std::cout << " Moore radius 1, two types of agents + 10% vacancy\n";
185 std::cout << " same-type edge fraction is a cluster-quality proxy:\n";
186 std::cout << " ~0.50 = mixed ~1.00 = perfectly segregated\n";
187
189 seed_population(seed, /*rng_seed=*/0xACE0u);
190
191 std::cout << "\nInitial configuration (shared by every scenario):\n";
192 render(seed, std::cout);
193 const double q_seed = same_type_edge_fraction(seed);
194 std::cout << "same-type edge fraction = "
195 << std::fixed << std::setprecision(3) << q_seed << std::defaultfloat
196 << " [" << bar(q_seed) << "]\n";
197
198 for (const double threshold : {0.30, 0.50, 0.70})
199 run_scenario(seed, threshold, master_seed, total_steps);
200
201 std::cout << "\nNote: master_seed and the initial frame are shared across\n"
202 " threshold scenarios, so the trace is reproducible\n"
203 " bit-for-bit on any thread count.\n";
204 return 0;
205}
size_t * rows
Definition ca-c-api.h:112
size_t cols
Definition ca-c-api.h:105
Reproducible random-number support for stochastic CA rules (Phase 8).
Common typedefs and tag types for the Cellular Automata module.
Lattice that adds boundary-aware access on top of a storage.
Moore (Chebyshev) neighborhood of radius R in N dimensions.
Local approximation of the Schelling segregation model.
Synchronous double-buffered engine.
static mt19937 rng
static void bar(int val, int scale=1)
size_t blossom_maximum_cardinality_matching(const GT &g, DynDlist< typename GT::Arc * > &matching, SA sa=SA())
Alias of compute_maximum_cardinality_general_matching().
Definition Blossom.H:466
std::ptrdiff_t ca_index_t
Signed coordinate component used by lattices and neighborhoods.
Definition ca-traits.H:60
Schelling_Cell
Discrete states of the Schelling automaton.
std::size_t ca_size_t
Unsigned size component used for extents and counts.
Definition ca-traits.H:63
Main namespace for Aleph-w library functions.
Definition ah-arena.H:89
The lattice wraps around on every axis.
Definition ca-traits.H:124
ValueArg< size_t > seed
Definition testHash.C:53
static int * k
static mt19937 engine
Synchronous double-buffered engine for cellular automata.
Cellular automata lattice with pluggable boundary policies.
Neighborhoods catalogue for Aleph::CA.
Reproducible stochastic CA rules (Phase 8).
Dense, contiguous storage for cellular automata cells (1D/2D/3D).