-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtarget-ga.html
More file actions
92 lines (76 loc) · 2.57 KB
/
target-ga.html
File metadata and controls
92 lines (76 loc) · 2.57 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Target String GA</title>
<style>
body { font-family: sans-serif; padding: 20px; }
.gene { font-size: 24px; font-family: monospace; }
</style>
</head>
<body>
<h1>Target String Genetic Algorithm</h1>
<p>Target: <strong id="target"></strong></p>
<p>Generation: <span id="generation">0</span></p>
<p>Best Match: <span class="gene" id="best"></span></p>
<p>Fitness: <span id="fitness">0</span></p>
<script>
const target = "Hello, world!";
const populationSize = 200;
const mutationRate = 0.01;
const charset = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz,.!? ";
const geneLength = target.length;
document.getElementById("target").textContent = target;
function randomChar() {
return charset.charAt(Math.floor(Math.random() * charset.length));
}
function randomGene() {
return Array.from({ length: geneLength }, randomChar).join('');
}
function fitness(gene) {
let score = 0;
for (let i = 0; i < gene.length; i++) {
if (gene[i] === target[i]) score++;
}
return score / geneLength;
}
function crossover(parentA, parentB) {
const midpoint = Math.floor(Math.random() * geneLength);
let child = "";
for (let i = 0; i < geneLength; i++) {
child += (i < midpoint ? parentA[i] : parentB[i]);
}
return mutate(child);
}
function mutate(gene) {
return gene.split('').map(ch => Math.random() < mutationRate ? randomChar() : ch).join('');
}
let generation = 0;
let population = Array.from({ length: populationSize }, randomGene);
function evolve() {
generation++;
const sorted = population
.map(g => ({ gene: g, fit: fitness(g) }))
.sort((a, b) => b.fit - a.fit);
const best = sorted[0];
document.getElementById("generation").textContent = generation;
document.getElementById("best").textContent = best.gene;
document.getElementById("fitness").textContent = (best.fit * 100).toFixed(2) + "%";
if (best.gene === target) {
clearInterval(interval);
alert("Target reached in " + generation + " generations!");
return;
}
// Select top 20% as parents
const parents = sorted.slice(0, populationSize * 0.2).map(p => p.gene);
// Reproduce
population = Array.from({ length: populationSize }, () => {
const a = parents[Math.floor(Math.random() * parents.length)];
const b = parents[Math.floor(Math.random() * parents.length)];
return crossover(a, b);
});
}
const interval = setInterval(evolve, 50); // evolve every 50 ms
</script>
</body>
</html>