@tscircuit/capacity-autorouter 0.0.189 → 0.0.191

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  import * as graphics_debug from 'graphics-debug';
2
2
  import { GraphicsObject, Rect, Circle, Line, Point as Point$3 } from 'graphics-debug';
3
3
  import { ConnectivityMap } from 'circuit-json-to-connectivity-map';
4
- import { RectDiffSolver } from '@tscircuit/rectdiff';
4
+ import { RectDiffPipeline } from '@tscircuit/rectdiff';
5
5
  import { Polygon } from '@tscircuit/math-utils';
6
6
 
7
7
  type TraceId = string;
@@ -42,6 +42,7 @@ interface SimpleRouteJson {
42
42
  traces?: SimplifiedPcbTraces;
43
43
  }
44
44
  interface Obstacle {
45
+ obstacleId?: string;
45
46
  type: "rect";
46
47
  layers: string[];
47
48
  zLayers?: number[];
@@ -107,6 +108,8 @@ interface CapacityMeshNode {
107
108
  _isVirtualOffboard?: boolean;
108
109
  _offboardNetName?: string;
109
110
  _adjacentNodeIds?: CapacityMeshNodeId[];
111
+ _offBoardConnectionId?: string;
112
+ _offBoardConnectedCapacityMeshNodeIds?: CapacityMeshNodeId[];
110
113
  _parent?: CapacityMeshNode;
111
114
  }
112
115
  interface CapacityMeshEdge {
@@ -1094,10 +1097,15 @@ interface PortPointPathingHyperParameters {
1094
1097
  GREEDY_MULTIPLIER?: number;
1095
1098
  NODE_PF_FACTOR?: number;
1096
1099
  RANDOM_COST_MAGNITUDE?: number;
1100
+ NODE_PF_MAX_PENALTY?: number;
1097
1101
  MEMORY_PF_FACTOR?: number;
1098
1102
  BASE_CANDIDATE_COST?: number;
1099
- REWARD_LOW_TRAVEL_PF_MAGNITUDE?: number;
1103
+ MIN_ALLOWED_BOARD_SCORE?: number;
1100
1104
  MAX_ITERATIONS_PER_PATH?: number;
1105
+ FORCE_CENTER_FIRST?: boolean;
1106
+ RANDOM_WALK_DISTANCE?: number;
1107
+ FORCE_OFF_BOARD_FREQUENCY?: number;
1108
+ FORCE_OFF_BOARD_SEED?: number;
1101
1109
  }
1102
1110
  /**
1103
1111
  * An input port point without connectionName assigned yet.
@@ -1112,6 +1120,7 @@ interface InputPortPoint {
1112
1120
  connectionNodeIds: [CapacityMeshNodeId, CapacityMeshNodeId];
1113
1121
  /** XY distance to the centermost port on this Z level (centermost port has distance 0) */
1114
1122
  distToCentermostPortOnZ: number;
1123
+ connectsToOffBoardNode?: boolean;
1115
1124
  }
1116
1125
  /**
1117
1126
  * A node with pre-computed port points (without connectionName assigned).
@@ -1132,6 +1141,8 @@ interface InputNodeWithPortPoints {
1132
1141
  _containsTarget?: boolean;
1133
1142
  /** If true, this node contains an obstacle */
1134
1143
  _containsObstacle?: boolean;
1144
+ _offBoardConnectionId?: string;
1145
+ _offBoardConnectedCapacityMeshNodeIds?: CapacityMeshNodeId[];
1135
1146
  }
1136
1147
  /**
1137
1148
  * A candidate in the A* search. Represents being at a port point,
@@ -1153,6 +1164,11 @@ interface PortPointCandidate {
1153
1164
  f: number;
1154
1165
  g: number;
1155
1166
  h: number;
1167
+ /** Total distance traveled from start to this candidate */
1168
+ distanceTraveled: number;
1169
+ /** Whether this candidate has ever crossed through an off-board node */
1170
+ hasTouchedOffBoardNode?: boolean;
1171
+ lastMoveWasOffBoard?: boolean;
1156
1172
  }
