random-boolean-network/random_boolean_network.php
2020-11-14 11:16:17 +01:00

94 lines
2.4 KiB
PHP

<?php
/*
Random boolean network in PHP (7.4+).
Inspired by the Computerphile Video: https://www.youtube.com/watch?v=mCML2B94rUg
The use of random_int combined with modulo leads to better randomness entropy.
Formally correct as the relations with other cells are bitshifted in the right order.
Not that it matters, as it's randomly chosen, but done anyway for the sake of repeatability.
Joop Schilder
Sat 14 Nov 01:30
One of the nights that I shall remember as if it were me who was in control of my brain.
*/
const NUM_NODES = 20;
const NUM_CONNECTIONS = 3;
const NUM_GENERATIONS = 20;
const CHAR_ON_ZERO = '0';
const CHAR_ON_ONE = ' ';
const TRUTH_TABLE_SIZE = (1 << NUM_CONNECTIONS);
$truth_table = [];
for ($i = 0; $i < TRUTH_TABLE_SIZE; $i++) {
$truth_table[$i] = random_int(0, 100) % 2;
}
$nodes = [];
for ($i = 0; $i < NUM_NODES; $i++) {
$nodes[$i] = random_int(0, 100) % 2;
}
$connections = [];
for ($i = 0; $i < NUM_NODES; $i++) {
for ($j = 0; $j < NUM_CONNECTIONS; $j++) {
$connections[$i][$j] = random_int(0, 2000) % 20;
}
}
function print_generation(int $g, array $nodes): void
{
printf("G%5d %s\n", $g, format_nodes($nodes));
}
function print_truth_table(array $truth_table): void
{
print("Truth table:\n");
for($i = 0; $i < TRUTH_TABLE_SIZE; $i++) {
printf("[%s] => %d\n", str_pad(decbin($i), NUM_CONNECTIONS, '0', STR_PAD_LEFT), $truth_table[$i]);
}
}
function print_connections(array $connections): void
{
print("Connections:\n");
for ($i = 0; $i < NUM_NODES; $i++) {
printf("[%3d] => [%s]\n", $i, implode(', ', $connections[$i]));
}
}
function format_nodes(array $nodes): string
{
return implode(' ', array_map(fn($i): string => $i == 0 ? CHAR_ON_ZERO : CHAR_ON_ONE, $nodes));
}
function propagate(array $nodes, array &$connections, array &$truth_table): array
{
$next_nodes = [];
for ($i = 0; $i < NUM_NODES; $i++) {
$tt_index = 0;
for ($j = 0; $j < NUM_CONNECTIONS; $j++) {
$tt_index += $nodes[$connections[$i][$j]] << (NUM_CONNECTIONS - 1 - $j);
}
$next_nodes[$i] = $truth_table[$tt_index];
}
return $next_nodes;
}
print_truth_table($truth_table);
print("\n");
print_connections($connections);
print("\n");
print_generation(0, $nodes);
for ($i = 0; $i < NUM_GENERATIONS; $i++) {
$nodes = propagate($nodes, $connections, $truth_table);
print_generation($i, $nodes);
}