@mark1russell7/highways 0.9.3 → 0.9.5

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.
Files changed (39) hide show
  1. package/README.md +85 -5
  2. package/build/index.d.ts +954 -5
  3. package/build/index.d.ts.map +1 -1
  4. package/build/index.js +10689 -5294
  5. package/build/index.js.map +1 -1
  6. package/package.json +1 -1
  7. package/src/bench/screen/exercise.ts +4 -1
  8. package/src/bench/screen/set.ts +58 -1
  9. package/src/families/cases.ts +17 -9
  10. package/src/families/coverage.ts +502 -0
  11. package/src/families/index.ts +4 -1
  12. package/src/highways/balance/index.ts +93 -0
  13. package/src/highways/bronchial/index.ts +144 -0
  14. package/src/highways/index.ts +5 -0
  15. package/src/highways/knee/index.ts +154 -0
  16. package/src/highways/knee/root.ts +19 -0
  17. package/src/highways/manifolds/index.ts +157 -0
  18. package/src/highways/slots/index.ts +178 -0
  19. package/src/index.ts +8 -0
  20. package/src/levels/detail/index.ts +140 -0
  21. package/src/levels/venation/index.ts +191 -0
  22. package/src/plugs/leaders/index.ts +42 -0
  23. package/src/plugs/spread/index.ts +39 -5
  24. package/src/routers/adam/index.ts +294 -0
  25. package/src/routers/annealing/index.ts +260 -0
  26. package/src/routers/canals/index.ts +191 -0
  27. package/src/routers/frames.ts +80 -16
  28. package/src/routers/gutter.ts +545 -0
  29. package/src/routers/index.ts +8 -2
  30. package/src/routers/reroute/index.ts +164 -0
  31. package/src/routers/shared.ts +43 -2
  32. package/src/routers/tight/index.ts +122 -0
  33. package/src/strategies/builtins.ts +158 -2
  34. package/src/strategies/schemas.ts +143 -0
  35. package/src/whole/curriculum/index.ts +243 -0
  36. package/src/whole/fireflies/index.ts +177 -0
  37. package/src/whole/portfolio/index.ts +108 -0
  38. package/src/whole/preferences/index.ts +247 -0
  39. package/src/whole/tracing/index.ts +144 -0
package/README.md CHANGED
@@ -59,11 +59,15 @@ A plug rule is a strategy of the step `plugs`. It places the free plugs of each
59
59
  | `side` | The search of the route starts from the whole free side. The plug goes where the way leaves the side (WILD-001). |
60
60
  | `justify` | The plugs of `facing`, then the plugs of each side keep their order and the gap `plugGap` (WILD-002). |
61
61
  | `spread` | The plugs of each wall share the room of the wall, with the gap `plugGap`, in the order of their far ends. |
62
+ | `leaders` | The boundary leaders of EDA-041. The plugs of each wall take the order of `po`, `s` or `opo` leaders, with the gap `slotSpacing`. |
62
63
 
63
64
  - `side` gives the plugs of `corners` with `plugs: "side"`. `justify` gives the plugs of `corners` with the same `plugGap`.
64
65
  - `spread` keeps the room of a wall free of the corner insets (`inset`) and of the fixed plugs on the wall.
65
66
  - When the room is too small for the gap, the gap shrinks evenly. No plug drops.
66
67
  - The order on the wall keeps the order of the far ends, so the straight lines of two plugs do not cross at the wall.
68
+ - `leaders` (EDA-041) uses the walls of `spread`. With `po`, the default, the order on a wall is the order of the far ends along the wall.
69
+ - A `po` stub leaves along the normal and turns one time, so this order gives stubs with no crossing.
70
+ - With `s`, the plugs are the plugs of `spread`. With `opo`, the plugs of a wall go at even places.
67
71
  - The ends of one port share one plug. The option `rounds` sorts each wall again by the new places of the far ends.
68
72
  - The option `plug` of `corners` takes a plug rule. The other routers place the plugs as `facing` does.
69
73
 
@@ -99,6 +103,16 @@ A node can name a frame node in `parent`. A frame is a node that holds other nod
99
103
  - `throw` (the default) throws a `RangeError`.
100
104
  - `skip` gives no route to the edges of that node.
101
105
  - `clamp` cuts the box to the bounds of the frame.
