Pārlūkot izejas kodu

gov: pareto front

ignore configurations that are worse than ones on the pareto front
raylu 1 nedēļu atpakaļ
vecāks
revīzija
c111e48ee4
1 mainītis faili ar 24 papildinājumiem un 5 dzēšanām
  1. 24 5
      ts/gov.ts

+ 24 - 5
ts/gov.ts

@@ -163,13 +163,12 @@ async function _render(planetName: string, pop: Pop) {
 	</table>
 
 	<h2>options</h2>
-	current ${pop} happiness: ${formatPct(projectedHappiness(pop, totalNeeds, siteCount, currentPOPIFilled))}
+	current projected ${pop} happiness: ${formatPct(projectedHappiness(pop, totalNeeds, siteCount, currentPOPIFilled))}
 	<table>
-	${[...popiFillCombinations(currentPOPIFilled)].map((combination) => {
-		const happiness = projectedHappiness(pop, totalNeeds, siteCount, combination);
+	${paretoFront(pop, totalNeeds, siteCount, currentPOPIFilled).map((result) => {
 		return `<tr>
-			<td>${[...combination.entries()].map(([building, fill]) => `${building}: ${fill.numMats}`).join(', ')}</td>
-			<td>${formatPct(happiness)}</td>
+			<td>${[...result.config.entries()].map(([building, fill]) => `${building}: ${fill.numMats}`).join(', ')}</td>
+			<td>${formatPct(result.happiness)}</td>
 		</tr>`;
 	}).join('')}
 	</table>
@@ -225,6 +224,26 @@ function calcPOPIFilled(infra: Infrastructure): number | null {
 	return filled;
 }
 
+function paretoFront(pop: Pop, totalNeeds: Record<Need, number>, siteCount: number, currentPOPIFilled: POPIFill):
+		{config: POPIFill, happiness: number, cost: number}[] {
+	const results: {config: POPIFill, happiness: number, cost: number}[] = [];
+	for (const config of popiFillCombinations(currentPOPIFilled)) {
+		const happiness = projectedHappiness(pop, totalNeeds, siteCount, config);
+		let cost = config.values().reduce((sum, fill) => sum + fill.numMats * fill.tier, 0); // TODO
+		// is any result better than this one?
+		if (results.some((result) => (result.happiness >= happiness && result.cost < cost) ||
+				(result.happiness > happiness && result.cost <= cost)))
+			continue;
+		// are any results worse than this one?
+		for (let i = results.length - 1; i >= 0; i--)
+			if ((results[i].happiness <= happiness && results[i].cost > cost) ||
+					(results[i].happiness < happiness && results[i].cost >= cost))
+				results.splice(i, 1);
+		results.push({config, happiness, cost});
+	}
+	return results;
+}
+
 function* popiFillCombinations(currentPOPIFilled: POPIFill): Generator<POPIFill> {
 	const entries = [...currentPOPIFilled.keys()];
 	function* helper(index: number, current: POPIFill): Generator<POPIFill> {