@tscircuit/capacity-autorouter 0.0.55 → 0.0.56
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 +41 -35
- package/dist/index.js +220 -145
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -47,6 +47,7 @@ var BaseSolver = class {
|
|
|
47
47
|
activeSubSolver;
|
|
48
48
|
failedSubSolvers;
|
|
49
49
|
timeToSolve;
|
|
50
|
+
stats = {};
|
|
50
51
|
/** DO NOT OVERRIDE! Override _step() instead */
|
|
51
52
|
step() {
|
|
52
53
|
if (this.solved) return;
|
|
@@ -65,6 +66,9 @@ var BaseSolver = class {
|
|
|
65
66
|
console.error(this.error);
|
|
66
67
|
this.failed = true;
|
|
67
68
|
}
|
|
69
|
+
if ("computeProgress" in this) {
|
|
70
|
+
this.progress = this.computeProgress();
|
|
71
|
+
}
|
|
68
72
|
}
|
|
69
73
|
_step() {
|
|
70
74
|
}
|
|
@@ -2902,7 +2906,7 @@ var CapacitySegmentToPointSolver = class extends BaseSolver {
|
|
|
2902
2906
|
}
|
|
2903
2907
|
};
|
|
2904
2908
|
|
|
2905
|
-
// node_modules/@tscircuit/math-utils/dist/chunk-
|
|
2909
|
+
// node_modules/@tscircuit/math-utils/dist/chunk-3453HRP7.js
|
|
2906
2910
|
function doSegmentsIntersect(p1, q1, p2, q2) {
|
|
2907
2911
|
const o1 = orientation(p1, q1, p2);
|
|
2908
2912
|
const o2 = orientation(p1, q1, q2);
|
|
@@ -2974,7 +2978,7 @@ function clamp(value, min, max) {
|
|
|
2974
2978
|
return Math.max(min, Math.min(max, value));
|
|
2975
2979
|
}
|
|
2976
2980
|
|
|
2977
|
-
// node_modules/@tscircuit/math-utils/dist/chunk-
|
|
2981
|
+
// node_modules/@tscircuit/math-utils/dist/chunk-FWQGMQBW.js
|
|
2978
2982
|
function segmentToSegmentMinDistance(a, b, u, v) {
|
|
2979
2983
|
if (a.x === b.x && a.y === b.y) {
|
|
2980
2984
|
return pointToSegmentDistance(a, u, v);
|
|
@@ -4008,12 +4012,15 @@ var HyperParameterSupervisorSolver = class extends BaseSolver {
|
|
|
4008
4012
|
}
|
|
4009
4013
|
return bestSolver;
|
|
4010
4014
|
}
|
|
4015
|
+
getFailureMessage() {
|
|
4016
|
+
return "All solvers failed in hyper solver.";
|
|
4017
|
+
}
|
|
4011
4018
|
_step() {
|
|
4012
4019
|
if (!this.supervisedSolvers) this.initializeSolvers();
|
|
4013
4020
|
const supervisedSolver = this.getSupervisedSolverWithBestFitness();
|
|
4014
4021
|
if (!supervisedSolver) {
|
|
4015
4022
|
this.failed = true;
|
|
4016
|
-
this.error =
|
|
4023
|
+
this.error = this.getFailureMessage();
|
|
4017
4024
|
return;
|
|
4018
4025
|
}
|
|
4019
4026
|
for (let i = 0; i < this.MIN_SUBSTEPS; i++) {
|
|
@@ -6262,10 +6269,13 @@ var Vertex = class {
|
|
|
6262
6269
|
y;
|
|
6263
6270
|
out;
|
|
6264
6271
|
// Outgoing half-edge indices
|
|
6272
|
+
connectionNames;
|
|
6273
|
+
// Names of connections passing through this vertex
|
|
6265
6274
|
constructor(x, y) {
|
|
6266
6275
|
this.x = x;
|
|
6267
6276
|
this.y = y;
|
|
6268
6277
|
this.out = [];
|
|
6278
|
+
this.connectionNames = /* @__PURE__ */ new Set();
|
|
6269
6279
|
}
|
|
6270
6280
|
};
|
|
6271
6281
|
var HalfEdge = class {
|
|
@@ -6349,9 +6359,17 @@ function getCentroidsFromInnerBoxIntersections(rectangle, userSegments) {
|
|
|
6349
6359
|
return t1 - t2;
|
|
6350
6360
|
});
|
|
6351
6361
|
for (let k = 0; k < list.length - 1; ++k) {
|
|
6352
|
-
const
|
|
6353
|
-
const
|
|
6354
|
-
|
|
6362
|
+
const p1 = list[k];
|
|
6363
|
+
const p2 = list[k + 1];
|
|
6364
|
+
const v1 = getVertexId(p1);
|
|
6365
|
+
const v2 = getVertexId(p2);
|
|
6366
|
+
if (v1 !== v2) {
|
|
6367
|
+
undirectedEdges.push([v1, v2]);
|
|
6368
|
+
if (s.connectionName) {
|
|
6369
|
+
vertices[v1].connectionNames.add(s.connectionName);
|
|
6370
|
+
vertices[v2].connectionNames.add(s.connectionName);
|
|
6371
|
+
}
|
|
6372
|
+
}
|
|
6355
6373
|
}
|
|
6356
6374
|
}
|
|
6357
6375
|
const halfEdges = [];
|
|
@@ -6408,8 +6426,11 @@ function getCentroidsFromInnerBoxIntersections(rectangle, userSegments) {
|
|
|
6408
6426
|
if (c) {
|
|
6409
6427
|
centroids.push(c);
|
|
6410
6428
|
faces.push({
|
|
6411
|
-
vertices: poly.map((
|
|
6412
|
-
|
|
6429
|
+
vertices: poly.map((v) => ({
|
|
6430
|
+
x: v.x,
|
|
6431
|
+
y: v.y,
|
|
6432
|
+
connectionNames: v.connectionNames.size > 0 ? v.connectionNames : void 0
|
|
6433
|
+
})),
|
|
6413
6434
|
centroid: c
|
|
6414
6435
|
});
|
|
6415
6436
|
}
|
|
@@ -6995,6 +7016,7 @@ var MultiHeadPolyLineIntraNodeSolver = class extends BaseSolver {
|
|
|
6995
7016
|
obstacleMargin = 0.1;
|
|
6996
7017
|
traceWidth = 0.15;
|
|
6997
7018
|
availableZ = [];
|
|
7019
|
+
uniqueConnections = 0;
|
|
6998
7020
|
lastCandidate = null;
|
|
6999
7021
|
maxViaCount;
|
|
7000
7022
|
minViaCount;
|
|
@@ -7022,6 +7044,7 @@ var MultiHeadPolyLineIntraNodeSolver = class extends BaseSolver {
|
|
|
7022
7044
|
const uniqueConnections = new Set(
|
|
7023
7045
|
this.nodeWithPortPoints.portPoints.map((pp) => pp.connectionName)
|
|
7024
7046
|
).size;
|
|
7047
|
+
this.uniqueConnections = uniqueConnections;
|
|
7025
7048
|
const { numSameLayerCrossings, numTransitions } = getIntraNodeCrossings(
|
|
7026
7049
|
this.nodeWithPortPoints
|
|
7027
7050
|
);
|
|
@@ -7030,11 +7053,6 @@ var MultiHeadPolyLineIntraNodeSolver = class extends BaseSolver {
|
|
|
7030
7053
|
Math.floor(areaInsideNode / areaPerVia),
|
|
7031
7054
|
Math.ceil(uniqueConnections * 1.5)
|
|
7032
7055
|
);
|
|
7033
|
-
if (uniqueConnections > 5) {
|
|
7034
|
-
this.failed = true;
|
|
7035
|
-
this.error = `Limit is currently set to 6 unique connections, ${uniqueConnections} found`;
|
|
7036
|
-
return;
|
|
7037
|
-
}
|
|
7038
7056
|
if (this.minViaCount > this.SEGMENTS_PER_POLYLINE * (uniqueConnections / 2)) {
|
|
7039
7057
|
this.failed = true;
|
|
7040
7058
|
this.error = `Not possible to solve problem with given SEGMENTS_PER_POLYLINE (${this.SEGMENTS_PER_POLYLINE}), atleast ${this.minViaCount} vias are required`;
|
|
@@ -7773,7 +7791,7 @@ var MultiHeadPolyLineIntraNodeSolver = class extends BaseSolver {
|
|
|
7773
7791
|
strokeColor: segmentColor,
|
|
7774
7792
|
strokeWidth: this.traceWidth,
|
|
7775
7793
|
// TODO: Use actual trace thickness from HighDensityRoute?
|
|
7776
|
-
strokeDash: !isLayer0 ?
|
|
7794
|
+
strokeDash: !isLayer0 ? [0.15, 0.15] : void 0,
|
|
7777
7795
|
// Dashed for layers > 0
|
|
7778
7796
|
label: `${polyLine.connectionName} segment (z=${segmentLayer})`
|
|
7779
7797
|
});
|
|
@@ -8502,7 +8520,7 @@ var HighDensitySolver = class extends BaseSolver {
|
|
|
8502
8520
|
if (this.failedSolvers.length > 0) {
|
|
8503
8521
|
this.solved = false;
|
|
8504
8522
|
this.failed = true;
|
|
8505
|
-
this.error = `Failed to solve ${this.failedSolvers.length} nodes`;
|
|
8523
|
+
this.error = `Failed to solve ${this.failedSolvers.length} nodes, ${this.failedSolvers.slice(0, 5).map((fs) => fs.nodeWithPortPoints.capacityMeshNodeId)}`;
|
|
8506
8524
|
return;
|
|
8507
8525
|
}
|
|
8508
8526
|
this.solved = true;
|
|
@@ -8574,7 +8592,8 @@ var HighDensitySolver = class extends BaseSolver {
|
|
|
8574
8592
|
graphics.lines.push({
|
|
8575
8593
|
points: [start, end],
|
|
8576
8594
|
strokeColor: "red",
|
|
8577
|
-
strokeDash: "10, 5"
|
|
8595
|
+
strokeDash: "10, 5",
|
|
8596
|
+
layer: "did_not_connect"
|
|
8578
8597
|
});
|
|
8579
8598
|
}
|
|
8580
8599
|
}
|
|
@@ -11476,7 +11495,7 @@ ${percent}% (Pf: ${(probabilityOfFailure * 100).toFixed(1)}%)`;
|
|
|
11476
11495
|
}
|
|
11477
11496
|
|
|
11478
11497
|
// lib/solvers/CapacityPathingSectionSolver/CapacityPathingSingleSectionPathingSolver.ts
|
|
11479
|
-
var
|
|
11498
|
+
var CapacityPathingSingleSectionSolver = class extends BaseSolver {
|
|
11480
11499
|
GREEDY_MULTIPLIER = 1.5;
|
|
11481
11500
|
sectionNodes;
|
|
11482
11501
|
sectionEdges;
|
|
@@ -11488,6 +11507,7 @@ var CapacityPathingSingleSectionPathingSolver = class extends BaseSolver {
|
|
|
11488
11507
|
colorMap;
|
|
11489
11508
|
usedNodeCapacityMap;
|
|
11490
11509
|
// Tracks capacity usage *within this solver's run*
|
|
11510
|
+
centerNodeId;
|
|
11491
11511
|
MAX_CANDIDATES_IN_MEMORY = 1e4;
|
|
11492
11512
|
// A* state
|
|
11493
11513
|
currentConnectionIndex = 0;
|
|
@@ -11501,6 +11521,7 @@ var CapacityPathingSingleSectionPathingSolver = class extends BaseSolver {
|
|
|
11501
11521
|
// Default, similar to CapacityPathingSolver5
|
|
11502
11522
|
constructor(params) {
|
|
11503
11523
|
super();
|
|
11524
|
+
this.centerNodeId = params.centerNodeId;
|
|
11504
11525
|
this.sectionNodes = params.sectionNodes;
|
|
11505
11526
|
this.sectionEdges = params.sectionEdges;
|
|
11506
11527
|
this.sectionConnectionTerminals = params.sectionConnectionTerminals.map(
|
|
@@ -11674,6 +11695,28 @@ var CapacityPathingSingleSectionPathingSolver = class extends BaseSolver {
|
|
|
11674
11695
|
candidates.push(newCandidate);
|
|
11675
11696
|
}
|
|
11676
11697
|
}
|
|
11698
|
+
computeProgress() {
|
|
11699
|
+
const totalConnections = this.sectionConnectionTerminals.length;
|
|
11700
|
+
if (totalConnections === 0) return 1;
|
|
11701
|
+
const completedConnections = this.currentConnectionIndex;
|
|
11702
|
+
let progress = completedConnections / totalConnections;
|
|
11703
|
+
if (this.currentConnectionIndex < totalConnections && this.candidates && this.candidates.length > 0 && this.activeCandidateStraightLineDistance && this.activeCandidateStraightLineDistance > 0) {
|
|
11704
|
+
const bestCandidate = this.candidates.reduce(
|
|
11705
|
+
(best, current) => current.f < best.f ? current : best
|
|
11706
|
+
);
|
|
11707
|
+
const currentConnectionProgress = Math.max(
|
|
11708
|
+
0,
|
|
11709
|
+
Math.min(
|
|
11710
|
+
1,
|
|
11711
|
+
1 - bestCandidate.h / this.activeCandidateStraightLineDistance
|
|
11712
|
+
)
|
|
11713
|
+
);
|
|
11714
|
+
progress += currentConnectionProgress / totalConnections;
|
|
11715
|
+
} else if (this.solved) {
|
|
11716
|
+
progress = 1;
|
|
11717
|
+
}
|
|
11718
|
+
return Math.min(1, progress);
|
|
11719
|
+
}
|
|
11677
11720
|
_setupAStar(startNode, endNode) {
|
|
11678
11721
|
this.candidates = [
|
|
11679
11722
|
{ prevCandidate: null, node: startNode, f: 0, g: 0, h: 0 }
|
|
@@ -11778,133 +11821,157 @@ var CapacityPathingSingleSectionPathingSolver = class extends BaseSolver {
|
|
|
11778
11821
|
return baseGraphics;
|
|
11779
11822
|
}
|
|
11780
11823
|
};
|
|
11824
|
+
var CapacityPathingSingleSectionPathingSolver = CapacityPathingSingleSectionSolver;
|
|
11781
11825
|
|
|
11782
|
-
// lib/solvers/CapacityPathingSectionSolver/
|
|
11783
|
-
var
|
|
11784
|
-
|
|
11785
|
-
|
|
11786
|
-
nodes;
|
|
11787
|
-
nodeMap;
|
|
11788
|
-
edges;
|
|
11789
|
-
nodeEdgeMap;
|
|
11790
|
-
expansionDegrees;
|
|
11791
|
-
colorMap;
|
|
11792
|
-
sectionNodes;
|
|
11793
|
-
sectionEdges;
|
|
11794
|
-
// Added sectionEdges property
|
|
11795
|
-
sectionConnectionTerminals;
|
|
11796
|
-
activeSubSolver = null;
|
|
11826
|
+
// lib/solvers/CapacityPathingSectionSolver/HyperCapacityPathingSingleSectionSolver.ts
|
|
11827
|
+
var HyperCapacityPathingSingleSectionSolver = class extends HyperParameterSupervisorSolver {
|
|
11828
|
+
constructorParams;
|
|
11829
|
+
winningSolver;
|
|
11797
11830
|
constructor(params) {
|
|
11798
11831
|
super();
|
|
11799
|
-
this.MAX_ITERATIONS =
|
|
11800
|
-
this.
|
|
11801
|
-
this.centerNodeId = params.centerNodeId;
|
|
11802
|
-
this.connectionsWithNodes = params.connectionsWithNodes;
|
|
11803
|
-
this.nodes = params.nodes;
|
|
11804
|
-
this.nodeMap = new Map(this.nodes.map((n) => [n.capacityMeshNodeId, n]));
|
|
11805
|
-
this.edges = params.edges;
|
|
11806
|
-
this.nodeEdgeMap = getNodeEdgeMap(this.edges);
|
|
11807
|
-
this.expansionDegrees = params.hyperParameters?.EXPANSION_DEGREES ?? 3;
|
|
11808
|
-
this.sectionNodes = [];
|
|
11809
|
-
this.sectionEdges = [];
|
|
11810
|
-
this.sectionConnectionTerminals = [];
|
|
11811
|
-
this.computeSectionNodesTerminalsAndEdges();
|
|
11812
|
-
this.activeSubSolver = new CapacityPathingSingleSectionPathingSolver({
|
|
11813
|
-
sectionConnectionTerminals: this.sectionConnectionTerminals,
|
|
11814
|
-
sectionNodes: this.sectionNodes,
|
|
11815
|
-
sectionEdges: this.sectionEdges,
|
|
11816
|
-
colorMap: this.colorMap,
|
|
11817
|
-
hyperParameters: params.hyperParameters
|
|
11818
|
-
});
|
|
11832
|
+
this.MAX_ITERATIONS = 1e4;
|
|
11833
|
+
this.constructorParams = params;
|
|
11819
11834
|
}
|
|
11820
|
-
|
|
11821
|
-
|
|
11822
|
-
const queue = [
|
|
11823
|
-
{ nodeId: this.centerNodeId, depth: 0 }
|
|
11824
|
-
];
|
|
11825
|
-
sectionNodeIds.add(this.centerNodeId);
|
|
11826
|
-
let head = 0;
|
|
11827
|
-
while (head < queue.length) {
|
|
11828
|
-
const { nodeId, depth } = queue[head++];
|
|
11829
|
-
if (depth >= this.expansionDegrees) continue;
|
|
11830
|
-
const neighbors = this.nodeEdgeMap.get(nodeId)?.flatMap((edge) => edge.nodeIds.filter((id) => id !== nodeId)) ?? [];
|
|
11831
|
-
for (const neighborId of neighbors) {
|
|
11832
|
-
if (!sectionNodeIds.has(neighborId)) {
|
|
11833
|
-
sectionNodeIds.add(neighborId);
|
|
11834
|
-
queue.push({ nodeId: neighborId, depth: depth + 1 });
|
|
11835
|
-
}
|
|
11836
|
-
}
|
|
11837
|
-
}
|
|
11838
|
-
this.sectionNodes = Array.from(sectionNodeIds).map(
|
|
11839
|
-
(id) => this.nodeMap.get(id)
|
|
11840
|
-
);
|
|
11841
|
-
this.sectionEdges = this.edges.filter((edge) => {
|
|
11842
|
-
const [nodeIdA, nodeIdB] = edge.nodeIds;
|
|
11843
|
-
return sectionNodeIds.has(nodeIdA) && sectionNodeIds.has(nodeIdB);
|
|
11844
|
-
});
|
|
11845
|
-
this.sectionConnectionTerminals = [];
|
|
11846
|
-
for (const conn of this.connectionsWithNodes) {
|
|
11847
|
-
if (!conn.path) continue;
|
|
11848
|
-
let startNodeId = null;
|
|
11849
|
-
let endNodeId = null;
|
|
11850
|
-
for (const node of conn.path) {
|
|
11851
|
-
if (sectionNodeIds.has(node.capacityMeshNodeId)) {
|
|
11852
|
-
startNodeId = node.capacityMeshNodeId;
|
|
11853
|
-
break;
|
|
11854
|
-
}
|
|
11855
|
-
}
|
|
11856
|
-
for (let i = conn.path.length - 1; i >= 0; i--) {
|
|
11857
|
-
const node = conn.path[i];
|
|
11858
|
-
if (sectionNodeIds.has(node.capacityMeshNodeId)) {
|
|
11859
|
-
endNodeId = node.capacityMeshNodeId;
|
|
11860
|
-
break;
|
|
11861
|
-
}
|
|
11862
|
-
}
|
|
11863
|
-
if (startNodeId && endNodeId) {
|
|
11864
|
-
this.sectionConnectionTerminals.push({
|
|
11865
|
-
connectionName: conn.connection.name,
|
|
11866
|
-
startNodeId,
|
|
11867
|
-
endNodeId
|
|
11868
|
-
});
|
|
11869
|
-
}
|
|
11870
|
-
}
|
|
11835
|
+
computeG(solver) {
|
|
11836
|
+
return solver.iterations / 100;
|
|
11871
11837
|
}
|
|
11872
|
-
|
|
11873
|
-
|
|
11874
|
-
if (this.activeSubSolver?.solved) {
|
|
11875
|
-
this.solved = true;
|
|
11876
|
-
return;
|
|
11877
|
-
}
|
|
11878
|
-
if (this.activeSubSolver?.failed) {
|
|
11879
|
-
this.failed = true;
|
|
11880
|
-
this.error = this.activeSubSolver.error;
|
|
11881
|
-
return;
|
|
11882
|
-
}
|
|
11838
|
+
computeH(solver) {
|
|
11839
|
+
return solver.computeProgress();
|
|
11883
11840
|
}
|
|
11884
|
-
|
|
11841
|
+
getCombinationDefs() {
|
|
11842
|
+
return [["orderings10"]];
|
|
11843
|
+
}
|
|
11844
|
+
getFailureMessage() {
|
|
11845
|
+
return `All CapacityPathingSingleSection solvers failed for "${this.centerNodeId}"`;
|
|
11846
|
+
}
|
|
11847
|
+
getHyperParameterDefs() {
|
|
11885
11848
|
return [
|
|
11886
11849
|
{
|
|
11887
|
-
|
|
11888
|
-
|
|
11889
|
-
|
|
11890
|
-
|
|
11891
|
-
|
|
11850
|
+
name: "orderings10",
|
|
11851
|
+
possibleValues: [
|
|
11852
|
+
{
|
|
11853
|
+
SHUFFLE_SEED: 0
|
|
11854
|
+
},
|
|
11855
|
+
{
|
|
11856
|
+
SHUFFLE_SEED: 1
|
|
11857
|
+
},
|
|
11858
|
+
{
|
|
11859
|
+
SHUFFLE_SEED: 2
|
|
11860
|
+
},
|
|
11861
|
+
{
|
|
11862
|
+
SHUFFLE_SEED: 3
|
|
11863
|
+
},
|
|
11864
|
+
{
|
|
11865
|
+
SHUFFLE_SEED: 4
|
|
11866
|
+
},
|
|
11867
|
+
{
|
|
11868
|
+
SHUFFLE_SEED: 5
|
|
11869
|
+
},
|
|
11870
|
+
{
|
|
11871
|
+
SHUFFLE_SEED: 6
|
|
11872
|
+
},
|
|
11873
|
+
{
|
|
11874
|
+
SHUFFLE_SEED: 7
|
|
11875
|
+
},
|
|
11876
|
+
{
|
|
11877
|
+
SHUFFLE_SEED: 8
|
|
11878
|
+
},
|
|
11879
|
+
{
|
|
11880
|
+
SHUFFLE_SEED: 9
|
|
11881
|
+
}
|
|
11882
|
+
]
|
|
11892
11883
|
}
|
|
11893
11884
|
];
|
|
11894
11885
|
}
|
|
11895
|
-
|
|
11896
|
-
return
|
|
11897
|
-
|
|
11898
|
-
|
|
11899
|
-
|
|
11900
|
-
|
|
11901
|
-
|
|
11902
|
-
colorMap: this.colorMap,
|
|
11903
|
-
centerNodeId: this.centerNodeId,
|
|
11904
|
-
nodeOpacity: 1e-3,
|
|
11905
|
-
title: `Section Solver (Center: ${this.centerNodeId}, Hops: ${this.expansionDegrees})`
|
|
11886
|
+
generateSolver(hyperParameters) {
|
|
11887
|
+
return new CapacityPathingSingleSectionPathingSolver({
|
|
11888
|
+
...this.constructorParams,
|
|
11889
|
+
hyperParameters: {
|
|
11890
|
+
...this.constructorParams.hyperParameters,
|
|
11891
|
+
...hyperParameters
|
|
11892
|
+
}
|
|
11906
11893
|
});
|
|
11907
11894
|
}
|
|
11895
|
+
onSolve({
|
|
11896
|
+
solver
|
|
11897
|
+
}) {
|
|
11898
|
+
this.winningSolver = solver;
|
|
11899
|
+
}
|
|
11900
|
+
get centerNodeId() {
|
|
11901
|
+
return this.constructorParams.centerNodeId;
|
|
11902
|
+
}
|
|
11903
|
+
get sectionNodes() {
|
|
11904
|
+
return this.constructorParams.sectionNodes;
|
|
11905
|
+
}
|
|
11906
|
+
get sectionConnectionTerminals() {
|
|
11907
|
+
return this.winningSolver?.sectionConnectionTerminals;
|
|
11908
|
+
}
|
|
11909
|
+
};
|
|
11910
|
+
|
|
11911
|
+
// lib/solvers/CapacityPathingSectionSolver/computeSectionNodesTerminalsAndEdges.ts
|
|
11912
|
+
var computeSectionNodesTerminalsAndEdges = (opts) => {
|
|
11913
|
+
const {
|
|
11914
|
+
centerNodeId,
|
|
11915
|
+
connectionsWithNodes,
|
|
11916
|
+
nodeMap,
|
|
11917
|
+
edges,
|
|
11918
|
+
nodeEdgeMap,
|
|
11919
|
+
expansionDegrees
|
|
11920
|
+
} = opts;
|
|
11921
|
+
const sectionNodeIds = /* @__PURE__ */ new Set();
|
|
11922
|
+
const queue = [
|
|
11923
|
+
{ nodeId: centerNodeId, depth: 0 }
|
|
11924
|
+
];
|
|
11925
|
+
sectionNodeIds.add(centerNodeId);
|
|
11926
|
+
let head = 0;
|
|
11927
|
+
while (head < queue.length) {
|
|
11928
|
+
const { nodeId, depth } = queue[head++];
|
|
11929
|
+
if (depth >= expansionDegrees) continue;
|
|
11930
|
+
const neighbors = nodeEdgeMap.get(nodeId)?.flatMap((edge) => edge.nodeIds.filter((id) => id !== nodeId)) ?? [];
|
|
11931
|
+
for (const neighborId of neighbors) {
|
|
11932
|
+
if (!sectionNodeIds.has(neighborId)) {
|
|
11933
|
+
sectionNodeIds.add(neighborId);
|
|
11934
|
+
queue.push({ nodeId: neighborId, depth: depth + 1 });
|
|
11935
|
+
}
|
|
11936
|
+
}
|
|
11937
|
+
}
|
|
11938
|
+
const sectionNodes = Array.from(sectionNodeIds).map((id) => nodeMap.get(id));
|
|
11939
|
+
const sectionEdges = edges.filter((edge) => {
|
|
11940
|
+
const [nodeIdA, nodeIdB] = edge.nodeIds;
|
|
11941
|
+
return sectionNodeIds.has(nodeIdA) && sectionNodeIds.has(nodeIdB);
|
|
11942
|
+
});
|
|
11943
|
+
const sectionConnectionTerminals = [];
|
|
11944
|
+
for (const conn of connectionsWithNodes) {
|
|
11945
|
+
if (!conn.path) continue;
|
|
11946
|
+
let startNodeId = null;
|
|
11947
|
+
let endNodeId = null;
|
|
11948
|
+
for (const node of conn.path) {
|
|
11949
|
+
if (sectionNodeIds.has(node.capacityMeshNodeId)) {
|
|
11950
|
+
startNodeId = node.capacityMeshNodeId;
|
|
11951
|
+
break;
|
|
11952
|
+
}
|
|
11953
|
+
}
|
|
11954
|
+
for (let i = conn.path.length - 1; i >= 0; i--) {
|
|
11955
|
+
const node = conn.path[i];
|
|
11956
|
+
if (sectionNodeIds.has(node.capacityMeshNodeId)) {
|
|
11957
|
+
endNodeId = node.capacityMeshNodeId;
|
|
11958
|
+
break;
|
|
11959
|
+
}
|
|
11960
|
+
}
|
|
11961
|
+
if (startNodeId && endNodeId) {
|
|
11962
|
+
sectionConnectionTerminals.push({
|
|
11963
|
+
connectionName: conn.connection.name,
|
|
11964
|
+
startNodeId,
|
|
11965
|
+
endNodeId
|
|
11966
|
+
});
|
|
11967
|
+
}
|
|
11968
|
+
}
|
|
11969
|
+
return {
|
|
11970
|
+
sectionConnectionTerminals,
|
|
11971
|
+
sectionNodes,
|
|
11972
|
+
sectionEdges,
|
|
11973
|
+
centerNodeId
|
|
11974
|
+
};
|
|
11908
11975
|
};
|
|
11909
11976
|
|
|
11910
11977
|
// lib/solvers/CapacityPathingSectionSolver/CapacityPathingMultiSectionSolver.ts
|
|
@@ -11912,6 +11979,7 @@ var CapacityPathingMultiSectionSolver = class extends BaseSolver {
|
|
|
11912
11979
|
simpleRouteJson;
|
|
11913
11980
|
nodes;
|
|
11914
11981
|
edges;
|
|
11982
|
+
nodeEdgeMap;
|
|
11915
11983
|
connectionsWithNodes = [];
|
|
11916
11984
|
// Initialize here
|
|
11917
11985
|
colorMap;
|
|
@@ -11923,6 +11991,7 @@ var CapacityPathingMultiSectionSolver = class extends BaseSolver {
|
|
|
11923
11991
|
// Added
|
|
11924
11992
|
nodeCapacityPercentMap = /* @__PURE__ */ new Map();
|
|
11925
11993
|
nodeOptimizationAttemptCountMap = /* @__PURE__ */ new Map();
|
|
11994
|
+
currentSection = null;
|
|
11926
11995
|
sectionSolver = null;
|
|
11927
11996
|
MAX_ATTEMPTS_PER_NODE = 10;
|
|
11928
11997
|
MINIMUM_PROBABILITY_OF_FAILURE_TO_OPTIMIZE = 0.05;
|
|
@@ -11937,6 +12006,7 @@ var CapacityPathingMultiSectionSolver = class extends BaseSolver {
|
|
|
11937
12006
|
this.nodeMap = new Map(
|
|
11938
12007
|
this.nodes.map((node) => [node.capacityMeshNodeId, node])
|
|
11939
12008
|
);
|
|
12009
|
+
this.nodeEdgeMap = getNodeEdgeMap(this.edges);
|
|
11940
12010
|
this.initialSolver = new CapacityPathingGreedySolver({
|
|
11941
12011
|
simpleRouteJson: this.simpleRouteJson,
|
|
11942
12012
|
nodes: this.nodes,
|
|
@@ -12002,16 +12072,21 @@ var CapacityPathingMultiSectionSolver = class extends BaseSolver {
|
|
|
12002
12072
|
this.solved = true;
|
|
12003
12073
|
return;
|
|
12004
12074
|
}
|
|
12005
|
-
|
|
12075
|
+
const section = computeSectionNodesTerminalsAndEdges({
|
|
12006
12076
|
centerNodeId,
|
|
12007
12077
|
connectionsWithNodes: this.connectionsWithNodes,
|
|
12008
|
-
|
|
12078
|
+
nodeMap: this.nodeMap,
|
|
12009
12079
|
edges: this.edges,
|
|
12080
|
+
expansionDegrees: this.MAX_EXPANSION_DEGREES,
|
|
12081
|
+
nodeEdgeMap: this.nodeEdgeMap
|
|
12082
|
+
});
|
|
12083
|
+
this.currentSection = section;
|
|
12084
|
+
this.sectionSolver = new HyperCapacityPathingSingleSectionSolver({
|
|
12085
|
+
sectionConnectionTerminals: section.sectionConnectionTerminals,
|
|
12086
|
+
sectionEdges: section.sectionEdges,
|
|
12087
|
+
sectionNodes: section.sectionNodes,
|
|
12010
12088
|
colorMap: this.colorMap,
|
|
12011
|
-
|
|
12012
|
-
EXPANSION_DEGREES: this.MAX_EXPANSION_DEGREES,
|
|
12013
|
-
SHUFFLE_SEED: this.iterations
|
|
12014
|
-
}
|
|
12089
|
+
centerNodeId: section.centerNodeId
|
|
12015
12090
|
});
|
|
12016
12091
|
this.activeSubSolver = this.sectionSolver;
|
|
12017
12092
|
this.nodeOptimizationAttemptCountMap.set(
|
|
@@ -12022,7 +12097,7 @@ var CapacityPathingMultiSectionSolver = class extends BaseSolver {
|
|
|
12022
12097
|
this.sectionSolver.step();
|
|
12023
12098
|
if (this.sectionSolver.failed) {
|
|
12024
12099
|
console.warn(
|
|
12025
|
-
`Section solver failed for node ${this.
|
|
12100
|
+
`Section solver failed for node ${this.currentSection.centerNodeId}. Error: ${this.sectionSolver.error}`
|
|
12026
12101
|
);
|
|
12027
12102
|
this.sectionSolver = null;
|
|
12028
12103
|
this.activeSubSolver = null;
|
|
@@ -12030,12 +12105,12 @@ var CapacityPathingMultiSectionSolver = class extends BaseSolver {
|
|
|
12030
12105
|
}
|
|
12031
12106
|
if (this.sectionSolver.solved) {
|
|
12032
12107
|
const solvedSectionSolver = this.sectionSolver;
|
|
12033
|
-
const pathingSolver = solvedSectionSolver
|
|
12108
|
+
const pathingSolver = solvedSectionSolver?.activeSubSolver || solvedSectionSolver;
|
|
12034
12109
|
this.sectionSolver = null;
|
|
12035
12110
|
this.activeSubSolver = null;
|
|
12036
12111
|
if (!pathingSolver || !pathingSolver.solved) {
|
|
12037
12112
|
console.warn(
|
|
12038
|
-
`Pathing sub-solver for section ${
|
|
12113
|
+
`Pathing sub-solver for section ${this.currentSection.centerNodeId} did not complete successfully. Discarding results.`
|
|
12039
12114
|
);
|
|
12040
12115
|
return;
|
|
12041
12116
|
}
|
|
@@ -12096,18 +12171,18 @@ var CapacityPathingMultiSectionSolver = class extends BaseSolver {
|
|
|
12096
12171
|
* connectionsWithNodes list.
|
|
12097
12172
|
*/
|
|
12098
12173
|
_mergeSolvedSectionPaths(solvedSectionSolver) {
|
|
12099
|
-
const
|
|
12100
|
-
if (!
|
|
12174
|
+
const centerNodeId = solvedSectionSolver.centerNodeId;
|
|
12175
|
+
if (!solvedSectionSolver || !solvedSectionSolver.solved) {
|
|
12101
12176
|
console.warn(
|
|
12102
|
-
`Pathing sub-solver for section ${
|
|
12177
|
+
`Pathing sub-solver for section ${centerNodeId} did not complete successfully. Skipping merge.`
|
|
12103
12178
|
);
|
|
12104
12179
|
return;
|
|
12105
12180
|
}
|
|
12106
|
-
const solvedTerminals =
|
|
12181
|
+
const solvedTerminals = solvedSectionSolver.sectionConnectionTerminals;
|
|
12107
12182
|
for (const solvedTerminal of solvedTerminals) {
|
|
12108
12183
|
if (!solvedTerminal.path) {
|
|
12109
12184
|
console.warn(
|
|
12110
|
-
`No path found for connection ${solvedTerminal.connectionName} in section ${
|
|
12185
|
+
`No path found for connection ${solvedTerminal.connectionName} in section ${centerNodeId}`
|
|
12111
12186
|
);
|
|
12112
12187
|
continue;
|
|
12113
12188
|
}
|