1157
1173
  interface ConnectionPathResult {
1158
1174
  connection: SimpleRouteConnection;
@@ -1197,25 +1213,33 @@ declare class PortPointPathingSolver extends BaseSolver {
1197
1213
  nodeAssignedPortPoints: Map<CapacityMeshNodeId, PortPoint[]>;
1198
1214
  /** Factor applied to port point reuse penalty */
1199
1215
  PORT_POINT_REUSE_FACTOR: number;
1216
+ /**
1217
+ * Cost when a node doesn't go off board when it's supposed to w/ the
1218
+ * FORCE_OFF_BOARD_FREQUENCY setting.
1219
+ */
1220
+ BASE_COST_FOR_NOT_GOING_OFF_BOARD: number;
1200
1221
  /** Multiplied by Pf delta cost (in -log(1-pf) space) */
1201
1222
  get NODE_PF_FACTOR(): number;
1223
+ get RANDOM_WALK_DISTANCE(): number;
1202
1224
  /** Used only in heuristic (h) to "look ahead" into known-congested regions */
1203
1225
  get MEMORY_PF_FACTOR(): number;
1204
1226
  get CENTER_OFFSET_FOCUS_SHIFT(): number;
1205
1227
  /** Used as a *tie-breaker* in f (not part of g) */
1206
1228
  get RANDOM_COST_MAGNITUDE(): number;
1207
- /** Optional heuristic reward for stepping into low-memoryPf nodes */
1208
- get REWARD_LOW_TRAVEL_PF_MAGNITUDE(): number;
1209
1229
  /** Cost of adding a candidate to the path */
1210
1230
  get BASE_CANDIDATE_COST(): number;
1211
- /** Cost penalty for changing layers (used in heuristic) */
1212
- Z_DIST_COST: number;
1231
+ get NODE_PF_MAX_PENALTY(): number;
1232
+ get FORCE_CENTER_FIRST(): boolean;
1233
+ get FORCE_OFF_BOARD_FREQUENCY(): number;
1234
+ get FORCE_OFF_BOARD_SEED(): number;
1235
+ get NODE_MAX_PF(): number;
1213
1236
  /** Penalty factor for port points that are far from the center of the segment */
1214
1237
  get CENTER_OFFSET_DIST_PENALTY_FACTOR(): number;
1215
1238
  colorMap: Record<string, string>;
1216
1239
  get GREEDY_MULTIPLIER(): number;
1217
1240
  MAX_CANDIDATES_IN_MEMORY: number;
1218
1241
  get MAX_ITERATIONS_PER_PATH(): number;
1242
+ get MIN_ALLOWED_BOARD_SCORE(): number;
1219
1243
  nodeMemoryPfMap: Map<CapacityMeshNodeId, number>;
1220
1244
  currentConnectionIndex: number;
1221
1245
  currentPathIterations: number;
@@ -1226,10 +1250,12 @@ declare class PortPointPathingSolver extends BaseSolver {
1226
1250
  capacityMeshNodeMap: Map<CapacityMeshNodeId, CapacityMeshNode>;
1227
1251
  /** Heuristic scaling: an estimate of "node pitch" used to estimate remaining hops */
1228
1252
  avgNodePitch: number;
1253
+ /** Whether the current connection should be forced to route off-board */
1254
+ currentConnectionShouldRouteOffBoard: boolean;
1255
+ /** Cached list of off-board nodes for computing distance to nearest off-board node */
1256
+ offBoardNodes: InputNodeWithPortPoints[];
1229
1257
  /** Cache of base node cost (cost of node in current committed state) */
1230
1258
  private baseNodeCostCache;
1231
- /** Cache of delta cost for a specific node segment (entry->exit) for a specific connection */
1232
- private segmentDeltaCostCache;
1233
1259
  constructor({ simpleRouteJson, inputNodes, capacityMeshNodes, colorMap, nodeMemoryPfMap, hyperParameters, }: {
1234
1260
  simpleRouteJson: SimpleRouteJson;
1235
1261
  capacityMeshNodes: CapacityMeshNode[];
@@ -1242,10 +1268,9 @@ declare class PortPointPathingSolver extends BaseSolver {
1242
1268
  private clampPf;
1243
1269
  /** Convert Pf into an additive "failure cost" */
1244
1270
  private pfToFailureCost;
1245
- private round3;
1246
- private pointKey;
1247
1271
  /** Base node cost with the currently-committed port points (no candidate additions) */
1248
1272
  private getBaseNodeFailureCost;
1273
+ computeBoardScore(): number;
1249
1274
  /**
1250
1275
  * Exact delta cost of routing this connection through `nodeId`
1251
1276
  * for the segment defined by entry->exit.
@@ -1288,6 +1313,13 @@ declare class PortPointPathingSolver extends BaseSolver {
1288
1313
  * This ensures the last node's segment is accounted for in g.
1289
1314
  */
1290
1315
  private computeGToEndTarget;
1316
+ /**
1317
+ * Compute distance to the nearest off-board node from a point.
1318
+ */
1319
+ computeDistanceToNearestOffBoardNode(point: {
1320
+ x: number;
1321
+ y: number;
1322
+ }): number;
1291
1323
  /**
1292
1324
  * Heuristic: approximate remaining cost.
1293
1325
  *
@@ -1296,10 +1328,8 @@ declare class PortPointPathingSolver extends BaseSolver {
1296
1328
  * - estimated remaining hops (distance / avgNodePitch)
1297
1329
  * - memoryPfMap to bias away from historically high Pf regions
1298
1330
  */
1299
- computeH(point: {
1300
- x: number;
1301
- y: number;
1302
- }, currentNodeId: CapacityMeshNodeId, endGoalNodeId: CapacityMeshNodeId, currentZ: number): number;
1331
+ computeH(point: InputPortPoint, currentNodeId: CapacityMeshNodeId, endGoalNodeId: CapacityMeshNodeId, currentZ: number, distanceTraveled: number, hasTouchedOffBoardNode?: boolean): number;
1332
+ getAvailableExitPortPoints(nodeId: CapacityMeshNodeId): InputPortPoint[];
1303
1333
  /**
1304
1334
  * Get available port points to exit from a node, but *do not* return all.
1305
1335
  *
@@ -1309,7 +1339,10 @@ declare class PortPointPathingSolver extends BaseSolver {
1309
1339
  * unassigned offsets as backups.
1310
1340
  */
1311
1341
  getAvailableExitPortPointsWithOmissions(nodeId: CapacityMeshNodeId, _endGoalNodeId: CapacityMeshNodeId): InputPortPoint[];
1312
- canTravelThroughObstacle(node: InputNodeWithPortPoints, connectionName: string): boolean;
1342
+ getAvailableExitPortPointsForOffboardConnection(nodeId: CapacityMeshNodeId): (InputPortPoint & {
1343
+ throughNodeId: CapacityMeshNodeId;
1344
+ })[];
1345
+ canTravelThroughObstacle(node: InputNodeWithPortPoints, connectionName: string, rootConnectionName: string): boolean;
1313
1346
  /**
1314
1347
  * Check if we've reached the end goal node
1315
1348
  */
@@ -1340,6 +1373,72 @@ declare class PortPointPathingSolver extends BaseSolver {
1340
1373
  visualize(): GraphicsObject;
1341
1374
  }
1342
1375
 
1376
+ interface HyperPortPointPathingSolverParams {
1377
+ simpleRouteJson: SimpleRouteJson;
1378
+ capacityMeshNodes: CapacityMeshNode[];
1379
+ inputNodes: InputNodeWithPortPoints[];
1380
+ colorMap?: Record<string, string>;
1381
+ nodeMemoryPfMap?: Map<CapacityMeshNodeId, number>;
1382
+ numShuffleSeeds?: number;
1383
+ minAllowedBoardScore?: number;
1384
+ hyperParameters?: Partial<PortPointPathingHyperParameters>;
1385
+ }
1386
+ declare class HyperPortPointPathingSolver extends HyperParameterSupervisorSolver<PortPointPathingSolver> {
1387
+ private params;
1388
+ constructor(params: HyperPortPointPathingSolverParams);
1389
+ getHyperParameterDefs(): Array<HyperParameterDef>;
1390
+ getCombinationDefs(): Array<string[]>;
1391
+ generateSolver(hyperParameters: any): PortPointPathingSolver;
1392
+ /**
1393
+ * G measures the "cost" of this solver based on current score.
1394
+ * We use the raw board score (more negative = worse quality = higher cost).
1395
+ *
1396
+ * The key insight is that early scores (at ~25% progress) are predictive
1397
+ * of final quality. Solvers with better early scores tend to finish better.
1398
+ */
1399
+ computeG(solver: PortPointPathingSolver): number;
1400
+ /**
1401
+ * H estimates remaining "cost" based on current trajectory.
1402
+ *
1403
+ * Key insight from analysis: bad solvers have similar early scores but
1404
+ * explode later (e.g., seed 760: -0.23 @ 25% → -15.05 final).
1405
+ * Good solvers maintain low scores throughout (e.g., seed 829: -0.06 @ 25% → -2.42 final).
1406
+ *
1407
+ * We estimate remaining cost by extrapolating current score/connection rate.
1408
+ */
1409
+ computeH(solver: PortPointPathingSolver): number;
1410
+ /**
1411
+ * Get the nodes with port points from the winning solver
1412
+ */
1413
+ getNodesWithPortPoints(): NodeWithPortPoints[];
1414
+ /**
1415
+ * Get connection results from the winning solver
1416
+ */
1417
+ get connectionsWithResults(): ConnectionPathResult[];
1418
+ /**
1419
+ * Get input nodes from the winning solver
1420
+ */
1421
+ get inputNodes(): InputNodeWithPortPoints[];
1422
+ /**
1423
+ * Get node map from the winning solver
1424
+ */
1425
+ get nodeMap(): Map<CapacityMeshNodeId, InputNodeWithPortPoints>;
1426
+ /**
1427
+ * Get assigned port points from the winning solver
1428
+ */
1429
+ get assignedPortPoints(): Map<any, any>;
1430
+ /**
1431
+ * Get node assigned port points from the winning solver
1432
+ */
1433
+ get nodeAssignedPortPoints(): Map<any, any>;
1434
+ /**
1435
+ * Compute board score from the winning solver
1436
+ */
1437
+ computeBoardScore(): number;
1438
+ onSolve(solver: SupervisedSolver<PortPointPathingSolver>): void;
1439
+ visualize(): GraphicsObject;
1440
+ }
1441
+
1343
1442
  interface PortPointSectionParams {
1344
1443
  centerOfSectionCapacityNodeId: CapacityMeshNodeId;
1345
1444
  expansionDegrees: number;
@@ -1514,7 +1613,12 @@ declare class MultiSectionPortPointOptimizer extends BaseSolver {
1514
1613
  * Marks nodes containing cut path endpoints as targets so the solver can route to/from them.
1515
1614
  */
1516
1615
  prepareSectionInputNodesForCutPaths(section: PortPointSection): InputNodeWithPortPoints[];
1517
- getHyperParametersForAttempt(attempt: number): PortPointPathingHyperParameters;
1616
+ getHyperParametersForScheduleIndex(scheduleIndex: number, sectionAttempt: number): PortPointPathingHyperParameters;
1617
+ /**
1618
+ * Create a PortPointPathingSolver for the current section.
1619
+ * This centralizes the solver creation logic that was previously duplicated in 3 places.
1620
+ */
1621
+ createSectionSolver(section: PortPointSection): PortPointPathingSolver;
1518
1622
  /**
1519
1623
  * Reattach the optimized section results back to the main state.
1520
1624
  * Handles both fully contained connections AND cut paths.
@@ -1542,7 +1646,7 @@ declare class AutoroutingPipelineSolver2_PortPointPathing extends BaseSolver {
1542
1646
  srj: SimpleRouteJson;
1543
1647
  opts: CapacityMeshSolverOptions$2;
1544
1648
  netToPointPairsSolver?: NetToPointPairsSolver;
1545
- nodeSolver?: RectDiffSolver;
1649
+ nodeSolver?: RectDiffPipeline;
1546
1650
  nodeTargetMerger?: CapacityNodeTargetMerger;
1547
1651
  edgeSolver?: CapacityMeshEdgeSolver;
1548
1652
  colorMap: Record<string, string>;
@@ -1553,7 +1657,7 @@ declare class AutoroutingPipelineSolver2_PortPointPathing extends BaseSolver {
1553
1657
  deadEndSolver?: DeadEndSolver;
1554
1658
  traceSimplificationSolver?: TraceSimplificationSolver;
1555
1659
  availableSegmentPointSolver?: AvailableSegmentPointSolver;
1556
- portPointPathingSolver?: PortPointPathingSolver;
1660
+ portPointPathingSolver?: HyperPortPointPathingSolver;
1557
1661
  multiSectionPortPointOptimizer?: MultiSectionPortPointOptimizer;
1558
1662
  viaDiameter: number;
1559
1663
  minTraceWidth: number;
@@ -1566,7 +1670,7 @@ declare class AutoroutingPipelineSolver2_PortPointPathing extends BaseSolver {
1566
1670
  capacityNodes: CapacityMeshNode[] | null;
1567
1671
  capacityEdges: CapacityMeshEdge[] | null;
1568
1672
  cacheProvider: CacheProvider | null;
1569
- pipelineDef: (PipelineStep$2<typeof NetToPointPairsSolver2_OffBoardConnection> | PipelineStep$2<typeof RectDiffSolver> | PipelineStep$2<typeof CapacityMeshEdgeSolver2_NodeTreeOptimization> | PipelineStep$2<typeof AvailableSegmentPointSolver> | PipelineStep$2<typeof PortPointPathingSolver> | PipelineStep$2<typeof MultiSectionPortPointOptimizer> | PipelineStep$2<typeof HighDensitySolver> | PipelineStep$2<typeof MultipleHighDensityRouteStitchSolver> | PipelineStep$2<typeof TraceSimplificationSolver>)[];
1673
+ pipelineDef: (PipelineStep$2<typeof NetToPointPairsSolver2_OffBoardConnection> | PipelineStep$2<typeof RectDiffPipeline> | PipelineStep$2<typeof CapacityMeshEdgeSolver2_NodeTreeOptimization> | PipelineStep$2<typeof AvailableSegmentPointSolver> | PipelineStep$2<typeof HyperPortPointPathingSolver> | PipelineStep$2<typeof MultiSectionPortPointOptimizer> | PipelineStep$2<typeof HighDensitySolver> | PipelineStep$2<typeof MultipleHighDensityRouteStitchSolver> | PipelineStep$2<typeof TraceSimplificationSolver>)[];
1570
1674
  constructor(srj: SimpleRouteJson, opts?: CapacityMeshSolverOptions$2);
1571
1675
  currentPipelineStepIndex: number;
1572
1676
  _step(): void;
@@ -2398,7 +2502,7 @@ declare class AutoroutingPipeline1_OriginalUnravel extends BaseSolver {
2398
2502
  srj: SimpleRouteJson;
2399
2503
  opts: CapacityMeshSolverOptions$1;
2400
2504
  netToPointPairsSolver?: NetToPointPairsSolver;
2401
- nodeSolver?: RectDiffSolver;
2505
+ nodeSolver?: RectDiffPipeline;
2402
2506
  nodeTargetMerger?: CapacityNodeTargetMerger;
2403
2507
  edgeSolver?: CapacityMeshEdgeSolver;
2404
2508
  initialPathingSolver?: CapacityPathingGreedySolver;
@@ -2425,7 +2529,7 @@ declare class AutoroutingPipeline1_OriginalUnravel extends BaseSolver {
2425
2529
  capacityNodes: CapacityMeshNode[] | null;
2426
2530
  capacityEdges: CapacityMeshEdge[] | null;
2427
2531
  cacheProvider: CacheProvider | null;
2428
- pipelineDef: (PipelineStep$1<typeof NetToPointPairsSolver2_OffBoardConnection> | PipelineStep$1<typeof RectDiffSolver> | PipelineStep$1<typeof StrawSolver> | PipelineStep$1<typeof CapacityMeshEdgeSolver2_NodeTreeOptimization> | PipelineStep$1<typeof DeadEndSolver> | PipelineStep$1<typeof CapacityPathingGreedySolver> | PipelineStep$1<typeof CapacityPathingMultiSectionSolver> | PipelineStep$1<typeof CapacityEdgeToPortSegmentSolver> | PipelineStep$1<typeof CapacitySegmentToPointSolver> | PipelineStep$1<typeof UnravelMultiSectionSolver> | PipelineStep$1<typeof HighDensitySolver> | PipelineStep$1<typeof MultipleHighDensityRouteStitchSolver> | PipelineStep$1<typeof TraceSimplificationSolver>)[];
2532
+ pipelineDef: (PipelineStep$1<typeof NetToPointPairsSolver2_OffBoardConnection> | PipelineStep$1<typeof RectDiffPipeline> | PipelineStep$1<typeof StrawSolver> | PipelineStep$1<typeof CapacityMeshEdgeSolver2_NodeTreeOptimization> | PipelineStep$1<typeof DeadEndSolver> | PipelineStep$1<typeof CapacityPathingGreedySolver> | PipelineStep$1<typeof CapacityPathingMultiSectionSolver> | PipelineStep$1<typeof CapacityEdgeToPortSegmentSolver> | PipelineStep$1<typeof CapacitySegmentToPointSolver> | PipelineStep$1<typeof UnravelMultiSectionSolver> | PipelineStep$1<typeof HighDensitySolver> | PipelineStep$1<typeof MultipleHighDensityRouteStitchSolver> | PipelineStep$1<typeof TraceSimplificationSolver>)[];
2429
2533
  constructor(srj: SimpleRouteJson, opts?: CapacityMeshSolverOptions$1);
2430
2534
  currentPipelineStepIndex: number;
2431
2535
  _step(): void;
@@ -3207,10 +3311,10 @@ type AutoroutingPipelineSolverOptions = CapacityMeshSolverOptions;
3207
3311
  type PipelineStep<T extends new (...args: any[]) => BaseSolver> = {
3208
3312
  solverName: string;
3209
3313
  solverClass: T;
3210
- getConstructorParams: (instance: AssignableViaAutoroutingPipelineSolver) => ConstructorParameters<T>;
3211
- onSolved?: (instance: AssignableViaAutoroutingPipelineSolver) => void;
3314
+ getConstructorParams: (instance: AssignableAutoroutingPipeline1Solver) => ConstructorParameters<T>;
3315
+ onSolved?: (instance: AssignableAutoroutingPipeline1Solver) => void;
3212
3316
  };
3213
- declare class AssignableViaAutoroutingPipelineSolver extends BaseSolver {
3317
+ declare class AssignableAutoroutingPipeline1Solver extends BaseSolver {
3214
3318
  srj: SimpleRouteJson;
3215
3319
  opts: CapacityMeshSolverOptions;
3216
3320
  netToPointPairsSolver?: NetToPointPairsSolver;
@@ -3278,4 +3382,4 @@ declare const convertSrjToGraphicsObject: (srj: SimpleRouteJson) => {
3278
3382
  points: Point$3[];
3279
3383
  };
3280
3384
 
3281
- export { AssignableViaAutoroutingPipelineSolver, AutoroutingPipeline1_OriginalUnravel, AutoroutingPipelineSolver2_PortPointPathing as AutoroutingPipelineSolver, type AutoroutingPipelineSolverOptions, type CachableSolver, type CacheProvider, CapacityMeshSolver, InMemoryCache, LocalStorageCache, calculateOptimalCapacityDepth, convertSrjToGraphicsObject, getGlobalInMemoryCache, getGlobalLocalStorageCache, getTunedTotalCapacity1, setupGlobalCaches };
3385
+ export { AssignableAutoroutingPipeline1Solver, AutoroutingPipeline1_OriginalUnravel, AutoroutingPipelineSolver2_PortPointPathing as AutoroutingPipelineSolver, type AutoroutingPipelineSolverOptions, type CachableSolver, type CacheProvider, CapacityMeshSolver, InMemoryCache, LocalStorageCache, calculateOptimalCapacityDepth, convertSrjToGraphicsObject, getGlobalInMemoryCache, getGlobalLocalStorageCache, getTunedTotalCapacity1, setupGlobalCaches };