Data update
This commit is contained in:
parent
4d5544505c
commit
4924dd0264
3073 changed files with 55820 additions and 4408 deletions
114
Task/Evolutionary-algorithm/Zig/evolutionary-algorithm.zig
Normal file
114
Task/Evolutionary-algorithm/Zig/evolutionary-algorithm.zig
Normal file
|
|
@ -0,0 +1,114 @@
|
|||
const std = @import("std");
|
||||
const math = std.math;
|
||||
const print = std.debug.print;
|
||||
|
||||
pub fn main() !void {
|
||||
const target = "METHINKS IT IS LIKE A WEASEL";
|
||||
const copies: usize = 100;
|
||||
const mutation_rate: u32 = 20; // 1/20 = 0.05 = 5%
|
||||
|
||||
var prng = std.Random.DefaultPrng.init(@as(u64, @intCast(std.time.milliTimestamp())));
|
||||
const rng = prng.random();
|
||||
|
||||
// Generate first sentence, mutating each character
|
||||
const start = try mutate(rng, target, 1, std.heap.page_allocator); // 1/1 = 1 = 100%
|
||||
|
||||
print("{s}\n", .{target});
|
||||
print("{s}\n", .{start});
|
||||
|
||||
_ = try evolve(rng, target, start, copies, mutation_rate, std.heap.page_allocator);
|
||||
}
|
||||
|
||||
/// Evolution algorithm
|
||||
///
|
||||
/// Evolves `parent` to match `target`. Returns the number of evolutions performed.
|
||||
fn evolve(
|
||||
rng: std.Random,
|
||||
target: []const u8,
|
||||
parent: []const u8,
|
||||
copies: usize,
|
||||
mutation_rate: u32,
|
||||
allocator: std.mem.Allocator,
|
||||
) !usize {
|
||||
var counter: usize = 0;
|
||||
var parent_fitness: usize = target.len + 1;
|
||||
var current_parent = try allocator.dupe(u8, parent);
|
||||
defer allocator.free(current_parent);
|
||||
|
||||
while (true) {
|
||||
counter += 1;
|
||||
|
||||
var best_fitness: usize = std.math.maxInt(usize);
|
||||
const best_sentence = try allocator.alloc(u8, target.len);
|
||||
|
||||
for (0..copies) |_| {
|
||||
// Copy and mutate a new sentence
|
||||
const sentence = try mutate(rng, current_parent, mutation_rate, allocator);
|
||||
defer allocator.free(sentence);
|
||||
|
||||
// Find the fitness of the new mutation
|
||||
const current_fitness = fitness(target, sentence);
|
||||
|
||||
if (current_fitness < best_fitness) {
|
||||
best_fitness = current_fitness;
|
||||
@memcpy( best_sentence, sentence);
|
||||
}
|
||||
}
|
||||
|
||||
// If the best mutation of this generation is better than `parent` then "the fittest
|
||||
// survives" and the next parent becomes the best of this generation.
|
||||
if (best_fitness < parent_fitness) {
|
||||
allocator.free(current_parent);
|
||||
current_parent = best_sentence;
|
||||
parent_fitness = best_fitness;
|
||||
print("{s} : generation {} with fitness {}\n", .{ current_parent, counter, best_fitness });
|
||||
|
||||
if (best_fitness == 0) {
|
||||
return counter;
|
||||
}
|
||||
} else {
|
||||
allocator.free(best_sentence);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Computes the fitness of a sentence against a target string, returning the number of
|
||||
/// incorrect characters.
|
||||
fn fitness(target: []const u8, sentence: []const u8) usize {
|
||||
var count: usize = 0;
|
||||
for (sentence, 0..) |c, i| {
|
||||
if (c != target[i]) {
|
||||
count += 1;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
/// Mutation algorithm.
|
||||
///
|
||||
/// It mutates each character of a string, according to a `mutation_rate`.
|
||||
fn mutate(
|
||||
rng: std.Random,
|
||||
sentence: []const u8,
|
||||
mutation_rate: u32,
|
||||
allocator: std.mem.Allocator,
|
||||
) ![]u8 {
|
||||
var result = try allocator.alloc(u8, sentence.len);
|
||||
|
||||
for (sentence, 0..) |c, i| {
|
||||
if (rng.int(u32) % mutation_rate == 0) {
|
||||
result[i] = randomChar(rng);
|
||||
} else {
|
||||
result[i] = c;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// Generates a random letter or space.
|
||||
fn randomChar(rng: std.Random) u8 {
|
||||
// Returns a value in the range [A, Z] + an extra slot for the space character.
|
||||
const c = rng.intRangeAtMost(u8, 'A', 'Z' + 1);
|
||||
return if (c == 'Z' + 1) ' ' else c;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue