@tscircuit/capacity-autorouter 0.0.87 → 0.0.89
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 +11 -0
- package/dist/index.js +52 -4
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -35,8 +35,10 @@ interface SimpleRouteConnection {
|
|
|
35
35
|
x: number;
|
|
36
36
|
y: number;
|
|
37
37
|
layer: string;
|
|
38
|
+
pointId?: string;
|
|
38
39
|
pcb_port_id?: string;
|
|
39
40
|
}>;
|
|
41
|
+
externallyConnectedPointIds?: string[][];
|
|
40
42
|
}
|
|
41
43
|
interface SimplifiedPcbTrace {
|
|
42
44
|
type: "pcb_trace";
|
|
@@ -114,6 +116,12 @@ declare class BaseSolver {
|
|
|
114
116
|
getConstructorParams(): void;
|
|
115
117
|
solve(): void;
|
|
116
118
|
visualize(): GraphicsObject;
|
|
119
|
+
/**
|
|
120
|
+
* Called when the solver is about to fail, but we want to see if we have an
|
|
121
|
+
* "acceptable" or "passable" solution. Mostly used for optimizers that
|
|
122
|
+
* have an aggressive early stopping criterion.
|
|
123
|
+
*/
|
|
124
|
+
tryFinalAcceptance(): void;
|
|
117
125
|
/**
|
|
118
126
|
* A lightweight version of the visualize method that can be used to stream
|
|
119
127
|
* progress
|
|
@@ -422,6 +430,7 @@ interface HighDensityHyperParameters {
|
|
|
422
430
|
SEGMENTS_PER_POLYLINE: number;
|
|
423
431
|
BOUNDARY_PADDING: number;
|
|
424
432
|
ITERATION_PENALTY: number;
|
|
433
|
+
MINIMUM_FINAL_ACCEPTANCE_GAP?: number;
|
|
425
434
|
}
|
|
426
435
|
|
|
427
436
|
type Node = {
|
|
@@ -762,11 +771,13 @@ declare class HyperSingleIntraNodeSolver extends HyperParameterSupervisorSolver<
|
|
|
762
771
|
SEGMENTS_PER_POLYLINE: number;
|
|
763
772
|
BOUNDARY_PADDING: number;
|
|
764
773
|
ITERATION_PENALTY?: undefined;
|
|
774
|
+
MINIMUM_FINAL_ACCEPTANCE_GAP?: undefined;
|
|
765
775
|
} | {
|
|
766
776
|
MULTI_HEAD_POLYLINE_SOLVER: boolean;
|
|
767
777
|
SEGMENTS_PER_POLYLINE: number;
|
|
768
778
|
BOUNDARY_PADDING: number;
|
|
769
779
|
ITERATION_PENALTY: number;
|
|
780
|
+
MINIMUM_FINAL_ACCEPTANCE_GAP: number;
|
|
770
781
|
})[];
|
|
771
782
|
})[];
|
|
772
783
|
computeG(solver: IntraNodeRouteSolver): number;
|
package/dist/index.js
CHANGED
|
@@ -67,6 +67,9 @@ var BaseSolver = class {
|
|
|
67
67
|
this.failed = true;
|
|
68
68
|
throw e;
|
|
69
69
|
}
|
|
70
|
+
if (!this.solved && this.iterations > this.MAX_ITERATIONS) {
|
|
71
|
+
this.tryFinalAcceptance();
|
|
72
|
+
}
|
|
70
73
|
if (!this.solved && this.iterations > this.MAX_ITERATIONS) {
|
|
71
74
|
this.error = `${this.constructor.name} ran out of iterations`;
|
|
72
75
|
console.error(this.error);
|
|
@@ -97,6 +100,13 @@ var BaseSolver = class {
|
|
|
97
100
|
circles: []
|
|
98
101
|
};
|
|
99
102
|
}
|
|
103
|
+
/**
|
|
104
|
+
* Called when the solver is about to fail, but we want to see if we have an
|
|
105
|
+
* "acceptable" or "passable" solution. Mostly used for optimizers that
|
|
106
|
+
* have an aggressive early stopping criterion.
|
|
107
|
+
*/
|
|
108
|
+
tryFinalAcceptance() {
|
|
109
|
+
}
|
|
100
110
|
/**
|
|
101
111
|
* A lightweight version of the visualize method that can be used to stream
|
|
102
112
|
* progress
|
|
@@ -8172,6 +8182,21 @@ var MultiHeadPolyLineIntraNodeSolver = class extends BaseSolver {
|
|
|
8172
8182
|
});
|
|
8173
8183
|
return minGapsToOtherConnectionsValid && allPointsWithinBounds;
|
|
8174
8184
|
}
|
|
8185
|
+
// ------------------------------------------------------------------
|
|
8186
|
+
// Try accepting the best candidate even if normal solving failed.
|
|
8187
|
+
// ------------------------------------------------------------------
|
|
8188
|
+
tryFinalAcceptance() {
|
|
8189
|
+
const minGapTarget = this.hyperParameters?.MINIMUM_FINAL_ACCEPTANCE_GAP ?? void 0;
|
|
8190
|
+
if (minGapTarget === void 0 || this.lastCandidate === null || this.lastCandidate.minGaps.length === 0)
|
|
8191
|
+
return;
|
|
8192
|
+
const minGapAchieved = Math.min(...this.lastCandidate.minGaps);
|
|
8193
|
+
if (minGapAchieved >= minGapTarget) {
|
|
8194
|
+
this.solved = true;
|
|
8195
|
+
this._setSolvedRoutes();
|
|
8196
|
+
return;
|
|
8197
|
+
}
|
|
8198
|
+
return;
|
|
8199
|
+
}
|
|
8175
8200
|
_step() {
|
|
8176
8201
|
if (this.phase === "setup") {
|
|
8177
8202
|
this.setupInitialPolyLines();
|
|
@@ -8180,6 +8205,8 @@ var MultiHeadPolyLineIntraNodeSolver = class extends BaseSolver {
|
|
|
8180
8205
|
}
|
|
8181
8206
|
const currentCandidate = this.candidates.shift();
|
|
8182
8207
|
if (!currentCandidate) {
|
|
8208
|
+
this.tryFinalAcceptance();
|
|
8209
|
+
if (this.solved) return;
|
|
8183
8210
|
this.failed = true;
|
|
8184
8211
|
this.error = "No candidates left";
|
|
8185
8212
|
return;
|
|
@@ -8413,6 +8440,8 @@ var MultiHeadPolyLineIntraNodeSolver2 = class extends MultiHeadPolyLineIntraNode
|
|
|
8413
8440
|
}
|
|
8414
8441
|
const currentCandidate = this.candidates.shift();
|
|
8415
8442
|
if (!currentCandidate) {
|
|
8443
|
+
this.tryFinalAcceptance();
|
|
8444
|
+
if (this.solved) return;
|
|
8416
8445
|
this.failed = true;
|
|
8417
8446
|
return;
|
|
8418
8447
|
}
|
|
@@ -9063,7 +9092,8 @@ var HyperSingleIntraNodeSolver = class extends HyperParameterSupervisorSolver {
|
|
|
9063
9092
|
SEGMENTS_PER_POLYLINE: 6,
|
|
9064
9093
|
BOUNDARY_PADDING: -0.05,
|
|
9065
9094
|
// Allow vias/traces outside the boundary
|
|
9066
|
-
ITERATION_PENALTY: 1e4
|
|
9095
|
+
ITERATION_PENALTY: 1e4,
|
|
9096
|
+
MINIMUM_FINAL_ACCEPTANCE_GAP: 1e-3
|
|
9067
9097
|
}
|
|
9068
9098
|
]
|
|
9069
9099
|
}
|
|
@@ -9585,16 +9615,34 @@ var NetToPointPairsSolver = class extends BaseSolver {
|
|
|
9585
9615
|
return;
|
|
9586
9616
|
}
|
|
9587
9617
|
const connection = this.unprocessedConnections.pop();
|
|
9618
|
+
const externalGroups = connection.externallyConnectedPointIds ?? [];
|
|
9619
|
+
const pointIdToGroup = /* @__PURE__ */ new Map();
|
|
9620
|
+
externalGroups.forEach(
|
|
9621
|
+
(group, idx) => group.forEach((pid) => pointIdToGroup.set(pid, idx))
|
|
9622
|
+
);
|
|
9623
|
+
const areExternallyConnected = (a, b) => {
|
|
9624
|
+
if (!a.pointId || !b.pointId) return false;
|
|
9625
|
+
const g1 = pointIdToGroup.get(a.pointId);
|
|
9626
|
+
const g2 = pointIdToGroup.get(b.pointId);
|
|
9627
|
+
return g1 !== void 0 && g1 === g2;
|
|
9628
|
+
};
|
|
9588
9629
|
if (connection.pointsToConnect.length === 2) {
|
|
9630
|
+
if (areExternallyConnected(
|
|
9631
|
+
connection.pointsToConnect[0],
|
|
9632
|
+
connection.pointsToConnect[1]
|
|
9633
|
+
)) {
|
|
9634
|
+
return;
|
|
9635
|
+
}
|
|
9589
9636
|
this.newConnections.push(connection);
|
|
9590
9637
|
return;
|
|
9591
9638
|
}
|
|
9592
9639
|
const edges = buildMinimumSpanningTree(connection.pointsToConnect);
|
|
9593
|
-
|
|
9594
|
-
|
|
9640
|
+
let mstIdx = 0;
|
|
9641
|
+
for (const edge of edges) {
|
|
9642
|
+
if (areExternallyConnected(edge.from, edge.to)) continue;
|
|
9595
9643
|
this.newConnections.push({
|
|
9596
9644
|
pointsToConnect: [edge.from, edge.to],
|
|
9597
|
-
name: `${connection.name}_mst${
|
|
9645
|
+
name: `${connection.name}_mst${mstIdx++}`
|
|
9598
9646
|
});
|
|
9599
9647
|
}
|
|
9600
9648
|
}
|