@tscircuit/fanout-solver 0.0.26 → 0.0.27

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.
@@ -1028,8 +1028,31 @@ export class FanoutSolver extends BaseSolver {
1028
1028
  this.pendingRepairAssignments.push(...repairs)
1029
1029
  }
1030
1030
 
1031
+ private hasCompleteBestAttempt(): boolean {
1032
+ return (
1033
+ this.bestAttempt?.summary.routedConnectionCount ===
1034
+ this.inputSrj.connections.length
1035
+ )
1036
+ }
1037
+
1038
+ private shouldEvaluateGroupedBeam(): boolean {
1039
+ if (this.groupedBeamEvaluated || this.nextAssignmentIndex === 0) {
1040
+ return false
1041
+ }
1042
+
1043
+ const targetedRepairSearchFinished =
1044
+ this.hasCompleteBestAttempt() ||
1045
+ this.pendingRepairAssignments.length === 0 ||
1046
+ this.nextAssignmentIndex >= this.config.maxLayerCombinations
1047
+
1048
+ return targetedRepairSearchFinished
1049
+ }
1050
+
1031
1051
  override _step(): void {
1032
- if (!this.groupedBeamEvaluated) {
1052
+ // Try the deterministic assignment and only its targeted repair queue
1053
+ // before paying for the grouped beam. If the beam cannot solve, continue
1054
+ // with the broader generated-assignment search below.
1055
+ if (this.shouldEvaluateGroupedBeam()) {
1033
1056
  this.groupedBeamEvaluated = true
1034
1057
  let beamAttempt = this.evaluateGroupedBeam(-1)
1035
1058
  if (!beamAttempt) {
@@ -1037,19 +1060,33 @@ export class FanoutSolver extends BaseSolver {
1037
1060
  }
1038
1061
  if (beamAttempt) {
1039
1062
  this.attempts.push(beamAttempt.summary)
1040
- this.bestAttempt = beamAttempt
1063
+ if (
1064
+ !this.bestAttempt ||
1065
+ beamAttempt.summary.score < this.bestAttempt.summary.score
1066
+ ) {
1067
+ this.bestAttempt = beamAttempt
1068
+ }
1069
+ const bestSummary = this.bestAttempt.summary
1041
1070
  this.stats = {
1042
- assignment: 0,
1071
+ assignment:
1072
+ bestSummary.assignmentIndex < 0
1073
+ ? 0
1074
+ : bestSummary.assignmentIndex + 1,
1043
1075
  assignmentCount: this.config.maxLayerCombinations,
1044
- routedBuses: `${beamAttempt.summary.routedBusCount}/${this.preparedBuses.length}`,
1045
- routedConnections: `${beamAttempt.summary.routedConnectionCount}/${this.inputSrj.connections.length}`,
1076
+ routedBuses: `${bestSummary.routedBusCount}/${this.preparedBuses.length}`,
1077
+ routedConnections: `${bestSummary.routedConnectionCount}/${this.inputSrj.connections.length}`,
1046
1078
  failedBuses: "none",
1047
- bestScore: beamAttempt.summary.score,
1079
+ bestScore: bestSummary.score,
1048
1080
  }
1049
1081
  this.completeBestAttemptEndpoints()
1050
1082
  this.solved = true
1051
1083
  return
1052
1084
  }
1085
+ if (this.hasCompleteBestAttempt()) {
1086
+ this.completeBestAttemptEndpoints()
1087
+ this.solved = true
1088
+ return
1089
+ }
1053
1090
  }
1054
1091
 
1055
1092
  let assignment: Readonly<Record<string, string>> | undefined
@@ -1060,13 +1097,19 @@ export class FanoutSolver extends BaseSolver {
1060
1097
  const preferGeneratedAssignment = this.nextAssignmentIndex % 3 === 0
1061
1098
  let candidate: Readonly<Record<string, string>> | undefined
1062
1099
  let candidateCameFromRepairQueue = false
1063
- if (preferGeneratedAssignment) {
1100
+ if (!this.groupedBeamEvaluated && this.nextAssignmentIndex > 0) {
1101
+ candidate = this.pendingRepairAssignments.pop()
1102
+ candidateCameFromRepairQueue = candidate !== undefined
1103
+ } else if (preferGeneratedAssignment) {
1064
1104
  candidate = this.layerAssignments[this.nextGeneratedAssignmentIndex++]
1065
1105
  } else {
1066
1106
  candidate = this.pendingRepairAssignments.pop()
1067
1107
  candidateCameFromRepairQueue = candidate !== undefined
1068
1108
  }
1069
- if (!candidate) {
1109
+ if (
1110
+ !candidate &&
1111
+ (this.groupedBeamEvaluated || this.nextAssignmentIndex === 0)
1112
+ ) {
1070
1113
  candidate = preferGeneratedAssignment
1071
1114
  ? this.pendingRepairAssignments.pop()
1072
1115
  : this.layerAssignments[this.nextGeneratedAssignmentIndex++]
@@ -1081,12 +1124,9 @@ export class FanoutSolver extends BaseSolver {
1081
1124
  if (this.evaluatedAssignmentKeys.has(candidateKey)) continue
1082
1125
  assignment = candidate
1083
1126
  }
1127
+ if (!assignment && !this.groupedBeamEvaluated) return
1084
1128
  if (!assignment) {
1085
- if (
1086
- this.bestAttempt &&
1087
- this.bestAttempt.summary.routedConnectionCount ===
1088
- this.inputSrj.connections.length
1089
- ) {
1129
+ if (this.hasCompleteBestAttempt()) {
1090
1130
  this.completeBestAttemptEndpoints()
1091
1131
  this.solved = true
1092
1132
  } else {
@@ -1131,6 +1171,7 @@ export class FanoutSolver extends BaseSolver {
1131
1171
  bestScore: this.bestAttempt.summary.score,
1132
1172
  }
1133
1173
  if (
1174
+ this.groupedBeamEvaluated &&
1134
1175
  attempt.summary.routedConnectionCount === this.inputSrj.connections.length
1135
1176
  ) {
1136
1177
  this.completeBestAttemptEndpoints()
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tscircuit/fanout-solver",
3
- "version": "0.0.26",
3
+ "version": "0.0.27",
4
4
  "description": "BGA fanout solver with coordinated bus-layer escapes for SimpleRouteJson",
5
5
  "module": "lib/index.ts",
6
6
  "type": "module",