@tscircuit/capacity-autorouter 0.0.62 → 0.0.63
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +135 -1
- package/dist/index.js +584 -136
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -3721,8 +3721,54 @@ function seededRandom(seed) {
|
|
|
3721
3721
|
return result - Math.floor(result);
|
|
3722
3722
|
};
|
|
3723
3723
|
}
|
|
3724
|
+
var PRESHUFFLED_CASES = {
|
|
3725
|
+
1: [[0]],
|
|
3726
|
+
2: [
|
|
3727
|
+
[0, 1],
|
|
3728
|
+
[1, 0]
|
|
3729
|
+
],
|
|
3730
|
+
3: [
|
|
3731
|
+
[0, 1, 2],
|
|
3732
|
+
[2, 0, 1],
|
|
3733
|
+
[1, 0, 2],
|
|
3734
|
+
[0, 2, 1],
|
|
3735
|
+
[1, 2, 0],
|
|
3736
|
+
[2, 1, 0]
|
|
3737
|
+
],
|
|
3738
|
+
4: [
|
|
3739
|
+
[0, 1, 2, 3],
|
|
3740
|
+
[2, 0, 1, 3],
|
|
3741
|
+
[1, 3, 2, 0],
|
|
3742
|
+
[3, 0, 1, 2],
|
|
3743
|
+
[0, 2, 1, 3],
|
|
3744
|
+
[2, 1, 3, 0],
|
|
3745
|
+
[3, 0, 2, 1],
|
|
3746
|
+
[1, 2, 0, 3],
|
|
3747
|
+
[3, 1, 0, 2],
|
|
3748
|
+
[0, 3, 2, 1],
|
|
3749
|
+
[2, 3, 0, 1],
|
|
3750
|
+
[2, 3, 1, 0],
|
|
3751
|
+
[1, 2, 3, 0],
|
|
3752
|
+
[3, 1, 2, 0],
|
|
3753
|
+
[0, 1, 3, 2],
|
|
3754
|
+
[0, 2, 3, 1],
|
|
3755
|
+
[0, 3, 1, 2],
|
|
3756
|
+
[1, 0, 2, 3],
|
|
3757
|
+
[1, 0, 3, 2],
|
|
3758
|
+
[1, 3, 0, 2],
|
|
3759
|
+
[2, 0, 3, 1],
|
|
3760
|
+
[2, 1, 0, 3],
|
|
3761
|
+
[3, 2, 0, 1],
|
|
3762
|
+
[3, 2, 1, 0]
|
|
3763
|
+
]
|
|
3764
|
+
};
|
|
3724
3765
|
function cloneAndShuffleArray(arr, seed) {
|
|
3725
3766
|
if (seed === 0) return arr;
|
|
3767
|
+
if (arr.length <= 4) {
|
|
3768
|
+
const preshuffledOptions = PRESHUFFLED_CASES[arr.length];
|
|
3769
|
+
const preshuffledCase = preshuffledOptions[seed % preshuffledOptions.length];
|
|
3770
|
+
return preshuffledCase.map((orderIndex) => arr[orderIndex]);
|
|
3771
|
+
}
|
|
3726
3772
|
const random = seededRandom(seed);
|
|
3727
3773
|
const shuffled = arr.slice();
|
|
3728
3774
|
for (let i = 0; i < shuffled.length; i++) {
|
|
@@ -10937,6 +10983,8 @@ import objectHash from "object-hash";
|
|
|
10937
10983
|
|
|
10938
10984
|
// lib/cache/InMemoryCache.ts
|
|
10939
10985
|
var InMemoryCache = class {
|
|
10986
|
+
cacheHitsByPrefix = {};
|
|
10987
|
+
cacheMissesByPrefix = {};
|
|
10940
10988
|
isSyncCache = true;
|
|
10941
10989
|
cacheHits = 0;
|
|
10942
10990
|
cacheMisses = 0;
|
|
@@ -11002,6 +11050,8 @@ var LocalStorageCache = class {
|
|
|
11002
11050
|
isSyncCache = true;
|
|
11003
11051
|
cacheHits = 0;
|
|
11004
11052
|
cacheMisses = 0;
|
|
11053
|
+
cacheHitsByPrefix = {};
|
|
11054
|
+
cacheMissesByPrefix = {};
|
|
11005
11055
|
constructor() {
|
|
11006
11056
|
if (typeof localStorage === "undefined") {
|
|
11007
11057
|
console.warn(
|
|
@@ -11026,14 +11076,20 @@ var LocalStorageCache = class {
|
|
|
11026
11076
|
if (cachedItem !== null) {
|
|
11027
11077
|
const solution = JSON.parse(cachedItem);
|
|
11028
11078
|
this.cacheHits++;
|
|
11079
|
+
const prefix = cacheKey.split(":")[0];
|
|
11080
|
+
this.cacheHitsByPrefix[prefix] = (this.cacheHitsByPrefix[prefix] || 0) + 1;
|
|
11029
11081
|
return solution;
|
|
11030
11082
|
} else {
|
|
11031
11083
|
this.cacheMisses++;
|
|
11084
|
+
const prefix = cacheKey.split(":")[0];
|
|
11085
|
+
this.cacheMissesByPrefix[prefix] = (this.cacheMissesByPrefix[prefix] || 0) + 1;
|
|
11032
11086
|
return void 0;
|
|
11033
11087
|
}
|
|
11034
11088
|
} catch (error) {
|
|
11035
11089
|
console.error(`Error getting cached solution sync for ${key}:`, error);
|
|
11036
11090
|
this.cacheMisses++;
|
|
11091
|
+
const prefix = cacheKey.split(":")[0];
|
|
11092
|
+
this.cacheMissesByPrefix[prefix] = (this.cacheMissesByPrefix[prefix] || 0) + 1;
|
|
11037
11093
|
return void 0;
|
|
11038
11094
|
}
|
|
11039
11095
|
}
|
|
@@ -11098,6 +11154,8 @@ var LocalStorageCache = class {
|
|
|
11098
11154
|
} finally {
|
|
11099
11155
|
this.cacheHits = 0;
|
|
11100
11156
|
this.cacheMisses = 0;
|
|
11157
|
+
this.cacheHitsByPrefix = {};
|
|
11158
|
+
this.cacheMissesByPrefix = {};
|
|
11101
11159
|
}
|
|
11102
11160
|
}
|
|
11103
11161
|
getAllCacheKeys() {
|
|
@@ -11119,6 +11177,12 @@ function getGlobalLocalStorageCache() {
|
|
|
11119
11177
|
}
|
|
11120
11178
|
return globalThis.TSCIRCUIT_AUTOROUTER_LOCAL_STORAGE_CACHE;
|
|
11121
11179
|
}
|
|
11180
|
+
function getGlobalInMemoryCache() {
|
|
11181
|
+
if (!globalThis.TSCIRCUIT_AUTOROUTER_IN_MEMORY_CACHE) {
|
|
11182
|
+
setupGlobalCaches();
|
|
11183
|
+
}
|
|
11184
|
+
return globalThis.TSCIRCUIT_AUTOROUTER_IN_MEMORY_CACHE;
|
|
11185
|
+
}
|
|
11122
11186
|
function setupGlobalCaches() {
|
|
11123
11187
|
globalThis.TSCIRCUIT_AUTOROUTER_LOCAL_STORAGE_CACHE ??= new LocalStorageCache();
|
|
11124
11188
|
globalThis.TSCIRCUIT_AUTOROUTER_IN_MEMORY_CACHE ??= new InMemoryCache();
|
|
@@ -12521,6 +12585,21 @@ var calculateNodeProbabilityOfFailure2 = (usedCapacity, totalCapacity, layerCoun
|
|
|
12521
12585
|
const adjustedRatio = ratioOverTotal - 1;
|
|
12522
12586
|
return 1 - Math.exp(-k * adjustedRatio);
|
|
12523
12587
|
};
|
|
12588
|
+
var calculateSingleNodeLogSuccessProbability = (usedCapacity, totalCapacity, node) => {
|
|
12589
|
+
if (node._containsTarget) return 0;
|
|
12590
|
+
if (usedCapacity <= totalCapacity) return 0;
|
|
12591
|
+
const probabilityOfFailure = calculateNodeProbabilityOfFailure2(
|
|
12592
|
+
usedCapacity,
|
|
12593
|
+
totalCapacity,
|
|
12594
|
+
node.availableZ.length
|
|
12595
|
+
);
|
|
12596
|
+
const probabilityOfSuccess = 1 - probabilityOfFailure;
|
|
12597
|
+
if (probabilityOfSuccess <= 0) {
|
|
12598
|
+
return -1e9;
|
|
12599
|
+
} else {
|
|
12600
|
+
return Math.log(probabilityOfSuccess);
|
|
12601
|
+
}
|
|
12602
|
+
};
|
|
12524
12603
|
var computeSectionScore = ({
|
|
12525
12604
|
totalNodeCapacityMap,
|
|
12526
12605
|
usedNodeCapacityMap,
|
|
@@ -12534,21 +12613,13 @@ var computeSectionScore = ({
|
|
|
12534
12613
|
if (!totalNodeCapacityMap.has(nodeId)) continue;
|
|
12535
12614
|
const node = nodeMap.get(nodeId);
|
|
12536
12615
|
if (!node) continue;
|
|
12537
|
-
if (node._containsTarget) continue;
|
|
12538
12616
|
const totalCapacity = totalNodeCapacityMap.get(nodeId);
|
|
12539
12617
|
const usedCapacity = usedNodeCapacityMap.get(nodeId) ?? 0;
|
|
12540
|
-
|
|
12541
|
-
const probabilityOfFailure = calculateNodeProbabilityOfFailure2(
|
|
12618
|
+
logProbabilityOfSuccessSum += calculateSingleNodeLogSuccessProbability(
|
|
12542
12619
|
usedCapacity,
|
|
12543
12620
|
totalCapacity,
|
|
12544
|
-
node
|
|
12621
|
+
node
|
|
12545
12622
|
);
|
|
12546
|
-
const probabilityOfSuccess = 1 - probabilityOfFailure;
|
|
12547
|
-
if (probabilityOfSuccess <= 0) {
|
|
12548
|
-
logProbabilityOfSuccessSum += -1e9;
|
|
12549
|
-
} else {
|
|
12550
|
-
logProbabilityOfSuccessSum += Math.log(probabilityOfSuccess);
|
|
12551
|
-
}
|
|
12552
12623
|
}
|
|
12553
12624
|
return logProbabilityOfSuccessSum;
|
|
12554
12625
|
};
|
|
@@ -12729,9 +12800,9 @@ ${percent}% (Pf: ${(probabilityOfFailure * 100).toFixed(1)}%)`;
|
|
|
12729
12800
|
x: x + offset.x,
|
|
12730
12801
|
y: y + offset.y
|
|
12731
12802
|
})),
|
|
12732
|
-
strokeColor: safeTransparentize(pathColor, 0.2)
|
|
12803
|
+
strokeColor: safeTransparentize(pathColor, 0.2)
|
|
12733
12804
|
// Make solved paths semi-transparent
|
|
12734
|
-
strokeWidth: 0.03
|
|
12805
|
+
// strokeWidth: 0.03,
|
|
12735
12806
|
});
|
|
12736
12807
|
}
|
|
12737
12808
|
});
|
|
@@ -12739,6 +12810,72 @@ ${percent}% (Pf: ${(probabilityOfFailure * 100).toFixed(1)}%)`;
|
|
|
12739
12810
|
return graphics;
|
|
12740
12811
|
}
|
|
12741
12812
|
|
|
12813
|
+
// lib/solvers/CapacityPathingSectionSolver/computeSectionNodesTerminalsAndEdges.ts
|
|
12814
|
+
var computeSectionNodesTerminalsAndEdges = (opts) => {
|
|
12815
|
+
const {
|
|
12816
|
+
centerNodeId,
|
|
12817
|
+
connectionsWithNodes,
|
|
12818
|
+
nodeMap,
|
|
12819
|
+
edges,
|
|
12820
|
+
nodeEdgeMap,
|
|
12821
|
+
expansionDegrees
|
|
12822
|
+
} = opts;
|
|
12823
|
+
const sectionNodeIds = /* @__PURE__ */ new Set();
|
|
12824
|
+
const queue = [
|
|
12825
|
+
{ nodeId: centerNodeId, depth: 0 }
|
|
12826
|
+
];
|
|
12827
|
+
sectionNodeIds.add(centerNodeId);
|
|
12828
|
+
let head = 0;
|
|
12829
|
+
while (head < queue.length) {
|
|
12830
|
+
const { nodeId, depth } = queue[head++];
|
|
12831
|
+
if (depth >= expansionDegrees) continue;
|
|
12832
|
+
const neighbors = nodeEdgeMap.get(nodeId)?.flatMap((edge) => edge.nodeIds.filter((id) => id !== nodeId)) ?? [];
|
|
12833
|
+
for (const neighborId of neighbors) {
|
|
12834
|
+
if (!sectionNodeIds.has(neighborId)) {
|
|
12835
|
+
sectionNodeIds.add(neighborId);
|
|
12836
|
+
queue.push({ nodeId: neighborId, depth: depth + 1 });
|
|
12837
|
+
}
|
|
12838
|
+
}
|
|
12839
|
+
}
|
|
12840
|
+
const sectionNodes = Array.from(sectionNodeIds).map((id) => nodeMap.get(id));
|
|
12841
|
+
const sectionEdges = edges.filter((edge) => {
|
|
12842
|
+
const [nodeIdA, nodeIdB] = edge.nodeIds;
|
|
12843
|
+
return sectionNodeIds.has(nodeIdA) && sectionNodeIds.has(nodeIdB);
|
|
12844
|
+
});
|
|
12845
|
+
const sectionConnectionTerminals = [];
|
|
12846
|
+
for (const conn of connectionsWithNodes) {
|
|
12847
|
+
if (!conn.path) continue;
|
|
12848
|
+
let startNodeId = null;
|
|
12849
|
+
let endNodeId = null;
|
|
12850
|
+
for (const node of conn.path) {
|
|
12851
|
+
if (sectionNodeIds.has(node.capacityMeshNodeId)) {
|
|
12852
|
+
startNodeId = node.capacityMeshNodeId;
|
|
12853
|
+
break;
|
|
12854
|
+
}
|
|
12855
|
+
}
|
|
12856
|
+
for (let i = conn.path.length - 1; i >= 0; i--) {
|
|
12857
|
+
const node = conn.path[i];
|
|
12858
|
+
if (sectionNodeIds.has(node.capacityMeshNodeId)) {
|
|
12859
|
+
endNodeId = node.capacityMeshNodeId;
|
|
12860
|
+
break;
|
|
12861
|
+
}
|
|
12862
|
+
}
|
|
12863
|
+
if (startNodeId && endNodeId) {
|
|
12864
|
+
sectionConnectionTerminals.push({
|
|
12865
|
+
connectionName: conn.connection.name,
|
|
12866
|
+
startNodeId,
|
|
12867
|
+
endNodeId
|
|
12868
|
+
});
|
|
12869
|
+
}
|
|
12870
|
+
}
|
|
12871
|
+
return {
|
|
12872
|
+
sectionConnectionTerminals,
|
|
12873
|
+
sectionNodes,
|
|
12874
|
+
sectionEdges,
|
|
12875
|
+
centerNodeId
|
|
12876
|
+
};
|
|
12877
|
+
};
|
|
12878
|
+
|
|
12742
12879
|
// lib/solvers/CapacityPathingSectionSolver/CapacityPathingSingleSectionSolver.ts
|
|
12743
12880
|
var CapacityPathingSingleSectionSolver = class extends BaseSolver {
|
|
12744
12881
|
GREEDY_MULTIPLIER = 1.5;
|
|
@@ -12752,7 +12889,10 @@ var CapacityPathingSingleSectionSolver = class extends BaseSolver {
|
|
|
12752
12889
|
colorMap;
|
|
12753
12890
|
usedNodeCapacityMap;
|
|
12754
12891
|
// Tracks capacity usage *within this solver's run*
|
|
12892
|
+
totalNodeCapacityMap;
|
|
12893
|
+
// Added: Stores total capacity for each node
|
|
12755
12894
|
centerNodeId;
|
|
12895
|
+
currentSectionScore = 0;
|
|
12756
12896
|
MAX_CANDIDATES_IN_MEMORY = 1e4;
|
|
12757
12897
|
// A* state
|
|
12758
12898
|
currentConnectionIndex = 0;
|
|
@@ -12773,14 +12913,28 @@ var CapacityPathingSingleSectionSolver = class extends BaseSolver {
|
|
|
12773
12913
|
this.sectionConnectionTerminals = params.sectionConnectionTerminals.map(
|
|
12774
12914
|
(t) => ({ ...t, path: void 0 })
|
|
12775
12915
|
);
|
|
12776
|
-
this.nodeMap = new Map(
|
|
12777
|
-
this.sectionNodes.map((n) => [n.capacityMeshNodeId, n])
|
|
12778
|
-
);
|
|
12916
|
+
this.nodeMap = params.nodeMap ?? new Map(this.sectionNodes.map((n) => [n.capacityMeshNodeId, n]));
|
|
12779
12917
|
this.nodeEdgeMap = params.nodeEdgeMap ?? getNodeEdgeMap(this.sectionEdges);
|
|
12780
12918
|
this.colorMap = params.colorMap ?? {};
|
|
12781
12919
|
this.usedNodeCapacityMap = new Map(
|
|
12782
12920
|
this.sectionNodes.map((node) => [node.capacityMeshNodeId, 0])
|
|
12783
12921
|
);
|
|
12922
|
+
this.totalNodeCapacityMap = new Map(
|
|
12923
|
+
this.sectionNodes.map((node) => [
|
|
12924
|
+
node.capacityMeshNodeId,
|
|
12925
|
+
this.getTotalCapacity(node)
|
|
12926
|
+
])
|
|
12927
|
+
);
|
|
12928
|
+
const initialSectionNodeIds = new Set(
|
|
12929
|
+
this.sectionNodes.map((n) => n.capacityMeshNodeId)
|
|
12930
|
+
);
|
|
12931
|
+
this.currentSectionScore = computeSectionScore({
|
|
12932
|
+
totalNodeCapacityMap: this.totalNodeCapacityMap,
|
|
12933
|
+
usedNodeCapacityMap: this.usedNodeCapacityMap,
|
|
12934
|
+
// Reflects initial capacities
|
|
12935
|
+
nodeMap: this.nodeMap,
|
|
12936
|
+
sectionNodeIds: initialSectionNodeIds
|
|
12937
|
+
});
|
|
12784
12938
|
if (params.hyperParameters?.SHUFFLE_SEED) {
|
|
12785
12939
|
this.sectionConnectionTerminals = cloneAndShuffleArray(
|
|
12786
12940
|
this.sectionConnectionTerminals,
|
|
@@ -12860,15 +13014,40 @@ var CapacityPathingSingleSectionSolver = class extends BaseSolver {
|
|
|
12860
13014
|
}
|
|
12861
13015
|
// Adapted from CapacityPathingSolver - uses section's capacity map
|
|
12862
13016
|
reduceCapacityAlongPath(path) {
|
|
12863
|
-
for (const
|
|
12864
|
-
if (this.usedNodeCapacityMap.has(
|
|
12865
|
-
|
|
12866
|
-
|
|
12867
|
-
|
|
13017
|
+
for (const pathNode of path) {
|
|
13018
|
+
if (this.usedNodeCapacityMap.has(pathNode.capacityMeshNodeId)) {
|
|
13019
|
+
const nodeId = pathNode.capacityMeshNodeId;
|
|
13020
|
+
const nodeInSection = this.nodeMap.get(nodeId);
|
|
13021
|
+
if (!nodeInSection) {
|
|
13022
|
+
console.warn(
|
|
13023
|
+
`Node ${nodeId} from path not found in section's nodeMap during score update.`
|
|
13024
|
+
);
|
|
13025
|
+
continue;
|
|
13026
|
+
}
|
|
13027
|
+
const totalCapacity = this.totalNodeCapacityMap.get(nodeId);
|
|
13028
|
+
const oldUsedCapacity = this.usedNodeCapacityMap.get(nodeId) ?? 0;
|
|
13029
|
+
const oldNodeScoreContribution = calculateSingleNodeLogSuccessProbability(
|
|
13030
|
+
oldUsedCapacity,
|
|
13031
|
+
totalCapacity,
|
|
13032
|
+
nodeInSection
|
|
13033
|
+
// Use the node object from the section's map
|
|
13034
|
+
);
|
|
13035
|
+
this.currentSectionScore -= oldNodeScoreContribution;
|
|
13036
|
+
const newUsedCapacity = oldUsedCapacity + 1;
|
|
13037
|
+
this.usedNodeCapacityMap.set(nodeId, newUsedCapacity);
|
|
13038
|
+
const newNodeScoreContribution = calculateSingleNodeLogSuccessProbability(
|
|
13039
|
+
newUsedCapacity,
|
|
13040
|
+
totalCapacity,
|
|
13041
|
+
nodeInSection
|
|
13042
|
+
// Use the node object from the section's map
|
|
12868
13043
|
);
|
|
13044
|
+
this.currentSectionScore += newNodeScoreContribution;
|
|
12869
13045
|
}
|
|
12870
13046
|
}
|
|
12871
13047
|
}
|
|
13048
|
+
getSolvedSectionScore() {
|
|
13049
|
+
return this.currentSectionScore;
|
|
13050
|
+
}
|
|
12872
13051
|
_step() {
|
|
12873
13052
|
const currentTerminal = this.sectionConnectionTerminals[this.currentConnectionIndex];
|
|
12874
13053
|
if (!currentTerminal) {
|
|
@@ -13070,6 +13249,7 @@ var CapacityPathingSingleSectionSolver = class extends BaseSolver {
|
|
|
13070
13249
|
var CapacityPathingSingleSectionPathingSolver = CapacityPathingSingleSectionSolver;
|
|
13071
13250
|
|
|
13072
13251
|
// lib/solvers/CapacityPathingSectionSolver/HyperCapacityPathingSingleSectionSolver.ts
|
|
13252
|
+
var range = (n) => Array.from({ length: n }, (_, i) => i);
|
|
13073
13253
|
var HyperCapacityPathingSingleSectionSolver = class extends HyperParameterSupervisorSolver {
|
|
13074
13254
|
constructorParams;
|
|
13075
13255
|
winningSolver;
|
|
@@ -13078,14 +13258,24 @@ var HyperCapacityPathingSingleSectionSolver = class extends HyperParameterSuperv
|
|
|
13078
13258
|
this.MAX_ITERATIONS = 1e5;
|
|
13079
13259
|
this.constructorParams = params;
|
|
13080
13260
|
}
|
|
13261
|
+
// TODO this needs to use the section score, ideally incorporating the current best candidate
|
|
13262
|
+
// of the paths being explored inside the single section
|
|
13081
13263
|
computeG(solver) {
|
|
13082
|
-
return solver.
|
|
13264
|
+
return -solver.getSolvedSectionScore();
|
|
13083
13265
|
}
|
|
13084
13266
|
computeH(solver) {
|
|
13085
|
-
return
|
|
13267
|
+
return 0;
|
|
13086
13268
|
}
|
|
13087
13269
|
getCombinationDefs() {
|
|
13088
|
-
|
|
13270
|
+
const numConnections = this.constructorParams.sectionConnectionTerminals.length;
|
|
13271
|
+
if (numConnections === 2) {
|
|
13272
|
+
return [["orderings2_for2"]];
|
|
13273
|
+
} else if (numConnections === 3) {
|
|
13274
|
+
return [["orderings6_for3"]];
|
|
13275
|
+
} else if (numConnections === 4) {
|
|
13276
|
+
return [["orderings24_for4"]];
|
|
13277
|
+
}
|
|
13278
|
+
return [["orderings30"]];
|
|
13089
13279
|
}
|
|
13090
13280
|
getFailureMessage() {
|
|
13091
13281
|
return `All CapacityPathingSingleSection solvers failed for "${this.centerNodeId}"`;
|
|
@@ -13093,39 +13283,28 @@ var HyperCapacityPathingSingleSectionSolver = class extends HyperParameterSuperv
|
|
|
13093
13283
|
getHyperParameterDefs() {
|
|
13094
13284
|
return [
|
|
13095
13285
|
{
|
|
13096
|
-
name: "
|
|
13097
|
-
possibleValues:
|
|
13098
|
-
|
|
13099
|
-
|
|
13100
|
-
|
|
13101
|
-
|
|
13102
|
-
|
|
13103
|
-
|
|
13104
|
-
|
|
13105
|
-
|
|
13106
|
-
|
|
13107
|
-
|
|
13108
|
-
|
|
13109
|
-
|
|
13110
|
-
|
|
13111
|
-
|
|
13112
|
-
|
|
13113
|
-
|
|
13114
|
-
|
|
13115
|
-
|
|
13116
|
-
|
|
13117
|
-
|
|
13118
|
-
},
|
|
13119
|
-
{
|
|
13120
|
-
SHUFFLE_SEED: 7
|
|
13121
|
-
},
|
|
13122
|
-
{
|
|
13123
|
-
SHUFFLE_SEED: 8
|
|
13124
|
-
},
|
|
13125
|
-
{
|
|
13126
|
-
SHUFFLE_SEED: 9
|
|
13127
|
-
}
|
|
13128
|
-
]
|
|
13286
|
+
name: "orderings2_for2",
|
|
13287
|
+
possibleValues: range(2).map((i) => ({
|
|
13288
|
+
SHUFFLE_SEED: i
|
|
13289
|
+
}))
|
|
13290
|
+
},
|
|
13291
|
+
{
|
|
13292
|
+
name: "orderings6_for3",
|
|
13293
|
+
possibleValues: range(6).map((i) => ({
|
|
13294
|
+
SHUFFLE_SEED: i
|
|
13295
|
+
}))
|
|
13296
|
+
},
|
|
13297
|
+
{
|
|
13298
|
+
name: "orderings24_for4",
|
|
13299
|
+
possibleValues: range(24).map((i) => ({
|
|
13300
|
+
SHUFFLE_SEED: i
|
|
13301
|
+
}))
|
|
13302
|
+
},
|
|
13303
|
+
{
|
|
13304
|
+
name: "orderings30",
|
|
13305
|
+
possibleValues: range(30).map((i) => ({
|
|
13306
|
+
SHUFFLE_SEED: i
|
|
13307
|
+
}))
|
|
13129
13308
|
}
|
|
13130
13309
|
];
|
|
13131
13310
|
}
|
|
@@ -13154,70 +13333,320 @@ var HyperCapacityPathingSingleSectionSolver = class extends HyperParameterSuperv
|
|
|
13154
13333
|
}
|
|
13155
13334
|
};
|
|
13156
13335
|
|
|
13157
|
-
// lib/solvers/CapacityPathingSectionSolver/
|
|
13158
|
-
|
|
13159
|
-
|
|
13160
|
-
|
|
13161
|
-
|
|
13162
|
-
|
|
13163
|
-
|
|
13164
|
-
|
|
13165
|
-
|
|
13166
|
-
|
|
13167
|
-
|
|
13168
|
-
|
|
13169
|
-
|
|
13170
|
-
|
|
13171
|
-
|
|
13172
|
-
|
|
13173
|
-
|
|
13174
|
-
|
|
13175
|
-
|
|
13176
|
-
|
|
13177
|
-
|
|
13178
|
-
|
|
13179
|
-
|
|
13180
|
-
|
|
13181
|
-
|
|
13336
|
+
// lib/solvers/CapacityPathingSectionSolver/CachedHyperCapacityPathingSingleSectionSolver.ts
|
|
13337
|
+
import objectHash2 from "object-hash";
|
|
13338
|
+
var roundCapacity = (capacity) => Math.floor(capacity * 10) / 10;
|
|
13339
|
+
var CachedHyperCapacityPathingSingleSectionSolver = class extends HyperCapacityPathingSingleSectionSolver {
|
|
13340
|
+
cacheHit = false;
|
|
13341
|
+
cacheProvider;
|
|
13342
|
+
hasAttemptedToUseCache = false;
|
|
13343
|
+
sectionNodeIdSet;
|
|
13344
|
+
cachedSectionConnectionTerminals = null;
|
|
13345
|
+
sectionScore = 0;
|
|
13346
|
+
constructor(params) {
|
|
13347
|
+
params.nodeMap = params.nodeMap ?? new Map(params.sectionNodes.map((n) => [n.capacityMeshNodeId, n]));
|
|
13348
|
+
super(params);
|
|
13349
|
+
this.sectionNodeIdSet = new Set(
|
|
13350
|
+
params.sectionNodes.map((sn) => sn.capacityMeshNodeId)
|
|
13351
|
+
);
|
|
13352
|
+
this.cacheProvider = params.cacheProvider === void 0 ? getGlobalInMemoryCache() : params.cacheProvider;
|
|
13353
|
+
}
|
|
13354
|
+
_step() {
|
|
13355
|
+
if (!this.hasAttemptedToUseCache && this.cacheProvider) {
|
|
13356
|
+
if (this.attemptToUseCacheSync()) return;
|
|
13357
|
+
}
|
|
13358
|
+
super._step();
|
|
13359
|
+
if ((this.solved || this.failed) && this.cacheProvider) {
|
|
13360
|
+
this.saveToCacheSync();
|
|
13182
13361
|
}
|
|
13183
13362
|
}
|
|
13184
|
-
|
|
13185
|
-
|
|
13186
|
-
const
|
|
13187
|
-
|
|
13188
|
-
|
|
13189
|
-
|
|
13190
|
-
|
|
13191
|
-
|
|
13192
|
-
|
|
13193
|
-
|
|
13194
|
-
|
|
13195
|
-
|
|
13196
|
-
|
|
13197
|
-
|
|
13363
|
+
_computeBfsOrderingOfNodesInSection() {
|
|
13364
|
+
const seenNodeIds = new Set(this.constructorParams.centerNodeId);
|
|
13365
|
+
const ordering = [];
|
|
13366
|
+
const candidates = [
|
|
13367
|
+
{
|
|
13368
|
+
ancestorCapacitySum: 0,
|
|
13369
|
+
capacity: 0,
|
|
13370
|
+
g: 0,
|
|
13371
|
+
capacityMeshNodeId: this.constructorParams.centerNodeId
|
|
13372
|
+
}
|
|
13373
|
+
];
|
|
13374
|
+
while (candidates.length > 0) {
|
|
13375
|
+
candidates.sort((a, b) => b.g - a.g);
|
|
13376
|
+
const candidate = candidates.pop();
|
|
13377
|
+
if (!candidate) break;
|
|
13378
|
+
ordering.push(candidate.capacityMeshNodeId);
|
|
13379
|
+
const neighborNodeIds = this.constructorParams.nodeEdgeMap.get(candidate.capacityMeshNodeId).flatMap((edge) => edge.nodeIds).filter((nodeId) => !seenNodeIds.has(nodeId)).filter((nodeId) => this.sectionNodeIdSet.has(nodeId));
|
|
13380
|
+
for (const neighborNodeId of neighborNodeIds) {
|
|
13381
|
+
seenNodeIds.add(neighborNodeId);
|
|
13382
|
+
const neighbor = this.constructorParams.nodeMap.get(neighborNodeId);
|
|
13383
|
+
const capacity = getTunedTotalCapacity1(neighbor);
|
|
13384
|
+
candidates.push({
|
|
13385
|
+
ancestorCapacitySum: candidate.g,
|
|
13386
|
+
capacity,
|
|
13387
|
+
g: candidate.g + capacity,
|
|
13388
|
+
capacityMeshNodeId: neighborNodeId
|
|
13389
|
+
});
|
|
13198
13390
|
}
|
|
13199
13391
|
}
|
|
13200
|
-
|
|
13201
|
-
|
|
13202
|
-
|
|
13203
|
-
|
|
13204
|
-
|
|
13392
|
+
return ordering;
|
|
13393
|
+
}
|
|
13394
|
+
computeCacheKeyAndTransform() {
|
|
13395
|
+
const nodeOrdering = this._computeBfsOrderingOfNodesInSection();
|
|
13396
|
+
const realToCacheSpaceNodeIdMap = /* @__PURE__ */ new Map();
|
|
13397
|
+
const cacheSpaceToRealNodeIdMap = /* @__PURE__ */ new Map();
|
|
13398
|
+
nodeOrdering.forEach((realNodeId, i) => {
|
|
13399
|
+
const cacheNodeId = `node${i}`;
|
|
13400
|
+
realToCacheSpaceNodeIdMap.set(realNodeId, cacheNodeId);
|
|
13401
|
+
cacheSpaceToRealNodeIdMap.set(cacheNodeId, realNodeId);
|
|
13402
|
+
});
|
|
13403
|
+
const node_capacity_map = {};
|
|
13404
|
+
for (const realNodeId of nodeOrdering) {
|
|
13405
|
+
const cacheNodeId = realToCacheSpaceNodeIdMap.get(realNodeId);
|
|
13406
|
+
const node = this.constructorParams.nodeMap.get(realNodeId);
|
|
13407
|
+
const capacity = getTunedTotalCapacity1(node);
|
|
13408
|
+
node_capacity_map[cacheNodeId] = roundCapacity(capacity).toFixed(
|
|
13409
|
+
1
|
|
13410
|
+
);
|
|
13411
|
+
}
|
|
13412
|
+
const node_edge_map_set = /* @__PURE__ */ new Set();
|
|
13413
|
+
const node_edge_map = [];
|
|
13414
|
+
for (const realNodeId1 of nodeOrdering) {
|
|
13415
|
+
const cacheNodeId1 = realToCacheSpaceNodeIdMap.get(realNodeId1);
|
|
13416
|
+
const neighbors = this.constructorParams.nodeEdgeMap.get(realNodeId1) ?? [];
|
|
13417
|
+
for (const edge of neighbors) {
|
|
13418
|
+
const realNodeId2 = edge.nodeIds.find((id) => id !== realNodeId1);
|
|
13419
|
+
if (this.sectionNodeIdSet.has(realNodeId2)) {
|
|
13420
|
+
const cacheNodeId2 = realToCacheSpaceNodeIdMap.get(realNodeId2);
|
|
13421
|
+
const pair = [cacheNodeId1, cacheNodeId2].sort();
|
|
13422
|
+
const pairKey = `${pair[0]}-${pair[1]}`;
|
|
13423
|
+
if (!node_edge_map_set.has(pairKey)) {
|
|
13424
|
+
node_edge_map.push(pair);
|
|
13425
|
+
node_edge_map_set.add(pairKey);
|
|
13426
|
+
}
|
|
13427
|
+
}
|
|
13205
13428
|
}
|
|
13206
13429
|
}
|
|
13207
|
-
|
|
13208
|
-
|
|
13209
|
-
|
|
13210
|
-
|
|
13211
|
-
|
|
13430
|
+
node_edge_map.sort((a, b) => {
|
|
13431
|
+
if (a[0] !== b[0]) return a[0].localeCompare(b[0]);
|
|
13432
|
+
return a[1].localeCompare(b[1]);
|
|
13433
|
+
});
|
|
13434
|
+
const terminals = {};
|
|
13435
|
+
const cacheSpaceToRealConnectionId = /* @__PURE__ */ new Map();
|
|
13436
|
+
for (const conn of this.constructorParams.sectionConnectionTerminals) {
|
|
13437
|
+
const cacheStartNodeId = realToCacheSpaceNodeIdMap.get(conn.startNodeId);
|
|
13438
|
+
const cacheEndNodeId = realToCacheSpaceNodeIdMap.get(conn.endNodeId);
|
|
13439
|
+
const [sortedStartId, sortedEndId] = [
|
|
13440
|
+
cacheStartNodeId,
|
|
13441
|
+
cacheEndNodeId
|
|
13442
|
+
].sort();
|
|
13443
|
+
const cacheSpaceConnectionId = `${sortedStartId}->${sortedEndId}`;
|
|
13444
|
+
terminals[cacheSpaceConnectionId] = {
|
|
13445
|
+
start: sortedStartId,
|
|
13446
|
+
end: sortedEndId
|
|
13447
|
+
};
|
|
13448
|
+
cacheSpaceToRealConnectionId.set(
|
|
13449
|
+
cacheSpaceConnectionId,
|
|
13450
|
+
// Use the canonically sorted key
|
|
13451
|
+
conn.connectionName
|
|
13452
|
+
);
|
|
13453
|
+
}
|
|
13454
|
+
const cacheKeyContent = {
|
|
13455
|
+
node_capacity_map,
|
|
13456
|
+
node_edge_map,
|
|
13457
|
+
terminals
|
|
13458
|
+
};
|
|
13459
|
+
const cacheKey = `capacitypathing:${objectHash2(cacheKeyContent)}`;
|
|
13460
|
+
const cacheToSolveSpaceTransform = {
|
|
13461
|
+
cacheSpaceToRealConnectionId,
|
|
13462
|
+
cacheSpaceToRealNodeId: cacheSpaceToRealNodeIdMap
|
|
13463
|
+
};
|
|
13464
|
+
this.cacheKey = cacheKey;
|
|
13465
|
+
this.cacheToSolveSpaceTransform = cacheToSolveSpaceTransform;
|
|
13466
|
+
return { cacheKey, cacheToSolveSpaceTransform };
|
|
13467
|
+
}
|
|
13468
|
+
applyCachedSolution(cachedSolution) {
|
|
13469
|
+
if (!this.cacheToSolveSpaceTransform) {
|
|
13470
|
+
console.error(
|
|
13471
|
+
"Cache transform not available, cannot apply cached solution."
|
|
13472
|
+
);
|
|
13473
|
+
this.failed = true;
|
|
13474
|
+
return;
|
|
13475
|
+
}
|
|
13476
|
+
if (!cachedSolution.success) {
|
|
13477
|
+
this.failed = true;
|
|
13478
|
+
this.cacheHit = true;
|
|
13479
|
+
return;
|
|
13480
|
+
}
|
|
13481
|
+
this.cachedSectionConnectionTerminals = [];
|
|
13482
|
+
const { cacheSpaceToRealNodeId, cacheSpaceToRealConnectionId } = this.cacheToSolveSpaceTransform;
|
|
13483
|
+
for (const [cacheConnId, cachePathNodeIds] of Object.entries(
|
|
13484
|
+
cachedSolution.solutionPaths
|
|
13485
|
+
)) {
|
|
13486
|
+
const realConnectionName = cacheSpaceToRealConnectionId.get(
|
|
13487
|
+
cacheConnId
|
|
13488
|
+
);
|
|
13489
|
+
if (!realConnectionName) {
|
|
13490
|
+
console.warn(`Could not find real connection name for ${cacheConnId}`);
|
|
13491
|
+
continue;
|
|
13492
|
+
}
|
|
13493
|
+
const originalTerminal = this.constructorParams.sectionConnectionTerminals.find(
|
|
13494
|
+
(t) => t.connectionName === realConnectionName
|
|
13495
|
+
);
|
|
13496
|
+
if (!originalTerminal) {
|
|
13497
|
+
console.warn(
|
|
13498
|
+
`Could not find original terminal for connection name ${realConnectionName}`
|
|
13499
|
+
);
|
|
13500
|
+
continue;
|
|
13501
|
+
}
|
|
13502
|
+
const realPathNodes = cachePathNodeIds.map(
|
|
13503
|
+
(cacheNodeId) => {
|
|
13504
|
+
const realNodeId = cacheSpaceToRealNodeId.get(cacheNodeId);
|
|
13505
|
+
if (!realNodeId) {
|
|
13506
|
+
throw new Error(
|
|
13507
|
+
`Could not map cache node ID ${cacheNodeId} to real node ID for connection ${realConnectionName}`
|
|
13508
|
+
);
|
|
13509
|
+
}
|
|
13510
|
+
const node = this.constructorParams.nodeMap.get(realNodeId);
|
|
13511
|
+
if (!node) {
|
|
13512
|
+
throw new Error(
|
|
13513
|
+
`Could not find node with ID ${realNodeId} in nodeMap for connection ${realConnectionName}`
|
|
13514
|
+
);
|
|
13515
|
+
}
|
|
13516
|
+
return node;
|
|
13517
|
+
}
|
|
13518
|
+
);
|
|
13519
|
+
this.cachedSectionConnectionTerminals.push({
|
|
13520
|
+
...originalTerminal,
|
|
13521
|
+
path: realPathNodes
|
|
13212
13522
|
});
|
|
13213
13523
|
}
|
|
13524
|
+
this.sectionScore = cachedSolution.sectionScore;
|
|
13525
|
+
this.solved = true;
|
|
13526
|
+
this.cacheHit = true;
|
|
13527
|
+
}
|
|
13528
|
+
attemptToUseCacheSync() {
|
|
13529
|
+
this.hasAttemptedToUseCache = true;
|
|
13530
|
+
if (!this.cacheProvider?.isSyncCache) {
|
|
13531
|
+
console.log(
|
|
13532
|
+
"Cache provider is not synchronous, skipping sync cache check."
|
|
13533
|
+
);
|
|
13534
|
+
return false;
|
|
13535
|
+
}
|
|
13536
|
+
if (!this.cacheKey) {
|
|
13537
|
+
this.computeCacheKeyAndTransform();
|
|
13538
|
+
}
|
|
13539
|
+
if (!this.cacheKey) {
|
|
13540
|
+
console.error("Failed to compute cache key.");
|
|
13541
|
+
return false;
|
|
13542
|
+
}
|
|
13543
|
+
try {
|
|
13544
|
+
const cachedSolution = this.cacheProvider.getCachedSolutionSync(
|
|
13545
|
+
this.cacheKey
|
|
13546
|
+
);
|
|
13547
|
+
if (cachedSolution) {
|
|
13548
|
+
this.applyCachedSolution(
|
|
13549
|
+
cachedSolution
|
|
13550
|
+
);
|
|
13551
|
+
return true;
|
|
13552
|
+
}
|
|
13553
|
+
} catch (error) {
|
|
13554
|
+
console.error("Error attempting to use cache:", error);
|
|
13555
|
+
}
|
|
13556
|
+
return false;
|
|
13557
|
+
}
|
|
13558
|
+
saveToCacheSync() {
|
|
13559
|
+
if (!this.cacheKey) {
|
|
13560
|
+
console.error("Cannot save to cache without cache key.");
|
|
13561
|
+
return;
|
|
13562
|
+
}
|
|
13563
|
+
if (!this.cacheToSolveSpaceTransform) {
|
|
13564
|
+
console.error(
|
|
13565
|
+
"Cache transform not available, cannot save solution to cache."
|
|
13566
|
+
);
|
|
13567
|
+
return;
|
|
13568
|
+
}
|
|
13569
|
+
let cachedSolution;
|
|
13570
|
+
if (this.failed) {
|
|
13571
|
+
cachedSolution = { success: false };
|
|
13572
|
+
} else if (this.solved) {
|
|
13573
|
+
const solutionPathsInCacheSpace = {};
|
|
13574
|
+
const { cacheSpaceToRealNodeId, cacheSpaceToRealConnectionId } = this.cacheToSolveSpaceTransform;
|
|
13575
|
+
const realToCacheSpaceNodeId = /* @__PURE__ */ new Map();
|
|
13576
|
+
for (const [cacheId, realId] of cacheSpaceToRealNodeId) {
|
|
13577
|
+
realToCacheSpaceNodeId.set(realId, cacheId);
|
|
13578
|
+
}
|
|
13579
|
+
const realToCacheSpaceConnectionId = /* @__PURE__ */ new Map();
|
|
13580
|
+
for (const [cacheConnId, realConnName] of cacheSpaceToRealConnectionId) {
|
|
13581
|
+
realToCacheSpaceConnectionId.set(realConnName, cacheConnId);
|
|
13582
|
+
}
|
|
13583
|
+
const realSolutionPaths = [];
|
|
13584
|
+
if (super.sectionConnectionTerminals) {
|
|
13585
|
+
for (const terminal of super.sectionConnectionTerminals) {
|
|
13586
|
+
if (terminal.path && terminal.path.length > 0) {
|
|
13587
|
+
const realPathNodeIds = terminal.path.map(
|
|
13588
|
+
(node) => node.capacityMeshNodeId
|
|
13589
|
+
);
|
|
13590
|
+
realSolutionPaths.push([terminal.connectionName, realPathNodeIds]);
|
|
13591
|
+
}
|
|
13592
|
+
}
|
|
13593
|
+
}
|
|
13594
|
+
for (const [realConnectionName, realPathNodeIds] of realSolutionPaths) {
|
|
13595
|
+
const cacheConnectionId = realToCacheSpaceConnectionId.get(realConnectionName);
|
|
13596
|
+
if (!cacheConnectionId) {
|
|
13597
|
+
console.warn(
|
|
13598
|
+
`Could not find cache space connection ID for ${realConnectionName} when saving to cache.`
|
|
13599
|
+
);
|
|
13600
|
+
continue;
|
|
13601
|
+
}
|
|
13602
|
+
const cachePathNodeIds = realPathNodeIds.map((realNodeId) => {
|
|
13603
|
+
const cacheNodeId = realToCacheSpaceNodeId.get(realNodeId);
|
|
13604
|
+
if (!cacheNodeId) {
|
|
13605
|
+
throw new Error(
|
|
13606
|
+
`Could not map real node ID ${realNodeId} to cache node ID for connection ${realConnectionName} when saving to cache.`
|
|
13607
|
+
);
|
|
13608
|
+
}
|
|
13609
|
+
return cacheNodeId;
|
|
13610
|
+
});
|
|
13611
|
+
solutionPathsInCacheSpace[cacheConnectionId] = cachePathNodeIds;
|
|
13612
|
+
}
|
|
13613
|
+
cachedSolution = {
|
|
13614
|
+
success: true,
|
|
13615
|
+
sectionScore: this.sectionScore,
|
|
13616
|
+
solutionPaths: solutionPathsInCacheSpace
|
|
13617
|
+
};
|
|
13618
|
+
} else {
|
|
13619
|
+
return;
|
|
13620
|
+
}
|
|
13621
|
+
try {
|
|
13622
|
+
this.cacheProvider?.setCachedSolutionSync(this.cacheKey, cachedSolution);
|
|
13623
|
+
} catch (error) {
|
|
13624
|
+
console.error("Error saving solution to cache:", error);
|
|
13625
|
+
}
|
|
13626
|
+
}
|
|
13627
|
+
get sectionConnectionTerminals() {
|
|
13628
|
+
if (this.cacheHit && this.solved && this.cachedSectionConnectionTerminals) {
|
|
13629
|
+
console.log("returning the cached section connection terminals");
|
|
13630
|
+
return this.cachedSectionConnectionTerminals;
|
|
13631
|
+
}
|
|
13632
|
+
return super.sectionConnectionTerminals;
|
|
13633
|
+
}
|
|
13634
|
+
visualize() {
|
|
13635
|
+
if (!this.cacheHit) return super.visualize();
|
|
13636
|
+
const graphics = visualizeSection({
|
|
13637
|
+
sectionNodes: this.constructorParams.sectionNodes,
|
|
13638
|
+
sectionEdges: this.constructorParams.sectionEdges,
|
|
13639
|
+
sectionConnectionTerminals: this.cachedSectionConnectionTerminals,
|
|
13640
|
+
completedPaths: this.cachedSectionConnectionTerminals.map((t) => ({
|
|
13641
|
+
connectionName: t.connectionName,
|
|
13642
|
+
path: t.path
|
|
13643
|
+
})),
|
|
13644
|
+
nodeMap: this.constructorParams.nodeMap,
|
|
13645
|
+
colorMap: this.constructorParams.colorMap,
|
|
13646
|
+
title: "CachedHyperCapacityPathingSingleSectionSolver"
|
|
13647
|
+
});
|
|
13648
|
+
return graphics;
|
|
13214
13649
|
}
|
|
13215
|
-
return {
|
|
13216
|
-
sectionConnectionTerminals,
|
|
13217
|
-
sectionNodes,
|
|
13218
|
-
sectionEdges,
|
|
13219
|
-
centerNodeId
|
|
13220
|
-
};
|
|
13221
13650
|
};
|
|
13222
13651
|
|
|
13223
13652
|
// lib/solvers/CapacityPathingSectionSolver/CapacityPathingMultiSectionSolver.ts
|
|
@@ -13230,8 +13659,10 @@ var CapacityPathingMultiSectionSolver = class extends BaseSolver {
|
|
|
13230
13659
|
// Initialize here
|
|
13231
13660
|
colorMap;
|
|
13232
13661
|
initialSolver;
|
|
13662
|
+
cacheProvider;
|
|
13233
13663
|
stage = "initialization";
|
|
13234
13664
|
nodeMap = /* @__PURE__ */ new Map();
|
|
13665
|
+
allNodeIdsSet;
|
|
13235
13666
|
usedNodeCapacityMap = /* @__PURE__ */ new Map();
|
|
13236
13667
|
totalNodeCapacityMap = /* @__PURE__ */ new Map();
|
|
13237
13668
|
// Added
|
|
@@ -13241,6 +13672,7 @@ var CapacityPathingMultiSectionSolver = class extends BaseSolver {
|
|
|
13241
13672
|
sectionSolver = null;
|
|
13242
13673
|
currentScheduleIndex = 0;
|
|
13243
13674
|
stats;
|
|
13675
|
+
// Adjusting this schedule is a trade-off between optimization speed and quality.
|
|
13244
13676
|
OPTIMIZATION_SCHEDULE = [
|
|
13245
13677
|
{
|
|
13246
13678
|
MAX_ATTEMPTS_PER_NODE: 1,
|
|
@@ -13255,7 +13687,7 @@ var CapacityPathingMultiSectionSolver = class extends BaseSolver {
|
|
|
13255
13687
|
{
|
|
13256
13688
|
MAX_ATTEMPTS_PER_NODE: 3,
|
|
13257
13689
|
MAX_EXPANSION_DEGREES: 7,
|
|
13258
|
-
MINIMUM_PROBABILITY_OF_FAILURE_TO_OPTIMIZE: 0.
|
|
13690
|
+
MINIMUM_PROBABILITY_OF_FAILURE_TO_OPTIMIZE: 0.9
|
|
13259
13691
|
}
|
|
13260
13692
|
];
|
|
13261
13693
|
get currentSchedule() {
|
|
@@ -13267,6 +13699,7 @@ var CapacityPathingMultiSectionSolver = class extends BaseSolver {
|
|
|
13267
13699
|
successfulOptimizations: 0,
|
|
13268
13700
|
failedOptimizations: 0,
|
|
13269
13701
|
failedSectionSolvers: 0,
|
|
13702
|
+
startingScore: 0,
|
|
13270
13703
|
scheduleScores: this.OPTIMIZATION_SCHEDULE.map(
|
|
13271
13704
|
({ MAX_EXPANSION_DEGREES }) => ({
|
|
13272
13705
|
maxExpansionDegrees: MAX_EXPANSION_DEGREES,
|
|
@@ -13277,6 +13710,7 @@ var CapacityPathingMultiSectionSolver = class extends BaseSolver {
|
|
|
13277
13710
|
)
|
|
13278
13711
|
};
|
|
13279
13712
|
this.MAX_ITERATIONS = 1e7;
|
|
13713
|
+
this.cacheProvider = params.cacheProvider;
|
|
13280
13714
|
this.simpleRouteJson = params.simpleRouteJson;
|
|
13281
13715
|
this.nodes = params.nodes;
|
|
13282
13716
|
this.edges = params.edges;
|
|
@@ -13297,6 +13731,7 @@ var CapacityPathingMultiSectionSolver = class extends BaseSolver {
|
|
|
13297
13731
|
const totalCapacity = this.initialSolver.getTotalCapacity(node);
|
|
13298
13732
|
this.totalNodeCapacityMap.set(node.capacityMeshNodeId, totalCapacity);
|
|
13299
13733
|
}
|
|
13734
|
+
this.allNodeIdsSet = new Set(this.nodes.map((n) => n.capacityMeshNodeId));
|
|
13300
13735
|
}
|
|
13301
13736
|
_stepInitialization() {
|
|
13302
13737
|
this.initialSolver?.step();
|
|
@@ -13315,6 +13750,12 @@ var CapacityPathingMultiSectionSolver = class extends BaseSolver {
|
|
|
13315
13750
|
this.nodeOptimizationAttemptCountMap.set(node.capacityMeshNodeId, 0);
|
|
13316
13751
|
}
|
|
13317
13752
|
this.connectionsWithNodes = this.initialSolver.connectionsWithNodes;
|
|
13753
|
+
this.stats.startingScore = computeSectionScore({
|
|
13754
|
+
totalNodeCapacityMap: this.totalNodeCapacityMap,
|
|
13755
|
+
usedNodeCapacityMap: this.usedNodeCapacityMap,
|
|
13756
|
+
nodeMap: this.nodeMap,
|
|
13757
|
+
sectionNodeIds: this.allNodeIdsSet
|
|
13758
|
+
});
|
|
13318
13759
|
this.stage = "section-optimization";
|
|
13319
13760
|
}
|
|
13320
13761
|
}
|
|
@@ -13366,9 +13807,7 @@ var CapacityPathingMultiSectionSolver = class extends BaseSolver {
|
|
|
13366
13807
|
totalNodeCapacityMap: this.totalNodeCapacityMap,
|
|
13367
13808
|
usedNodeCapacityMap: this.usedNodeCapacityMap,
|
|
13368
13809
|
nodeMap: this.nodeMap,
|
|
13369
|
-
sectionNodeIds:
|
|
13370
|
-
this.nodes.map((node) => node.capacityMeshNodeId)
|
|
13371
|
-
)
|
|
13810
|
+
sectionNodeIds: this.allNodeIdsSet
|
|
13372
13811
|
})
|
|
13373
13812
|
};
|
|
13374
13813
|
}
|
|
@@ -13396,13 +13835,17 @@ var CapacityPathingMultiSectionSolver = class extends BaseSolver {
|
|
|
13396
13835
|
});
|
|
13397
13836
|
this.stats.scheduleScores[this.currentScheduleIndex].sectionAttempts++;
|
|
13398
13837
|
this.currentSection = section;
|
|
13399
|
-
this.sectionSolver = new
|
|
13838
|
+
this.sectionSolver = new CachedHyperCapacityPathingSingleSectionSolver({
|
|
13400
13839
|
sectionNodes: this.currentSection.sectionNodes,
|
|
13401
13840
|
sectionEdges: this.currentSection.sectionEdges,
|
|
13402
13841
|
sectionConnectionTerminals: this.currentSection.sectionConnectionTerminals,
|
|
13403
13842
|
colorMap: this.colorMap,
|
|
13404
13843
|
centerNodeId: this.currentSection.centerNodeId,
|
|
13405
|
-
nodeEdgeMap: this.nodeEdgeMap
|
|
13844
|
+
nodeEdgeMap: this.nodeEdgeMap,
|
|
13845
|
+
hyperParameters: {
|
|
13846
|
+
EXPANSION_DEGREES: this.currentSchedule.MAX_EXPANSION_DEGREES
|
|
13847
|
+
},
|
|
13848
|
+
cacheProvider: this.cacheProvider
|
|
13406
13849
|
});
|
|
13407
13850
|
this.activeSubSolver = this.sectionSolver;
|
|
13408
13851
|
this.nodeOptimizationAttemptCountMap.set(
|
|
@@ -13422,18 +13865,19 @@ var CapacityPathingMultiSectionSolver = class extends BaseSolver {
|
|
|
13422
13865
|
return;
|
|
13423
13866
|
}
|
|
13424
13867
|
if (this.sectionSolver.solved) {
|
|
13425
|
-
const
|
|
13426
|
-
const
|
|
13868
|
+
const sectionConnectionTerminals = this.sectionSolver.sectionConnectionTerminals;
|
|
13869
|
+
const sectionNodes = this.sectionSolver.sectionNodes;
|
|
13870
|
+
const centerNodeId = this.sectionSolver.centerNodeId;
|
|
13427
13871
|
this.sectionSolver = null;
|
|
13428
13872
|
this.activeSubSolver = null;
|
|
13429
|
-
if (!
|
|
13873
|
+
if (!sectionConnectionTerminals) {
|
|
13430
13874
|
console.warn(
|
|
13431
13875
|
`Pathing sub-solver for section ${this.currentSection.centerNodeId} did not complete successfully. Discarding results.`
|
|
13432
13876
|
);
|
|
13433
13877
|
return;
|
|
13434
13878
|
}
|
|
13435
13879
|
const sectionNodeIds = new Set(
|
|
13436
|
-
|
|
13880
|
+
sectionNodes.map((n) => n.capacityMeshNodeId)
|
|
13437
13881
|
);
|
|
13438
13882
|
const beforeScore = computeSectionScore({
|
|
13439
13883
|
totalNodeCapacityMap: this.totalNodeCapacityMap,
|
|
@@ -13442,7 +13886,7 @@ var CapacityPathingMultiSectionSolver = class extends BaseSolver {
|
|
|
13442
13886
|
sectionNodeIds
|
|
13443
13887
|
});
|
|
13444
13888
|
const afterUsedCapacityMap = new Map(this.usedNodeCapacityMap);
|
|
13445
|
-
const newSectionPaths =
|
|
13889
|
+
const newSectionPaths = sectionConnectionTerminals;
|
|
13446
13890
|
for (const terminal of newSectionPaths) {
|
|
13447
13891
|
const originalConnection = this.connectionsWithNodes.find(
|
|
13448
13892
|
(conn) => conn.connection.name === terminal.connectionName
|
|
@@ -13479,7 +13923,10 @@ var CapacityPathingMultiSectionSolver = class extends BaseSolver {
|
|
|
13479
13923
|
});
|
|
13480
13924
|
if (afterScore > beforeScore) {
|
|
13481
13925
|
this.stats.successfulOptimizations++;
|
|
13482
|
-
this._mergeSolvedSectionPaths(
|
|
13926
|
+
this._mergeSolvedSectionPaths({
|
|
13927
|
+
centerNodeId,
|
|
13928
|
+
sectionConnectionTerminals
|
|
13929
|
+
});
|
|
13483
13930
|
this._recalculateNodeCapacityUsage();
|
|
13484
13931
|
} else {
|
|
13485
13932
|
this.stats.failedOptimizations++;
|
|
@@ -13490,16 +13937,11 @@ var CapacityPathingMultiSectionSolver = class extends BaseSolver {
|
|
|
13490
13937
|
* Merges the paths found by a successful section solver back into the main
|
|
13491
13938
|
* connectionsWithNodes list.
|
|
13492
13939
|
*/
|
|
13493
|
-
_mergeSolvedSectionPaths(
|
|
13494
|
-
|
|
13495
|
-
|
|
13496
|
-
|
|
13497
|
-
|
|
13498
|
-
);
|
|
13499
|
-
return;
|
|
13500
|
-
}
|
|
13501
|
-
const solvedTerminals = solvedSectionSolver.sectionConnectionTerminals;
|
|
13502
|
-
for (const solvedTerminal of solvedTerminals) {
|
|
13940
|
+
_mergeSolvedSectionPaths({
|
|
13941
|
+
centerNodeId,
|
|
13942
|
+
sectionConnectionTerminals
|
|
13943
|
+
}) {
|
|
13944
|
+
for (const solvedTerminal of sectionConnectionTerminals) {
|
|
13503
13945
|
if (!solvedTerminal.path) {
|
|
13504
13946
|
console.warn(
|
|
13505
13947
|
`No path found for connection ${solvedTerminal.connectionName} in section ${centerNodeId}`
|
|
@@ -13511,7 +13953,7 @@ var CapacityPathingMultiSectionSolver = class extends BaseSolver {
|
|
|
13511
13953
|
);
|
|
13512
13954
|
if (!originalConnection || !originalConnection.path) {
|
|
13513
13955
|
console.warn(
|
|
13514
|
-
`Original connection or path not found for ${solvedTerminal.connectionName} while merging section ${
|
|
13956
|
+
`Original connection or path not found for ${solvedTerminal.connectionName} while merging section ${centerNodeId}`
|
|
13515
13957
|
);
|
|
13516
13958
|
continue;
|
|
13517
13959
|
}
|
|
@@ -15858,7 +16300,7 @@ var AutoroutingPipelineSolver = class extends BaseSolver {
|
|
|
15858
16300
|
}
|
|
15859
16301
|
this.connMap = getConnectivityMapFromSimpleRouteJson(srj);
|
|
15860
16302
|
this.colorMap = getColorMap(srj, this.connMap);
|
|
15861
|
-
this.cacheProvider = opts.cacheProvider
|
|
16303
|
+
this.cacheProvider = opts.cacheProvider === void 0 ? getGlobalInMemoryCache() : opts.cacheProvider === null ? null : opts.cacheProvider;
|
|
15862
16304
|
this.startTimeOfPhase = {};
|
|
15863
16305
|
this.endTimeOfPhase = {};
|
|
15864
16306
|
this.timeSpentOnPhase = {};
|
|
@@ -15982,6 +16424,7 @@ var AutoroutingPipelineSolver = class extends BaseSolver {
|
|
|
15982
16424
|
nodes: cms.capacityNodes,
|
|
15983
16425
|
edges: cms.edgeSolver?.edges || [],
|
|
15984
16426
|
colorMap: cms.colorMap,
|
|
16427
|
+
cacheProvider: cms.cacheProvider,
|
|
15985
16428
|
hyperParameters: {
|
|
15986
16429
|
MAX_CAPACITY_FACTOR: 1
|
|
15987
16430
|
}
|
|
@@ -16324,7 +16767,12 @@ var AutoroutingPipelineSolver = class extends BaseSolver {
|
|
|
16324
16767
|
var CapacityMeshSolver = AutoroutingPipelineSolver;
|
|
16325
16768
|
export {
|
|
16326
16769
|
CapacityMeshSolver,
|
|
16770
|
+
InMemoryCache,
|
|
16771
|
+
LocalStorageCache,
|
|
16327
16772
|
calculateOptimalCapacityDepth,
|
|
16328
|
-
|
|
16773
|
+
getGlobalInMemoryCache,
|
|
16774
|
+
getGlobalLocalStorageCache,
|
|
16775
|
+
getTunedTotalCapacity1,
|
|
16776
|
+
setupGlobalCaches
|
|
16329
16777
|
};
|
|
16330
16778
|
//# sourceMappingURL=index.js.map
|