优化算法:提高随机性

pull/664/head
ChenX 5 years ago
parent 6152cded4e
commit 3f891398c7

@ -122,6 +122,7 @@ export class Container
if (area < minArea || if (area < minArea ||
((equaln(area, minArea, 1)) ((equaln(area, minArea, 1))
&& (p.x < translate.x || (p.x === translate.x && p.y < translate.y)))) && (p.x < translate.x || (p.x === translate.x && p.y < translate.y))))
// && (p.y < translate.y || (p.y === translate.y && p.x < translate.x))))
// && (this.BinPath.Size.x > this.BinPath.Size.y ? p.x < translate.x : p.y < translate.y))) // && (this.BinPath.Size.x > this.BinPath.Size.y ? p.x < translate.x : p.y < translate.y)))
{ {
translate = p; translate = p;
@ -138,6 +139,7 @@ export class Container
if (area < minArea || if (area < minArea ||
((equaln(area, minArea, 1)) ((equaln(area, minArea, 1))
&& (p.x < translate.x || (p.x === translate.x && p.y < translate.y)))) && (p.x < translate.x || (p.x === translate.x && p.y < translate.y))))
// && (p.y < translate.y || (p.y === translate.y && p.x < translate.x))))
// && (this.BinPath.Size.x > this.BinPath.Size.y ? p.x < translate.x : p.y < translate.y))) // && (this.BinPath.Size.x > this.BinPath.Size.y ? p.x < translate.x : p.y < translate.y)))
{ {
translate = p; translate = p;

@ -98,6 +98,10 @@ export function ConverBoard2Part(board: Board, knifRadius = 3.5): Part
let [, pts] = Curves2Points(board.ContourCurve as Polyline, true, knifRadius); let [, pts] = Curves2Points(board.ContourCurve as Polyline, true, knifRadius);
arrayRemoveDuplicateBySort(pts, (p1, p2) => equalv2(p1, p2, 1e-2)); arrayRemoveDuplicateBySort(pts, (p1, p2) => equalv2(p1, p2, 1e-2));
path = new Path(pts); path = new Path(pts);
let area = path.BoundingBox.area - path.Area;
if (area < 15000 && pts.length > 6)
path = NestCache.CreatePath(board.Width, board.Height, knifRadius);
} }
part.Init2(path, DefaultBin, Rotations[board.BoardProcessOption.lines]); part.Init2(path, DefaultBin, Rotations[board.BoardProcessOption.lines]);
for (let m of board.BoardModeling) for (let m of board.BoardModeling)
@ -106,7 +110,10 @@ export function ConverBoard2Part(board: Board, knifRadius = 3.5): Part
{ {
let [, pts] = Curves2Points(m.shape.Outline.Curve, false, knifRadius); let [, pts] = Curves2Points(m.shape.Outline.Curve, false, knifRadius);
part.UserData.push(m.shape.Outline.Curve.Clone()); part.UserData.push(m.shape.Outline.Curve.Clone());
part.AppendHole(new Path(pts));
let path = new Path(pts);
if (path.Area > 15000)
part.AppendHole(path);
} }
} }

