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