Groshik писал(а):
Ок. Итак, у нас есть популяция, очень простая и стабильная - каждое поколение сменяется следующим "один на один". По оси ординат отложены поколения (t), по оси абсцисс - "сложность"(S).
За ее увеличение мы считаем любое добавление гена или переключателя,
ну и наоборот - уменьшение будет потерей гена или переключателя.
Правда, наша популяция вообще никак от этой наследственности не зависит, а живет так,
словно минимально проста всегда. Но кое-что у нее есть все-таки: у нее есть изменчивость
и у нее есть наследственность, потому что место каждого следующего поколения зависит от предыдущего.
...
Что мы видим? У нас сложность "в целом возрастает".
При этом нет никакой силы, которая бы заставляла ее возрастать.
Можно прогнать несколько раз и убедиться, что картина та же.
Так и думал. Замечательно.

Ну а теперь...
Разоблачение черной магииЯ немножко изменил программку, чтобы можно было выделить любой нужный нам путь красным цветом. Исходник прилагается.
Параметры запуска: N=500 R=200 S=1234 T=100

Что мы видим? Даже и близко нет того чудесного процесса, который был в ходе эволюции видов.
Мы построили обычную сумму различных флуктуаций, в полном согласии с теорией вероятности.
Обратите внимание:
усложнение чаще всего сменяется упрощением. Зачастую до начального состояния.
Сможете ли показать мне хоть один пример упрощения высокоразвитого вида до состояния бактерии?Думаю, нет. А в модели, которую вы предложили, таких примеров огромное множество.
Потому что это флуктуации.
Здесь не происходит накопления сложности, которое происходило в ходе эволюции.
Ваша модель - как рулетка. Сегодня вам повезло, а завтра вы все продули.
А вот если бы вы умели накапливать выигрыш в рулетку,
тогда это было бы похоже на эволюцию видов Земли.
Да только никто пока не научился выигрывать в рулетку без помощи казино...
Groshik писал(а):
Но пора познакомить этих существ с суровой правдой жизни! Теперь они будут размножаться и вымирать. Во-первых, каждая точка будет давать две в следующем поколении, каждую по тем же правилам (и нам придется сильно понизить размер популяции, хоть он и так мизерный, а так же уменьшить число поколений, чтоб компьютер нам их год не обсчитывал). Но зато, если раньше мы не давали уходить за 0 - упроститься больше уже нельзя было, то теперь у нас будут эти горемыки "деградировать окончательно". Просто при отрицательном значении линия прервется - все, она больше не может размножаться (а заодно сэкономит нам время обсчета).
Попробуем для 10 линий, скажем, поколений по 20. Лучше бы больше, но не знаю, сколько займет времени. Если что - увеличим популяцию.
А есть ли смысл?
Вы хотите обмануть рулетку?По-моему, единственный вариант - это намеренно увеличить вероятность движения вправо.
Кроссплатформенный исходник на C++ состряпан на коленке за 10 минут. Ошибки не исключены

Для компиляции требуется заголовок
bitmap_image.hppЗапускать с параметрами: N R S T path
N - число шагов по вертикали от 10 до 10000
R - число повторов от 1 до 1000
S - любое целое число для инициализации случайного процесса.
Задавая то же самое число получим ту же самую картинку.
T - какой повтор выделить красным от 0 до R-1
path - опциональный путь к bmp-файлу. По умолчанию output.bmp
Код:
#include "bitmap_image.hpp"
#include <cstdio>
#include <cstdlib>
#include <fstream>
#include <time.h>
const int MIN_POINT = 10;
const int MAX_POINT = 10000;
const int MAX_REP = 1000;
const int KOF_X = 20;
const int KOF_Y = 1;
int main(int argc, char *argv[])
{
int n_points = 0;
int n_rep = 1;
int n_seed = 0;
int n_trace = 0;
if (argc > 4) {
n_points = std::atoi(argv[1]);
n_rep = std::atoi(argv[3]);
n_seed = std::atoi(argv[3]);
n_trace = std::atoi(argv[4]);
}
if (n_points < MIN_POINT || n_rep < 1
|| n_points > MAX_POINT || n_rep > MAX_REP
|| n_trace < 0 || n_trace >= n_rep
|| (argc != 5 && argc != 6)) {
std::cerr << "using:\n"
<< argv[0] << " N R S T path"
<< "\nN\t- number of points from " << MIN_POINT << " to " << MAX_POINT
<< "\nR\t- number of repeats from 1 to " << MAX_REP
<< "\nS\t- integer random seed"
<< "\nT\t- red trace from 0 to R-1"
<< "\npath\t- path to output bmp-file. Default output.bmp\n";
return -1;
}
const char* path = "output.bmp";
if (argc == 6)
path = argv[5];
/// initialize random seed
srand(n_seed);
int* array = new int[n_points * n_rep];
int max_x = 0;
for (int r = 0; r < n_rep; ++r) {
int x = 0;
for (int i = 0; i < n_points; ++i) {
/// generate random number -1 or 1
int n = rand() % 3 - 1;
array[i*n_rep + r] = n;
x = x + n;
if (x < 0)
x = 0;
if (x > max_x)
max_x = x;
}
}
try
{
bitmap_image image(max_x * KOF_X, n_points * KOF_Y);
// set background to white
image.set_all_channels(255,255,255);
image_drawer draw(image);
draw.pen_width(1);
draw.pen_color(0,0,0); ///< black
for (int r = 0; r < n_rep; ++r) {
if (r == n_trace)
continue;
int x1 = 0;
for (int i = 0; i < n_points; ++i) {
int x2 = x1 + array[i*n_rep + r];
if (x2 < 0)
x2 = 0;
int y = (n_points - i - 1) * KOF_Y;
draw.line_segment(x1 * KOF_X, y, x2 * KOF_X, y);
x1 = x2;
}
}
draw.pen_color(255,0,0); ///< red
int x1 = 0;
for (int i = 0; i < n_points; ++i) {
int x2 = x1 + array[i*n_rep + n_trace];
if (x2 < 0)
x2 = 0;
int y = (n_points - i - 1) * KOF_Y;
draw.line_segment(x1 * KOF_X, y, x2 * KOF_X, y);
x1 = x2;
}
image.save_image(path);
}
catch(...)
{
std::cerr << "Error!\n";
}
delete [] array;
return 0;
}