106
+ - The option `inner` sets the mode of the inner routes:
107
+ - `corners` (the default) finds each route in the corner graph, as above.
108
+ - `gutter` gives orthogonal routes in the gaps between the nodes and in the strips at the walls.
109
+ - In the mode `gutter`, a route uses the whole box of the frame. The mode does not use `frameInset`.
110
+ - A route of the mode `gutter` goes into its row at the port, or at the left or right end of the row.
111
+ - The plug stub stays perpendicular to the wall. A plug that is level with its row gives only the stub.
112
+ - The option `bendCost` is the cost of one bend in units of length. A larger cost gives fewer bends. The default is 16.
113
+ - Each gap that two or more routes share gets one lane for each route. The lanes are evenly spaced, in an order with few crossings.
114
+ - The space between two lanes is the margin of the router. In a narrow gap, the space becomes smaller.
115
+ - An edge with no way through the free room gets no route, as with `skip`. Rows that touch each other with gap 0 can block a way.
102
116
 
103
117
  ```ts
104
118
  const nodes = [
@@ -107,6 +121,7 @@ const nodes = [
107
121
  ];
108
122
  const edges = [{ id: "inner", source: { node: "row" }, target: { node: "card", port: "in" } }];
109
123
  const inner = cornersRouter({ name: "corners" }).route({ nodes, edges }).routes; // inner[0].frame is "card"
124
+ const gutters = cornersRouter({ name: "corners", inner: "gutter", bendCost: 24 }).route({ nodes, edges }).routes; // only H and V legs
110
125
  ```
111
126
 
112
127
  ## Curve types
@@ -430,13 +445,13 @@ The steps of the pipeline that vary have strategies. Each step has one interface
430
445
  | Step | Input | Output | Built-in strategies |
431
446
  |---|---|---|---|
432
447
  | `group` | `Graph` | `Section`: the tree of groups of the router `sections` | `quadtree`, `keys`, `kd`, `cut` |
433
- | `plugs` | `PlugInput`: the graph, and optionally the ways of the router | `PlugPair[]`: the two plugs of each edge | `facing`, `side`, `justify`, `spread` |
448
+ | `plugs` | `PlugInput`: the graph, and optionally the ways of the router | `PlugPair[]`: the two plugs of each edge | `facing`, `side`, `justify`, `spread`, `leaders` |
434
449
  | `router` | `Graph` | `Result` | `straight`, `plugs`, `corners`, `corners-smooth`, `trunks`, `shared`, `shared-all`, `sections`, `sections-tree` |
435
- | `highway` | `HighwayInput`: the graph, optionally the first routes of a router, and optionally the plan before an edit | `HighwayPlan`: the highways as data | `keys`, `shared-ways`, `corridors`, `meet`, `weiszfeld`, `stubs`, `zipper`, `level-links`, `quickbundles`, `road-classes`, `flow-field`, `wspd`, `od-cells`, `select`, `mingle`, `spiral`, `flow-clusters`, `traclus`, `diffusion`, `nested`, `lanes`, `growth`, `edge-paths`, `soft-keys`, `hough`, `ridges`, `hdbscan`, `hub-arcs`, `divided`, `hierarchy`, `fdeb`, `mesh`, `kdeeb`, `cubu`, `mlseb`, `sbeb`, `areas`, `confluent`, `power`, `crossbars`, `frechet`, `spectral`, `resistance`, `link-communities`, `territories`, `consensus`, `p-hub`, `scale-space`, `corridors+breakeven`, `corridors+stretch`, `corridors+ambiguity`, `corridors+hysteresis`, `corridors+ids` |
436
- | `levels` | `LevelInput`: the graph, the tree of groups and the routes | `Level[]`: the zoom levels of the router `sections` | `depths` |
450
+ | `highway` | `HighwayInput`: the graph, optionally the first routes of a router, and optionally the plan before an edit | `HighwayPlan`: the highways as data | `keys`, `shared-ways`, `corridors`, `meet`, `weiszfeld`, `stubs`, `zipper`, `level-links`, `quickbundles`, `road-classes`, `flow-field`, `wspd`, `od-cells`, `select`, `mingle`, `spiral`, `flow-clusters`, `traclus`, `diffusion`, `nested`, `lanes`, `growth`, `edge-paths`, `soft-keys`, `hough`, `ridges`, `hdbscan`, `hub-arcs`, `divided`, `hierarchy`, `fdeb`, `mesh`, `kdeeb`, `cubu`, `mlseb`, `sbeb`, `areas`, `confluent`, `power`, `crossbars`, `frechet`, `spectral`, `resistance`, `link-communities`, `territories`, `consensus`, `p-hub`, `scale-space`, `gaps`, `streets`, `search`, `interchanges`, `knee`, `bronchial`, `balance`, `manifolds`, `slots`, `corridors+breakeven`, `corridors+stretch`, `corridors+ambiguity`, `corridors+hysteresis`, `corridors+ids` |
451
+ | `levels` | `LevelInput`: the graph, the tree of groups and the routes | `Level[]`: the zoom levels of the router `sections` | `depths`, `venation`, `detail` |
437
452
  | `curve` | `CurveInput`: the points, the normals of the plugs, the free space and the lane on its board | `CurveSegment[]` | `straight`, `rounded`, `spline`, `arc`, `smooth`, `clothoid`, `highway` |
