@tscircuit/hypergraph 0.0.12 → 0.0.14
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 +16 -8
- package/dist/index.js +118 -10
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -63,13 +63,16 @@ type HyperGraph = {
|
|
|
63
63
|
ports: RegionPort[];
|
|
64
64
|
regions: Region[];
|
|
65
65
|
};
|
|
66
|
-
type SerializedGraphPort =
|
|
66
|
+
type SerializedGraphPort = {
|
|
67
67
|
portId: PortId;
|
|
68
68
|
region1Id: RegionId;
|
|
69
69
|
region2Id: RegionId;
|
|
70
|
+
d: any;
|
|
70
71
|
};
|
|
71
|
-
type SerializedGraphRegion =
|
|
72
|
+
type SerializedGraphRegion = {
|
|
73
|
+
regionId: RegionId;
|
|
72
74
|
pointIds: PortId[];
|
|
75
|
+
d: any;
|
|
73
76
|
assignments?: SerializedRegionPortAssignment[];
|
|
74
77
|
};
|
|
75
78
|
type SerializedRegionPortAssignment = {
|
|
@@ -295,11 +298,11 @@ declare class HyperGraphSolver<RegionType extends Region = Region, RegionPortTyp
|
|
|
295
298
|
ripCost?: number;
|
|
296
299
|
});
|
|
297
300
|
getConstructorParams(): {
|
|
298
|
-
inputGraph:
|
|
299
|
-
inputConnections:
|
|
300
|
-
greedyMultiplier
|
|
301
|
-
rippingEnabled
|
|
302
|
-
ripCost
|
|
301
|
+
inputGraph: SerializedHyperGraph;
|
|
302
|
+
inputConnections: SerializedConnection[];
|
|
303
|
+
greedyMultiplier: number;
|
|
304
|
+
rippingEnabled: boolean;
|
|
305
|
+
ripCost: number;
|
|
303
306
|
};
|
|
304
307
|
computeH(candidate: CandidateType): number;
|
|
305
308
|
/**
|
|
@@ -386,6 +389,7 @@ declare class JumperGraphSolver extends HyperGraphSolver<JRegion, JPort> {
|
|
|
386
389
|
ripCost: number;
|
|
387
390
|
baseMaxIterations: number;
|
|
388
391
|
additionalMaxIterationsPerConnection: number;
|
|
392
|
+
additionalMaxIterationsPerCrossing: number;
|
|
389
393
|
constructor(input: {
|
|
390
394
|
inputGraph: HyperGraph | SerializedHyperGraph;
|
|
391
395
|
inputConnections: (Connection | SerializedConnection)[];
|
|
@@ -405,6 +409,10 @@ declare class JumperGraphSolver extends HyperGraphSolver<JRegion, JPort> {
|
|
|
405
409
|
visualize(): GraphicsObject;
|
|
406
410
|
}
|
|
407
411
|
|
|
412
|
+
declare const convertHyperGraphToSerializedHyperGraph: (graph: HyperGraph) => SerializedHyperGraph;
|
|
413
|
+
|
|
414
|
+
declare const convertConnectionsToSerializedConnections: (connections: Connection[]) => SerializedConnection[];
|
|
415
|
+
|
|
408
416
|
/**
|
|
409
417
|
* Applies a transformation matrix to all points in a graph.
|
|
410
418
|
* Transforms region bounds, region centers, and port positions.
|
|
@@ -417,4 +425,4 @@ declare const rotateGraph90Degrees: (graph: JumperGraph) => JumperGraph;
|
|
|
417
425
|
|
|
418
426
|
declare const calculateGraphBounds: (regions: JRegion[]) => Bounds;
|
|
419
427
|
|
|
420
|
-
export { type Candidate, type Connection, type ConnectionId, type GScore, type GraphEdgeId, type HyperGraph, HyperGraphSolver, type JPort, type JRegion, JUMPER_GRAPH_SOLVER_DEFAULTS, type JumperGraph, JumperGraphSolver, type JumperGraphWithConnections, type NetworkId, type PortAssignment, type PortId, type Region, type RegionId, type RegionPort, type RegionPortAssignment, type SerializedConnection, type SerializedGraphPort, type SerializedGraphRegion, type SerializedHyperGraph, type SerializedRegionPortAssignment, type SolvedRoute, type XYConnection, applyTransformToGraph, calculateGraphBounds, createGraphWithConnectionsFromBaseGraph, generateJumperGrid, generateJumperX4Grid, rotateGraph90Degrees };
|
|
428
|
+
export { type Candidate, type Connection, type ConnectionId, type GScore, type GraphEdgeId, type HyperGraph, HyperGraphSolver, type JPort, type JRegion, JUMPER_GRAPH_SOLVER_DEFAULTS, type JumperGraph, JumperGraphSolver, type JumperGraphWithConnections, type NetworkId, type PortAssignment, type PortId, type Region, type RegionId, type RegionPort, type RegionPortAssignment, type SerializedConnection, type SerializedGraphPort, type SerializedGraphRegion, type SerializedHyperGraph, type SerializedRegionPortAssignment, type SolvedRoute, type XYConnection, applyTransformToGraph, calculateGraphBounds, convertConnectionsToSerializedConnections, convertHyperGraphToSerializedHyperGraph, createGraphWithConnectionsFromBaseGraph, generateJumperGrid, generateJumperX4Grid, rotateGraph90Degrees };
|
package/dist/index.js
CHANGED
|
@@ -1562,6 +1562,36 @@ var convertSerializedHyperGraphToHyperGraph = (inputGraph) => {
|
|
|
1562
1562
|
};
|
|
1563
1563
|
};
|
|
1564
1564
|
|
|
1565
|
+
// lib/convertHyperGraphToSerializedHyperGraph.ts
|
|
1566
|
+
var convertHyperGraphToSerializedHyperGraph = (graph) => {
|
|
1567
|
+
const serializedPorts = graph.ports.map((port) => ({
|
|
1568
|
+
portId: port.portId,
|
|
1569
|
+
region1Id: port.region1.regionId,
|
|
1570
|
+
region2Id: port.region2.regionId,
|
|
1571
|
+
d: port.d
|
|
1572
|
+
}));
|
|
1573
|
+
const serializedRegions = graph.regions.map(
|
|
1574
|
+
(region) => ({
|
|
1575
|
+
regionId: region.regionId,
|
|
1576
|
+
pointIds: region.ports.map((port) => port.portId),
|
|
1577
|
+
d: region.d
|
|
1578
|
+
})
|
|
1579
|
+
);
|
|
1580
|
+
return {
|
|
1581
|
+
ports: serializedPorts,
|
|
1582
|
+
regions: serializedRegions
|
|
1583
|
+
};
|
|
1584
|
+
};
|
|
1585
|
+
|
|
1586
|
+
// lib/convertConnectionsToSerializedConnections.ts
|
|
1587
|
+
var convertConnectionsToSerializedConnections = (connections) => {
|
|
1588
|
+
return connections.map((conn) => ({
|
|
1589
|
+
connectionId: conn.connectionId,
|
|
1590
|
+
startRegionId: conn.startRegion.regionId,
|
|
1591
|
+
endRegionId: conn.endRegion.regionId
|
|
1592
|
+
}));
|
|
1593
|
+
};
|
|
1594
|
+
|
|
1565
1595
|
// lib/convertSerializedConnectionsToConnections.ts
|
|
1566
1596
|
var convertSerializedConnectionsToConnections = (inputConnections, graph) => {
|
|
1567
1597
|
const connections = [];
|
|
@@ -1768,7 +1798,15 @@ var HyperGraphSolver = class extends BaseSolver {
|
|
|
1768
1798
|
lastCandidate = null;
|
|
1769
1799
|
visitedPointsForCurrentConnection = /* @__PURE__ */ new Map();
|
|
1770
1800
|
getConstructorParams() {
|
|
1771
|
-
return
|
|
1801
|
+
return {
|
|
1802
|
+
inputGraph: convertHyperGraphToSerializedHyperGraph(this.graph),
|
|
1803
|
+
inputConnections: convertConnectionsToSerializedConnections(
|
|
1804
|
+
this.connections
|
|
1805
|
+
),
|
|
1806
|
+
greedyMultiplier: this.greedyMultiplier,
|
|
1807
|
+
rippingEnabled: this.rippingEnabled,
|
|
1808
|
+
ripCost: this.ripCost
|
|
1809
|
+
};
|
|
1772
1810
|
}
|
|
1773
1811
|
computeH(candidate) {
|
|
1774
1812
|
return this.estimateCostToEnd(candidate.port);
|
|
@@ -2331,24 +2369,88 @@ function computeCrossingAssignments(region, port1, port2) {
|
|
|
2331
2369
|
return crossingAssignments;
|
|
2332
2370
|
}
|
|
2333
2371
|
|
|
2372
|
+
// lib/JumperGraphSolver/countInputConnectionCrossings.ts
|
|
2373
|
+
function countInputConnectionCrossings(graph, connections) {
|
|
2374
|
+
if (connections.length < 2) {
|
|
2375
|
+
return 0;
|
|
2376
|
+
}
|
|
2377
|
+
let minX = Infinity;
|
|
2378
|
+
let maxX = -Infinity;
|
|
2379
|
+
let minY = Infinity;
|
|
2380
|
+
let maxY = -Infinity;
|
|
2381
|
+
for (const region of graph.regions) {
|
|
2382
|
+
const jRegion = region;
|
|
2383
|
+
if (jRegion.d?.bounds) {
|
|
2384
|
+
minX = Math.min(minX, jRegion.d.bounds.minX);
|
|
2385
|
+
maxX = Math.max(maxX, jRegion.d.bounds.maxX);
|
|
2386
|
+
minY = Math.min(minY, jRegion.d.bounds.minY);
|
|
2387
|
+
maxY = Math.max(maxY, jRegion.d.bounds.maxY);
|
|
2388
|
+
} else if (jRegion.d?.center) {
|
|
2389
|
+
minX = Math.min(minX, jRegion.d.center.x);
|
|
2390
|
+
maxX = Math.max(maxX, jRegion.d.center.x);
|
|
2391
|
+
minY = Math.min(minY, jRegion.d.center.y);
|
|
2392
|
+
maxY = Math.max(maxY, jRegion.d.center.y);
|
|
2393
|
+
}
|
|
2394
|
+
}
|
|
2395
|
+
const regionCenterMap = /* @__PURE__ */ new Map();
|
|
2396
|
+
for (const region of graph.regions) {
|
|
2397
|
+
const jRegion = region;
|
|
2398
|
+
if (jRegion.d?.center) {
|
|
2399
|
+
regionCenterMap.set(region.regionId, jRegion.d.center);
|
|
2400
|
+
}
|
|
2401
|
+
}
|
|
2402
|
+
const chords = [];
|
|
2403
|
+
for (const conn of connections) {
|
|
2404
|
+
let startCenter;
|
|
2405
|
+
let endCenter;
|
|
2406
|
+
if ("startRegion" in conn && conn.startRegion) {
|
|
2407
|
+
const startRegion = conn.startRegion;
|
|
2408
|
+
const endRegion = conn.endRegion;
|
|
2409
|
+
startCenter = startRegion.d?.center;
|
|
2410
|
+
endCenter = endRegion.d?.center;
|
|
2411
|
+
} else if ("startRegionId" in conn) {
|
|
2412
|
+
startCenter = regionCenterMap.get(conn.startRegionId);
|
|
2413
|
+
endCenter = regionCenterMap.get(conn.endRegionId);
|
|
2414
|
+
}
|
|
2415
|
+
if (!startCenter || !endCenter) {
|
|
2416
|
+
continue;
|
|
2417
|
+
}
|
|
2418
|
+
const t1 = perimeterT(startCenter, minX, maxX, minY, maxY);
|
|
2419
|
+
const t2 = perimeterT(endCenter, minX, maxX, minY, maxY);
|
|
2420
|
+
chords.push([t1, t2]);
|
|
2421
|
+
}
|
|
2422
|
+
let crossings = 0;
|
|
2423
|
+
for (let i = 0; i < chords.length; i++) {
|
|
2424
|
+
for (let j = i + 1; j < chords.length; j++) {
|
|
2425
|
+
if (chordsCross(chords[i], chords[j])) {
|
|
2426
|
+
crossings++;
|
|
2427
|
+
}
|
|
2428
|
+
}
|
|
2429
|
+
}
|
|
2430
|
+
return crossings;
|
|
2431
|
+
}
|
|
2432
|
+
|
|
2334
2433
|
// lib/JumperGraphSolver/JumperGraphSolver.ts
|
|
2335
2434
|
var JUMPER_GRAPH_SOLVER_DEFAULTS = {
|
|
2336
|
-
portUsagePenalty: 0.
|
|
2337
|
-
portUsagePenaltySq: 0.06194817180037216,
|
|
2338
|
-
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
|
|
2435
|
+
portUsagePenalty: 0.034685181009478865,
|
|
2436
|
+
// portUsagePenaltySq: 0.06194817180037216,
|
|
2437
|
+
portUsagePenaltySq: 0,
|
|
2438
|
+
crossingPenalty: 4.072520483177124,
|
|
2439
|
+
crossingPenaltySq: 0,
|
|
2440
|
+
// crossingPenaltySq: 0.1315528159128946,
|
|
2441
|
+
ripCost: 35.38577539020022,
|
|
2442
|
+
greedyMultiplier: 0.5518001238069296
|
|
2342
2443
|
};
|
|
2343
2444
|
var JumperGraphSolver = class extends HyperGraphSolver {
|
|
2344
|
-
UNIT_OF_COST = "
|
|
2445
|
+
UNIT_OF_COST = "hops";
|
|
2345
2446
|
portUsagePenalty = JUMPER_GRAPH_SOLVER_DEFAULTS.portUsagePenalty;
|
|
2346
2447
|
portUsagePenaltySq = JUMPER_GRAPH_SOLVER_DEFAULTS.portUsagePenaltySq;
|
|
2347
2448
|
crossingPenalty = JUMPER_GRAPH_SOLVER_DEFAULTS.crossingPenalty;
|
|
2348
2449
|
crossingPenaltySq = JUMPER_GRAPH_SOLVER_DEFAULTS.crossingPenaltySq;
|
|
2349
2450
|
ripCost = JUMPER_GRAPH_SOLVER_DEFAULTS.ripCost;
|
|
2350
2451
|
baseMaxIterations = 4e3;
|
|
2351
|
-
additionalMaxIterationsPerConnection =
|
|
2452
|
+
additionalMaxIterationsPerConnection = 2e3;
|
|
2453
|
+
additionalMaxIterationsPerCrossing = 2e3;
|
|
2352
2454
|
constructor(input) {
|
|
2353
2455
|
super({
|
|
2354
2456
|
greedyMultiplier: JUMPER_GRAPH_SOLVER_DEFAULTS.greedyMultiplier,
|
|
@@ -2360,7 +2462,11 @@ var JumperGraphSolver = class extends HyperGraphSolver {
|
|
|
2360
2462
|
this.crossingPenalty = input.crossingPenalty ?? this.crossingPenalty;
|
|
2361
2463
|
this.baseMaxIterations = input.baseMaxIterations ?? this.baseMaxIterations;
|
|
2362
2464
|
this.additionalMaxIterationsPerConnection = input.additionalMaxIterationsPerConnection ?? this.additionalMaxIterationsPerConnection;
|
|
2363
|
-
|
|
2465
|
+
const crossings = countInputConnectionCrossings(
|
|
2466
|
+
this.graph,
|
|
2467
|
+
input.inputConnections
|
|
2468
|
+
);
|
|
2469
|
+
this.MAX_ITERATIONS = this.baseMaxIterations + input.inputConnections.length * this.additionalMaxIterationsPerConnection + crossings * this.additionalMaxIterationsPerCrossing;
|
|
2364
2470
|
this.populateDistanceToEndMaps();
|
|
2365
2471
|
}
|
|
2366
2472
|
populateDistanceToEndMaps() {
|
|
@@ -2423,6 +2529,8 @@ export {
|
|
|
2423
2529
|
JumperGraphSolver,
|
|
2424
2530
|
applyTransformToGraph,
|
|
2425
2531
|
calculateGraphBounds,
|
|
2532
|
+
convertConnectionsToSerializedConnections,
|
|
2533
|
+
convertHyperGraphToSerializedHyperGraph,
|
|
2426
2534
|
createGraphWithConnectionsFromBaseGraph,
|
|
2427
2535
|
generateJumperGrid,
|
|
2428
2536
|
generateJumperX4Grid,
|