fix general algo
This commit is contained in:
@ -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];
|
||||||
|
// Safety check: ensure index is valid
|
||||||
|
if (idx >= 0 && idx < this.cells.length) {
|
||||||
group.push(this.cells[idx]);
|
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,29 +190,49 @@ 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 = [];
|
||||||
|
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]);
|
||||||
}
|
}
|
||||||
child[childIdx] = parent2[parent2Idx];
|
|
||||||
usedIndices.add(parent2[parent2Idx]);
|
|
||||||
childIdx = (childIdx + 1) % length;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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));
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user