438
453
  | `room` | `RoomInput`: the boxes and the links of a board, and the tree of sections for `levels` | `Gap[]` | `routes`, `lines`, `levels` |
439
- | `whole` | `Graph` | `WholeOutput`: the board and its `Result` | `pipeline` |
454
+ | `whole` | `Graph` | `WholeOutput`: the board and its `Result` | `pipeline`, `board-portfolio`, `curriculum`, `preferences`, `fireflies`, `tracing` |
440
455
 
441
456
  `STEPS` gives the steps in the order of the pipeline: `group`, `plugs`, `router`, `highway`, `levels`, `curve`, `room`, `whole`.
442
457
 
@@ -463,6 +478,29 @@ Each of these steps has one default strategy. The default gives the output of th
463
478
  The option `level` of `sections` takes a level strategy, and `levelOptions` gives its options. The strategy also gets the level options of the router.
464
479
  - `pipeline` (the step `whole`) runs a room strategy, then a router or a highway plan, with the rules that the router reads (`runPipeline`).
465
480
  Without options, it routes with `corners`. The demo of the site runs it. It does not draw the curves.
481
+ - `venation` (the step `levels`, NAT-016) keeps the levels of `depths`. Its level links take their ways on a closed backbone of the items.
482
+ The backbone is the relative neighbourhood graph (`rng`) or the Gabriel graph. A backbone link that a level link uses costs less for the next level links.
483
+ The routes do not change, so only the level links (Z3) change.
484
+ - `board-portfolio` (the step `whole`, WILD-045) runs a short list of settings on the board and keeps the best one.
485
+ The list `BOARD_PORTFOLIO_SETTINGS` holds 12 routers and highway plans. The option `settings` sets how many of them run.
486
+ A setting with a break of a hard rule does not count. The score adds the rank shares of the crossings, the median detour and the ink saved.
487
+ It reads no screen record and has no fit. With `budget: 0`, the default, the pick does not depend on the speed of the machine.
488
+ - `detail` (the step `levels`, WILD-016 with EDA-038) keeps the levels of `depths`. Close legs of level links become one stroke.
489
+ At the scale where a level first shows, two parallel legs closer than `pxMin` pixels collapse onto the leg with the larger count.
490
+ `detailWidth(count, options)` gives the width of a stroke for a renderer. The routes do not change, so only the level links change.
491
+ - `curriculum` (the step `whole`, RULE-048) adds the rules one at a time: the crossings, the lane separation and the crossing angle.
492
+ The pool `CURRICULUM_POOL` holds the routes of `corners`, `shared` and `trunks`. The first answer is the routes of `corners`.
493
+ In each stage, an edge takes a route of the pool that improves the new rule with no loss on the earlier rules.
494
+ The output has the routes alone, with no runs or bundles.
495
+ - `preferences` (the step `whole`, RULE-038) fits the weights of five rules to made-up pairs of routes, with a Bradley-Terry model.
496
+ A made-up panel labels the pairs (`PREFERENCE_PANEL`). The pairs do not come from the screen or from a board.
497
+ `fitPreferences()` gives the weights and the agreement with 50 held-out pairs. Each edge takes the route of `CURRICULUM_POOL` with the least weighted cost.
498
+ - `fireflies` (the step `whole`, NAT-047) searches the options `discount` and `margin` of `shared` on the board, with a seeded swarm.
499
+ The option `search` is `firefly` or `bees`. The option `budget` (4 to 40) is the largest number of different settings that the search routes.
500
+ The first setting is the default of `shared`. The attraction of a firefly is rational, so it uses no `Math.exp`.
501
+ - `tracing` (the step `whole`, WILD-057) runs the settings of `BOARD_PORTFOLIO_SETTINGS` and keeps the one with the least tracing load.
502
+ The load of an edge is `crossing × crossings + merge × merges and splits + bend × bends`. A merge counts only where the edge is not an outer lane.
503
+ `tracingLoads(result, weights)` gives the load of each edge, as the measure W4. The pick reads the quantile 0.95 of the loads by default.
466
504
  - `strategyKey(router, step)` gives the option of a router that takes a strategy of the step. `pipeline` uses it for the steps `group`, `plugs` and `levels`.