@ -35,7 +35,7 @@ export class Individual
*/ */
Mutate() Mutate()
{ {
if (this.mutationRate > 0.6) if (this.mutationRate > 0.5)
for (let i = 0; i < this.Parts.length; i++) for (let i = 0; i < this.Parts.length; i++)
{ {
let rand = Math.random(); let rand = Math.random();
@ -47,25 +47,32 @@ export class Individual
[this.Parts[i], this.Parts[j]] = [this.Parts[j], this.Parts[i]]; [this.Parts[i], this.Parts[j]] = [this.Parts[j], this.Parts[i]];
} }
if (rand < this.mutationRate) if (rand < this.mutationRate)
{
this.Parts[i].Mutate(); this.Parts[i].Mutate();
break;
}
} }
else
//洗牌
let rand = Math.random();
if (rand < 0.5)
{ {
let index = RandomIndex(this.Parts.length - 2); //洗牌
let count = Math.ceil(RandomIndex(this.Parts.length - 2 - index) * this.mutationRate * 2) || 1; let rand = Math.random();
let parts = this.Parts.splice(index, count); if (rand < 0.5)
this.Parts.push(...parts); {
let index = RandomIndex(this.Parts.length - 2);
let count = Math.ceil(RandomIndex(this.Parts.length - 2 - index) * this.mutationRate * 2) || 1;
let parts = this.Parts.splice(index, count);
this.Parts.push(...parts);
this.Parts[index].Mutate();
}
else
for (let i = 0; i < this.Parts.length; i++)
{
let rand = Math.random();
if (rand < this.mutationRate)
{
this.Parts[i].Mutate();
i += 5;
}
}
} }
let index = RandomIndex(this.Parts.length);
this.Parts[index].Mutate();
if (this.mutationRate > 0.2) if (this.mutationRate > 0.2)
this.mutationRate -= 0.004; this.mutationRate -= 0.004;
return this; return this;

@ -57,7 +57,14 @@ export class OptimizeMachine
{ {
let parts = this.Parts.map(p => p.Clone()); let parts = this.Parts.map(p => p.Clone());
if (i < 3) if (i < 3)
ShuffleArray(parts); {
for (let i = parts.length - 1; i > 0; i--)
{
const j = Math.floor(Math.random() * (i + 1));
[parts[i], parts[j]] = [parts[j], parts[i]];
parts[i].Mutate();
}
}
this._Individuals.push(new Individual(parts, 0.8)); this._Individuals.push(new Individual(parts, 0.8));
} }
//2.执行 //2.执行
@ -82,7 +89,7 @@ export class OptimizeMachine
if (globalThis.document || !clipperCpp.lib) if (globalThis.document || !clipperCpp.lib)
await Sleep(0); await Sleep(0);
let p = this._Individuals[i]; let p = this._Individuals[i];
if (this.calcCount < 2000 || this.calcCount % 1000 === 0) if (this.calcCount < 1000 || this.calcCount % 1000 === 0)
p.Evaluate(this.Bin, this.best, true, i % 2); p.Evaluate(this.Bin, this.best, true, i % 2);
else else
p.Evaluate(this.Bin, this.best); p.Evaluate(this.Bin, this.best);
@ -118,8 +125,9 @@ export class OptimizeMachine
//自然选择 //自然选择
this._Individuals.splice(-10);//杀死它 this._Individuals.splice(-10);//杀死它
for (let i = 0; i < 5; i++) for (let i = 0; i < 4; i++)
this._Individuals.push(bestP.Clone()); this._Individuals.push(bestP.Clone());
this._Individuals.push(this.bestP.Clone());
for (let i = 0; i < 3; i++) for (let i = 0; i < 3; i++)
this._Individuals.push(this._Individuals[1].Clone()); this._Individuals.push(this._Individuals[1].Clone());
for (let i = 0; i < 2; i++) for (let i = 0; i < 2; i++)

@ -2,8 +2,7 @@ import { FixIndex } from "./Util";
export function RandomIndex(count: number, exclude?: number): number export function RandomIndex(count: number, exclude?: number): number
{ {
let r = Math.random(); let index = Math.floor(Math.random() * count);
let index = Math.floor(r * count);
if (index === count) index = 0; if (index === count) index = 0;
if (index === exclude) index = FixIndex(index + 1, count); if (index === exclude) index = FixIndex(index + 1, count);
return index; return index;

@ -202,7 +202,7 @@ export class Command_TestYHWorker implements Command
} }
}, "应用优化"); }, "应用优化");
}; };
for (let i = 0; i < navigator.hardwareConcurrency - 2; i++)// || for (let i = 0; i < navigator.hardwareConcurrency / 2; i++)// ||
{ {
let w = new Worker; let w = new Worker;
workers.push(w); workers.push(w);

Loading…
Cancel
Save