#generation #running #array #scratch #model #integer #simulation

generations

一个简单的Rust运行基于代数模拟的实用工具

3个稳定版本

2.0.0 2019年12月3日
1.0.1 2019年9月20日

#2099 in 算法

MPL-2.0 许可证

18KB
143

generations

Generations是一个运行基于代数模拟的实用工具库,例如康威生命游戏、其他细胞自动机遗传算法。其目的是使没有必要为每一代分配新的模型结构;相反,两个代数实例存储在Generations结构体中,其中一个是始终被认为是可见的“当前”代。

示例

在这个示例中,我们的系统是一个整数数组。随着每一代的后续,数组中的值是原始值及其两个邻居的和。为了简单起见,我们忽略第一个和最后一个元素。

例如

[0  1  0  1  1  -1 -1  0]
[0  1  2  2  1  -1 -2  0]
[0  3  5  5  2  -2 -3  0]
[0  8  13 12 5  -3 -5  0]
[0  21 33 30 14 -3 -8  0]
use generations::Generations;

// Our model type is a vector. Any type that implements the `Clearable`
// trait can be used as a model; this includes all std data structures.
let initial_state = vec![0, 1, 0, 1, 1, -1, -1, 0];

// A Generations instance stores our model, plus some scratch space to
// use as the next generation each step. When stepped, the new generation is
// written to this scratch space, which then becomes the current generation
// while the previous generation becomes the new scratch space.
let gens = Generations::new_defaulted(initial_state);

// A Simulation combines a Generations instance with a rule to apply with
// each step of the simulation
let mut sim = gens.with_rule(move |current_gen, next_gen| {
    if let Some(&first) = current_gen.first() {
        next_gen.push(first);
    }

    for window in current_gen.windows(3) {
        next_gen.push(window[0] + window[1] + window[2]);
    }

    if current_gen.len() > 1 {
        next_gen.push(*current_gen.last().unwrap())
    }
});

assert_eq!(sim.current(), &[0, 1, 0, 1, 1, -1, -1, 0]);
sim.step();
assert_eq!(sim.current(), &[0, 1, 2, 2, 1, -1, -2, 0]);
sim.step();
assert_eq!(sim.current(), &[0, 3, 5, 5, 2, -2, -3, 0]);
sim.step();
assert_eq!(sim.current(), &[0, 8, 13, 12, 5, -3, -5, 0]);
sim.step();
assert_eq!(sim.current(), &[0, 21, 33, 30, 14, -3, -8, 0]);

无运行时依赖