467
505
  - `stepRouterStrategy(strategy)` runs a strategy of a step of `RoutedStep` as a router. `stepRouters(registry, step)` gives one router for each strategy of the step.
468
506
 
@@ -541,9 +579,14 @@ The step `highway` decides which edges share a way. It gives a plan, not routes.
541
579
  | `streets` | The orthogonal streets of HWY-058. A greedy set cover picks the free horizontal and vertical lines that carry the most edge length. |
542
580
  | `search` | The local search of HWY-059. It adds, drops and changes the highways of a start plan, and it keeps the plan with the best score. |
543
581
  | `interchanges` | The interchanges of HWY-060. An edge can change from one highway to another at an interchange, where two spines come near. |
582
+ | `knee` | The knee tree of NAT-018. A sweep of the balancing factor gives trees from the least ink to the most direct paths, and the knee of that front is the pick. |
583
+ | `bronchial` | The bronchial tree of NAT-019. The tree grows toward the center of its targets, then splits them in two sectors, again and again. |
584
+ | `balance` | The stretch balance of EDA-017. A price for each edge grows while its stretch is above `tau`, and the price moves the exit of its ride forward. |
585
+ | `manifolds` | The manifolds of WILD-036. A fan from one node to a row of nodes gets a straight header in the gap before the row, with taps at right angles. |
586
+ | `slots` | The lane slots of RULE-047. An edge whose first route runs near a trunk joins it on a new outer lane, when the pull is larger than its detour. |
544
587
 
545
588
  The strategy `corridors` joins two ways when they share a long length. The length is `BREAK_EVEN` times the lane width or more, and the share `rho` of the shorter way or more.
546
- The strategies `meet`, `weiszfeld`, `stubs`, `zipper`, `level-links`, `lanes`, `divided` and `crossbars` change the plan of the option `from`: `shared-ways` (the default), `corridors` or `none`.
589
+ The strategies `meet`, `weiszfeld`, `stubs`, `zipper`, `level-links`, `lanes`, `divided`, `crossbars` and `slots` change the plan of the option `from`: `shared-ways` (the default), `corridors` or `none`.
547
590
  The routers `trunks` and `shared` keep their own code. A test pins their output, so the strategies `keys` and `shared-ways` read the same decision.
548
591
 
549
592
  A gate keeps, drops or changes the highways of a plan. `gateStrategy(strategy, gate)` puts a gate after a highway strategy, with the name `<strategy>+<gate>`.
@@ -616,6 +659,25 @@ The router `attraction` is opt-in. It is not in `STRATEGIES`, so the default out
616
659
  - A capacity term raises the cost of a link when its users are more than its width holds.
617
660
  - With 1 pass, `attraction: 0` and `capacityWeight: 0`, the routes are the routes of `shared`.
618
661
 
