Files
KSP-MGA-Planner/dist/main/solvers/sequence-solver.js
2022-07-21 19:14:48 +02:00

61 lines
2.7 KiB
JavaScript

import { WorkerManager } from "../utilities/worker.js";
import { shuffleArray } from "../utilities/array.js";
import { FlybySequence } from "./sequence.js";
export class FlybySequenceGenerator {
constructor(system, config) {
this.system = system;
this.config = config;
this.totalFeasible = 0;
this._evaluationPool = WorkerManager.getPool("sequence-evaluator");
this._evaluationPool.initialize({ system: this.system.data, config: this.config });
this._sequenceWorker = WorkerManager.getWorker("sequence-generator");
this._sequenceWorker.initialize(this.config);
}
cancel() { this._evaluationPool.cancel(); }
get progression() {
return this._evaluationPool.totalProgress;
}
async generateFlybySequences(params, onProgress) {
const toHigherOrbit = params.destinationId > params.departureId;
const departureBody = this.system.bodyFromId(params.departureId);
const allowedBodies = this._getAllowedBodies(departureBody, params, toHigherOrbit);
const feasibleSet = await this._generateFeasibleSet(allowedBodies, params);
this.totalFeasible = feasibleSet.length;
const evaluations = await this._evaluateSequences(feasibleSet, onProgress);
evaluations.sort((a, b) => a.cost - b.cost);
const { maxPropositions } = this.config.flybySequence;
const sequences = [];
for (let i = 0; i < Math.min(maxPropositions, evaluations.length); i++) {
const result = evaluations[i];
const sequence = new FlybySequence(this.system, feasibleSet[result.seq]);
sequences.push(sequence);
}
return sequences;
}
_getAllowedBodies(departureBody, params, toHigherOrbit) {
const allowedBodies = [];
for (const body of departureBody.attractor.orbiters) {
if ((toHigherOrbit && body.id <= params.destinationId) ||
(!toHigherOrbit && body.id >= params.destinationId)) {
allowedBodies.push(body.id);
}
}
return allowedBodies;
}
_generateFeasibleSet(allowedBodies, params) {
return this._sequenceWorker.run({ bodies: allowedBodies, params: params });
}
async _evaluateSequences(sequences, onProgress) {
shuffleArray(sequences);
const { splitLimit } = this.config.flybySequence;
const costs = await this._evaluationPool.runPoolChunked(sequences, splitLimit, onProgress);
const evaluations = [];
for (let i = 0; i < sequences.length; i++) {
if (costs[i] != undefined) {
evaluations.push({ seq: i, cost: costs[i] });
}
}
return evaluations;
}
}