fix general algo
This commit is contained in:
@ -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));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user