すべてのチャレンジ
中級 0件解決済み 正答率0%

One Generation of a Genetic Algorithm

Breed the next generation of bit strings with tournament selection, single-point crossover and mutation.

このチャレンジで学べること

  • Select parents with tournaments
  • Combine solutions with crossover
  • Add variation with mutation

問題

翻訳を表示

A genetic algorithm improves a population of candidate solutions the way evolution does: select fit parents, combine them, and add random mutations. Here the candidates are bit strings and fitness is the number of 1s (the OneMax problem).

To make it testable, every random choice is given. With N strings (N is even), build N children in pairs. For pair k = 0, 1, …, N/2 - 1:

  1. Selection: parent1 wins tournament tournaments[2k] and parent2 wins tournaments[2k + 1]. A tournament [i, j] is won by whichever of population[i] and population[j] has more 1s; on a tie, population[i] wins.
  2. Crossover at c = crossover_points[k]: child 2k = parent1[0:c] + parent2[c:] and child 2k + 1 = parent2[0:c] + parent1[c:].

Then apply each mutation [child, position] in order by flipping that bit of that child.

Implement ga_generation(population, tournaments, crossover_points, mutations).

Input

population: N bit strings of equal length L.

tournaments: N pairs of population indices.

crossover_points: N/2 cut points, each between 1 and L - 1.

mutations: [child, position] pairs (may be empty).

Output

Return the N children in order.

制約

2 ≤ N ≤ 200 (N even), 2 ≤ L ≤ 64

0 ≤ number of mutations ≤ 1,000

例

例 1
入力:
mutations = [
    [0, 0]
]
population = ["0000", "1111", "1100", "0011"]
tournaments = [
    [0, 1],
    [2, 3],
    [1, 2],
    [0, 3]
]
crossover_points = [2, 1]

期待される出力:
expected = ["0100", "1111", "1011", "0111"]
入力:
std::vector<std::vector<long long>> mutations = {
    {0, 0}
};
std::vector<std::string> population = {"0000", "1111", "1100", "0011"};
std::vector<std::vector<long long>> tournaments = {
    {0, 1},
    {2, 3},
    {1, 2},
    {0, 3}
};
std::vector<long long> crossover_points = {2, 1};

期待される出力:
std::vector<std::string> expected = {"0100", "1111", "1011", "0111"};
入力:
long[][] mutations = new long[][] {
    new long[] {0, 0}
};
string[] population = new string[] {"0000", "1111", "1100", "0011"};
long[][] tournaments = new long[][] {
    new long[] {0, 1},
    new long[] {2, 3},
    new long[] {1, 2},
    new long[] {0, 3}
};
long[] crossover_points = new long[] {2, 1};

期待される出力:
string[] expected = new string[] {"0100", "1111", "1011", "0111"};

解説

Pair 0: "1111" beats "0000", and "1100" ties "0011" so the first one wins. Cutting after 2 bits gives "1100" and "1111". Pair 1: parents "1111" and "0011", cut after 1 bit: "1011" and "0111". Finally child 0 has bit 0 flipped: "0100".

例 2
入力:
mutations = []
population = ["10", "01"]
tournaments = [
    [0, 1],
    [1, 0]
]
crossover_points = [1]

期待される出力:
expected = ["11", "00"]
入力:
std::vector<std::vector<long long>> mutations = {};
std::vector<std::string> population = {"10", "01"};
std::vector<std::vector<long long>> tournaments = {
    {0, 1},
    {1, 0}
};
std::vector<long long> crossover_points = {1};

期待される出力:
std::vector<std::string> expected = {"11", "00"};
入力:
long[][] mutations = new long[][] {};
string[] population = new string[] {"10", "01"};
long[][] tournaments = new long[][] {
    new long[] {0, 1},
    new long[] {1, 0}
};
long[] crossover_points = new long[] {1};

期待される出力:
string[] expected = new string[] {"11", "00"};

解説

Both strings have one 1, so each tournament is won by its first index: parent1 = "10" and parent2 = "01". Cutting after 1 bit gives "11" and "00".

参考資料

この課題はCodeUtility用に調整されています。上記の説明と制約に従ってください。

他の人の解答から学ぶ

コミュニティの解答

まだ公開された解答がありません。この課題を解いて最初の解答を共有しましょう。