โจทย์
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:
- Selection: parent1 wins tournament
tournaments[2k]and parent2 winstournaments[2k + 1]. A tournament[i, j]is won by whichever ofpopulation[i]andpopulation[j]has more 1s; on a tie,population[i]wins. - 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
ตัวอย่าง
อินพุต:
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".
อินพุต:
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".
แนวทางการแก้
ลองทำเองก่อน แล้วค่อยเปิดคำใบ้ทีละข้อ
คำใบ้ 1
Build children in pairs by first choosing two parents from each tournament, then combining their bit strings at one cut point.
คำใบ้ 2
Selection depends on fitness only, with ties always favoring the first contestant in the tournament pair.
คำใบ้ 3
Apply mutations after all children are created, and make sure each flip targets the current child string.
ความซับซ้อนที่คาดหวัง
O(N * L + M) time, O(N * L) extra space
แหล่งอ้างอิง
โจทย์นี้ปรับให้เหมาะกับ CodeUtility กรุณาทำตามคำชี้แจงและข้อจำกัดด้านบน