662
+ ### The routers `tight`, `annealing`, `reroute`, `canals` and `adam`
663
+
664
+ The routers `tight`, `annealing`, `reroute`, `canals` and `adam` are opt-in. They are not in `STRATEGIES`, so the default outputs do not change. Each one starts from the router `shared`.
665
+
666
+ - `tightRouter(options)` gives the order of WILD-023: the edges whose second way costs much more than their first way go first.
667
+ Its options are `penalty` (2 to 10), `first` (`tight` or `loose`) and `ties` (`id` or `length`). `tightStrategy` is its router strategy.
668
+ - `annealingRouter(options)` gives the simulated annealing of RULE-021, with the candidate routes of WILD-028. Each edge picks one of a few ways.
669
+ The energy adds the ink, the path length and the crossings. The chance to keep a worse state is rational, so it uses no `Math.exp`.
670
+ Its options are `candidates` (3 to 8), `crossing` (0 to 20), `temperature` (0.1 to 10), `cooling` (0.9 to 0.99), `budget` (20 to 200) and `seed`.
671
+ The same seed gives the same routes. `annealingStrategy` is its router strategy.
672
+ - `rerouteRouter(options)` gives the rule prices and the rip-up of RULE-044. A link costs more in a narrow channel and with edges of other keys.
673
+ A link with an edge of the same key costs less. Each round routes again the share `q` of the edges with the largest prices.
674
+ Its options are `alpha`, `beta`, `gamma` and `tau` (0 to 2), `rounds` (1 to 5), `q` (0.05 to 0.3) and `clearance`. `rerouteStrategy` is its router strategy.
675
+ - `canalRouter(options)` gives the feeder trees of NAT-004. The edges of one key at a hub are sources of flux, and a link with more flux gets cheaper.
676
+ Its options are `mu` (1 to 3), `steps` (30 to 150), `decay` (0.5 to 2) and `minMembers` (2 to 8). `canalStrategy` is its router strategy.
677
+ - `adamRouter(options)` gives the steps of Adam of RULE-020. The free legs of the routes move away from near legs and boxes, along their normals.
678
+ No point of a run, of a trunk or of two routes moves. A route goes back when it gets more crossings or a break of a hard rule.
679
+ Its options are `eta` (0.01 to 1), `samples` (4 to 32), `steps` (100 to 2000, the budget), `seed` and `clearance`. The same seed gives the same routes. `adamStrategy` is its router strategy.
680
+
619
681
  ### The portfolio router
620
682
 
621
683
  The router `portfolio` is opt-in. It is not in `STRATEGIES`, so the default outputs do not change. [`PORTFOLIO.md`](../../docs/research/PORTFOLIO.md#the-portfolio-router-portfolio-api) gives its tables.
@@ -774,6 +836,24 @@ const { rows, front } = compareStep("curve", graph, { options: { arc: { radius:
774
836
  const lanes = compareStep("curve", graph, { curveRouter: "shared", lanes: { width: 5, maxWidth: 30 }, options: { highway: { jog: "quintic" } } });
775
837
  ```
776
838
 
839
+ ## The corpus families
840
+
841
+ `HIGHWAYS_FAMILIES` lists the 15 generators of the boards of the screen and the site. Each one is a family of `@mark1russell7/layout-contract`, with its dimensions as data. `highwaysRegistry()` makes a registry of them.
842
+
843
+ - The first 6 families make the boards of `screen-v1` and `screen-v2`.
844
+ - `COVERAGE_FAMILIES` adds 9 families: `frame-rows`, `pipeline`, `fan-out`, `two-hubs`, `uneven-sizes`, `thin-bars`, `sparse-long`, `local-mesh` and `bipartite`.
845
+ - The screen set `screen-v3` has the 15 families, each with 10 seeds.
846
+ - `signTestPower(n)` gives the least count of families out of `n` that passes a two-sided sign test at the level 0.05. For 15 families, the count is 12.
847
+
848
+ ```ts
849
+ import { highwaysRegistry, signTestPower } from "@mark1russell7/highways";
850
+
851
+ const { graph } = highwaysRegistry().generate("fan-out", 4, { leaves: 40 });
852
+ console.log(graph.nodes.length, signTestPower(15)); // 41 12
853
+ ```
854
+
855
+ [The corpus families](https://github.com/mark1russell7/highways/blob/main/docs/LAYOUT-RECORDS.md#the-corpus-families-corpus-gen) give the dimensions of each family.
856
+
777
857
  ## The same routes on each platform
778
858
 
779
859
  A transcendental Math function, for example `Math.atan2` or `Math.hypot`, can give a different last bit on another platform or node version. A decision of a router must not depend on that bit.