fix general algo

This commit is contained in:
2025-12-20 20:50:02 +01:00
parent d7557635ee
commit 12ffc48ffc

View File

@ -176,7 +176,13 @@ class GeneticAlgorithm {
const group = [];
for (let j = 0; j < this.parallel; j++) {
const idx = indices[i * this.parallel + j];
group.push(this.cells[idx]);
// Safety check: ensure index is valid
if (idx >= 0 && idx < this.cells.length) {
group.push(this.cells[idx]);
} else {
// Fallback: use a random valid cell
group.push(this.cells[Math.floor(Math.random() * this.cells.length)]);
}
}
configuration.push(group);
}
@ -184,31 +190,51 @@ class GeneticAlgorithm {
}
crossover(parent1, parent2) {
// Simple two-point crossover with repair
const length = parent1.length;
const start = Math.floor(Math.random() * length);
const end = start + Math.floor(Math.random() * (length - start));
const child = new Array(length).fill(-1);
const usedIndices = new Set();
for (let i = start; i <= end; i++) {
child[i] = parent1[i];
usedIndices.add(parent1[i]);
// 50% chance to just return a copy of one parent (with shuffle)
if (Math.random() < 0.5) {
const child = [...parent1];
// Swap a few random positions
for (let i = 0; i < 2; i++) {
const a = Math.floor(Math.random() * length);
const b = Math.floor(Math.random() * length);
[child[a], child[b]] = [child[b], child[a]];
}
return child;
}
let childIdx = (end + 1) % length;
for (let i = 0; i < length; i++) {
const parent2Idx = (end + 1 + i) % length;
if (!usedIndices.has(parent2[parent2Idx])) {
while (child[childIdx] !== -1) {
childIdx = (childIdx + 1) % length;
}
child[childIdx] = parent2[parent2Idx];
usedIndices.add(parent2[parent2Idx]);
childIdx = (childIdx + 1) % length;
// Otherwise, take half from each parent and repair duplicates
const midpoint = Math.floor(length / 2);
const child = [...parent1.slice(0, midpoint), ...parent2.slice(midpoint)];
// Find and fix duplicates
const seen = new Set();
const duplicatePositions = [];
const allIndices = new Set(parent1.concat(parent2));
for (let i = 0; i < child.length; i++) {
if (seen.has(child[i])) {
duplicatePositions.push(i);
} else {
seen.add(child[i]);
}
}
// Find missing indices
const missing = [];
for (const idx of allIndices) {
if (!seen.has(idx)) {
missing.push(idx);
}
}
// Replace duplicates with missing values
for (let i = 0; i < duplicatePositions.length && i < missing.length; i++) {
child[duplicatePositions[i]] = missing[i];
}
return child;
}
@ -276,6 +302,12 @@ class GeneticAlgorithm {
let child = this.crossover(parent1.indices, parent2.indices);
// Safety: ensure all indices are valid
child = child.map(idx => {
if (idx >= 0 && idx < this.cells.length) return idx;
return Math.floor(Math.random() * this.cells.length);
});
const usedLabels = new Set(child.map(idx => this.cells[idx].label));
const unusedCells = this.cells.filter(c => !usedLabels.has(c.label));