@mark1russell7/highways 0.8.0 → 0.9.0
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/README.md +74 -8
- package/build/index.d.ts +705 -183
- package/build/index.d.ts.map +1 -1
- package/build/index.js +3458 -1979
- package/build/index.js.map +1 -1
- package/package.json +3 -2
- package/src/bench/compare.ts +174 -5
- package/src/bench/exact/index.ts +4 -0
- package/src/bench/properties.ts +8 -2
- package/src/bench/room.ts +1 -1
- package/src/bench/run.ts +38 -3
- package/src/bench/screen/generators.ts +11 -41
- package/src/bench/screen/screen.ts +16 -10
- package/src/bench/screen/set.ts +156 -49
- package/src/bench/suite.ts +110 -12
- package/src/cases.ts +64 -18
- package/src/families/cases.ts +108 -0
- package/src/families/fixtures.ts +101 -0
- package/src/families/index.ts +36 -0
- package/src/families/model.ts +55 -0
- package/src/fixtures.ts +8 -2
- package/src/highways/soft-keys/index.ts +8 -4
- package/src/highways/stretches.ts +28 -7
- package/src/index.ts +8 -0
- package/src/lane-order.ts +42 -2
- package/src/lane-orders/stretch/index.ts +486 -0
- package/src/lane-orders/stretch/router.ts +22 -0
- package/src/levels/depths/index.ts +57 -0
- package/src/plugs/facing/index.ts +22 -0
- package/src/portfolio/router.ts +44 -0
- package/src/routers/corners.ts +27 -3
- package/src/routers/sections.ts +22 -40
- package/src/routers/shared.ts +51 -19
- package/src/routers/trunks.ts +21 -3
- package/src/segments.ts +8 -26
- package/src/strategies/builtins.ts +54 -2
- package/src/strategies/model.ts +55 -10
- package/src/strategies/options.ts +36 -4
- package/src/strategies/schemas.ts +68 -5
- package/src/whole/pipeline/index.ts +66 -0
package/README.md
CHANGED
|
@@ -107,6 +107,8 @@ Two edges can go along several runs one after the other. The option `laneOrder`
|
|
|
107
107
|
- The default of `trunks` and `shared` is `bundle`. The default of `sections` is `run`, so its runs keep the lane order of version 0.2.0.
|
|
108
108
|
- `orderLanes(run, routes, order)` gives the order of one run. Its default order is `run`.
|
|
109
109
|
- The option changes only the lane order. The routes, the runs and their keys stay the same.
|
|
110
|
+
- The option `stretchOrder` of `shared` and `shared-all` gives one order to each stretch of runs: `none` (the default), `consensus`, `periphery` or `sifting`. The default of `shared-stretch` is `sifting`. `siftPasses` sets the passes of `sifting`.
|
|
111
|
+
- `stretchLaneOrders(runs, options?)` gives the order of each run. `laneStretches` gives the stretches. [One lane order for each stretch](../../docs/research/XPLAT.md#one-lane-order-for-each-stretch-lane-stretch) gives the numbers.
|
|
110
112
|
|
|
111
113
|
The benchmark measures the lanes of `highwayCurves` on the case boards, with each lane order. A crossing in the body is between the middles of the first and the last leg of a bundle. An end crossing is near a merge or a split.
|
|
112
114
|
|
|
@@ -345,10 +347,19 @@ The steps of the pipeline that vary have strategies. Each step has one interface
|
|
|
345
347
|
| Step | Input | Output | Built-in strategies |
|
|
346
348
|
|---|---|---|---|
|
|
347
349
|
| `group` | `Graph` | `Section`: the tree of groups of the router `sections` | `quadtree`, `keys`, `kd`, `cut` |
|
|
350
|
+
| `plugs` | `PlugInput`: the graph, and optionally the ways of the router | `PlugPair[]`: the two plugs of each edge | `facing` |
|
|
348
351
|
| `router` | `Graph` | `Result` | `straight`, `plugs`, `corners`, `corners-smooth`, `trunks`, `shared`, `shared-all`, `sections`, `sections-tree` |
|
|
349
352
|
| `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` |
|
|
353
|
+
| `levels` | `LevelInput`: the graph, the tree of groups and the routes | `Level[]`: the zoom levels of the router `sections` | `depths` |
|
|
350
354
|
| `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` |
|
|
351
355
|
| `room` | `RoomInput`: the boxes and the links of a board, and the tree of sections for `levels` | `Gap[]` | `routes`, `lines`, `levels` |
|
|
356
|
+
| `whole` | `Graph` | `WholeOutput`: the board and its `Result` | `pipeline` |
|
|
357
|
+
|
|
358
|
+
`STEPS` gives the steps in the order of the pipeline: `group`, `plugs`, `router`, `highway`, `levels`, `curve`, `room`, `whole`.
|
|
359
|
+
|
|
360
|
+
- The plugs come before the router, because the router finds its ways between the plugs.
|
|
361
|
+
- The levels come after the routes, because the last level uses the routes.
|
|
362
|
+
- The step `whole` runs the other steps, so it comes last.
|
|
352
363
|
|
|
353
364
|
A strategy has a `step`, a `name`, a `describe` text, its `defaults` and the method `run(input, options?)`. The type of the options comes from `defaults`. Each option that a call does not give gets its default value.
|
|
354
365
|
|
|
@@ -357,7 +368,29 @@ A strategy has a `step`, a `name`, a `describe` text, its `defaults` and the met
|
|
|
357
368
|
- `register(registry, ...strategies)` gives a new registry. It does not change the registry before it.
|
|
358
369
|
- `listStrategies(registry, step)` gives the strategies of a step, in order. `findStrategy` and `getStrategy` give one strategy by its name.
|
|
359
370
|
- `asRouter(strategy, options?)` gives a `Router`, and `routersOf(registry)` gives the routers of a registry.
|
|
360
|
-
- `STRATEGIES` is the registry of `BUILT_IN_STRATEGIES`. The records `groupStrategies`, `routerStrategies`, `highwayStrategies`, `curveStrategies` and `
|
|
371
|
+
- `STRATEGIES` is the registry of `BUILT_IN_STRATEGIES`. The records `groupStrategies`, `plugStrategies`, `routerStrategies`, `highwayStrategies`, `levelStrategies`, `curveStrategies`, `roomStrategies` and `wholeStrategies` give each built-in strategy with its typed options.
|
|
372
|
+
|
|
373
|
+
### The steps `plugs`, `levels` and `whole`
|
|
374
|
+
|
|
375
|
+
Each of these steps has one default strategy. The default gives the output of the code before the step, so each route stays the same.
|
|
376
|
+
|
|
377
|
+
- `facing` (the step `plugs`) puts each free plug on the side that faces the other end of its edge. The router `corners` uses it by default.
|
|
378
|
+
The option `plug` of `corners` takes a plug strategy, and `plugOptions` gives its options.
|
|
379
|
+
- `depths` (the step `levels`) makes one zoom level for each depth of the tree, and a last level with each node alone (`depthLevels`).
|
|
380
|
+
The option `level` of `sections` takes a level strategy, and `levelOptions` gives its options. The strategy also gets the level options of the router.
|
|
381
|
+
- `pipeline` (the step `whole`) runs a room strategy, then a router or a highway plan, with the rules that the router reads (`runPipeline`).
|
|
382
|
+
Without options, it routes with `corners`. The demo of the site runs it. It does not draw the curves.
|
|
383
|
+
- `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`.
|
|
384
|
+
- `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.
|
|
385
|
+
|
|
386
|
+
```ts
|
|
387
|
+
import { asRouter, CASES, plugStrategies, routerStrategies, wholeStrategies } from "@mark1russell7/highways";
|
|
388
|
+
|
|
389
|
+
const graph = CASES.find((c) => c.name === "case-hub-chain")!.make();
|
|
390
|
+
// The two calls give the routes of `corners` with no option.
|
|
391
|
+
const a = asRouter(routerStrategies.corners, { plug: plugStrategies.facing }).route(graph);
|
|
392
|
+
const b = wholeStrategies.pipeline.run(graph).result;
|
|
393
|
+
```
|
|
361
394
|
|
|
362
395
|
### The step `highway`
|
|
363
396
|
|
|
@@ -505,6 +538,7 @@ The router `portfolio` is opt-in. It is not in `STRATEGIES`, so the default outp
|
|
|
505
538
|
- The result has the output, the winner, the trace of the pick and the move count `move.pick`.
|
|
506
539
|
- `exactStretches(graph, options?)` gives a function from the routes to the stretch of each edge in the exact model. The router uses it for the cap. `exactStretch` gives the largest stretch.
|
|
507
540
|
- `portfolioRouter(options?)` gives a `Router`, and `portfolioStrategy` is the router strategy. Add `portfolioStrategy` to a registry of your own to race it.
|
|
541
|
+
- `portfolioStrategy.schema` declares each option except the clock `now` (SCHEMA-GAPS). The lists of `rule`, `cap`, `k` and `hashes` come from `PORTFOLIO_RULES`, `PORTFOLIO_CAPS`, `PORTFOLIO_KS_API` and `PORTFOLIO_HASHES`.
|
|
508
542
|
|
|
509
543
|
```ts
|
|
510
544
|
import { routePortfolio } from "@mark1russell7/highways";
|
|
@@ -512,15 +546,24 @@ import { routePortfolio } from "@mark1russell7/highways";
|
|
|
512
546
|
const { result, winner } = routePortfolio(graph, { rule: "all", cap: 1.25, k: 5, budgetMs: 50 });
|
|
513
547
|
```
|
|
514
548
|
|
|
549
|
+
### The router `shared-stretch`
|
|
550
|
+
|
|
551
|
+
The router `shared-stretch` is opt-in. It is `shared` with the stretch order `sifting`. It is not in `STRATEGIES`, so the default outputs do not change.
|
|
552
|
+
|
|
553
|
+
- `sharedStretchStrategy` is the router strategy. Add it to a registry of your own to race it.
|
|
554
|
+
- Its routes are the routes of `shared`. Only the lane order of the runs changes.
|
|
555
|
+
- On `screen-v1`, the order `sifting` cuts the lane crossings and the broken pairs of `shared` from 21 to 16.
|
|
556
|
+
- Each run calculates the relation of each pair of its lanes. On a dense board of 1000 boxes, a route takes 25 times the time of `shared`.
|
|
557
|
+
|
|
515
558
|
### Declarations of the options
|
|
516
559
|
|
|
517
560
|
Each strategy declares its options in `schema`. A declaration tells the type, the range, the step and the meaning of one option. Tools make controls and sweeps from these declarations, with no other data.
|
|
518
561
|
|
|
519
562
|
| Type | Fields | Values |
|
|
520
563
|
|---|---|---|
|
|
521
|
-
| `number`, `integer` | `min`, `max`, `step`, `scale`, `special`, `marks` | A number. An `integer` takes only whole numbers. |
|
|
564
|
+
| `number`, `integer` | `min`, `max`, `step`, `scale`, `special`, `marks`, `values` | A number. An `integer` takes only whole numbers. With `values`, only one of `values`. |
|
|
522
565
|
| `boolean` | | `false` or `true`. |
|
|
523
|
-
| `enum` | `values` | One of `values`. |
|
|
566
|
+
| `enum` | `values`, `custom` | One of `values`. With `custom: "function"`, also a rule of the caller. |
|
|
524
567
|
| `function`, `strategy`, `list`, `object` | `step` (for `strategy`) | A rule, a strategy, an array or an object. A sweep cannot set them. |
|
|
525
568
|
|
|
526
569
|
Each declaration has a `describe` sentence and an optional `default`.
|
|
@@ -529,18 +572,27 @@ Each declaration has a `describe` sentence and an optional `default`.
|
|
|
529
572
|
- The `scale` is `linear` or `log`. A sweep on the scale `log` gives values with equal ratios.
|
|
530
573
|
- The `special` values are valid outside the range. `Infinity` sets no limit.
|
|
531
574
|
- The `marks` are the notable values: the default and the values of the sweeps of the benchmark.
|
|
575
|
+
- The `values` of a number option are its only valid values. A control shows them as a list, and a sweep gives them. The `cap` of the portfolio router uses them.
|
|
576
|
+
- An enum with `custom: "function"` names the known rules of an option that also takes a rule. A control sets the names, and a caller can still give its own rule.
|
|
532
577
|
- The `default` is the value that the strategy uses when the caller and `defaults` give no value. A value of `defaults` comes first.
|
|
533
578
|
|
|
534
579
|
The type `OptionSchema<O>` needs one declaration for each key of the options, and no other key. A number option needs a number declaration, and an enum declaration takes only the values of its type.
|
|
580
|
+
An option of a rule or its name, for example `GroupRule | "collection" | "all"`, takes an enum of the names or a declaration of the rule.
|
|
581
|
+
|
|
582
|
+
The option `rule` of the routers `trunks`, `shared` and `shared-all`, and of the highway strategies `keys`, `shared-ways` and `soft-keys`, takes a name (SCHEMA-GAPS):
|
|
583
|
+
|
|
584
|
+
- With `collection`, the rule is `byCollection`. With `all`, each edge has one key. For the router `shared`, `all` is the same as no rule.
|
|
585
|
+
- The `defaults` of each strategy keep the rule `byCollection`, as before. The declaration gives its name `collection` as its `default`. The router `shared-all` sets no rule.
|
|
586
|
+
- A rule of the caller stays valid. The name `collection` gives the same output as the rule `byCollection`.
|
|
535
587
|
|
|
536
588
|
The helpers read the declarations:
|
|
537
589
|
|
|
538
590
|
- `optionDefaults(strategy)` gives the effective default of each option. The strategy gives the same output with this object as with no options.
|
|
539
591
|
- `listOptions(strategy)` gives each option with its key, its declaration and its default, in the order of the schema.
|
|
540
|
-
- `checkOptions(strategy, options)` reports each value without a declaration, of the wrong type, out of the range
|
|
541
|
-
- `clampOptions(strategy, options)` moves each number into its range, for a control. A special value stays.
|
|
592
|
+
- `checkOptions(strategy, options)` reports each value without a declaration, of the wrong type, out of the range, not a whole number or not one of `values`. It changes no value.
|
|
593
|
+
- `clampOptions(strategy, options)` moves each number into its range, for a control. A number with `values` moves to the nearest value. A special value stays.
|
|
542
594
|
- `checkSchema(strategy)` reports each option of `defaults` without a declaration, and each bad declaration.
|
|
543
|
-
- `sweepValues(declaration, { count, special })` gives the values of a sweep. Without `count`, a number option gives its `marks`.
|
|
595
|
+
- `sweepValues(declaration, { count, special })` gives the values of a sweep. Without `count`, a number option gives its `marks`. Else, a number option with `values` gives its `values`.
|
|
544
596
|
- `sweepOf(strategy, key, options)` gives one setting for each value of a sweep. The name of a setting is the key and the value.
|
|
545
597
|
- `sweepGrid(strategy, keys, options)` gives one setting for each combination of the values of the keys.
|
|
546
598
|
|
|
@@ -556,7 +608,7 @@ const rows = sweepSections("case-hub-chain", graph, sweepOf(routerStrategies.sec
|
|
|
556
608
|
|
|
557
609
|
A test examines each built-in strategy with `checkSchema`. Thus an option of `defaults` without a declaration makes the test fail.
|
|
558
610
|
|
|
559
|
-
The plugs
|
|
611
|
+
The step `plugs` gives the plugs of the router `corners`. The step `group` gives the grouping rule of the zoom levels, and the step `levels` makes the levels.
|
|
560
612
|
|
|
561
613
|
## Measures and the report
|
|
562
614
|
|
|
@@ -596,7 +648,20 @@ The script `bench` takes `--seeds <n>` and `--report <file>`. A family with more
|
|
|
596
648
|
|
|
597
649
|
The workflow `Bench` runs the suite in parts. Each part writes its report, and `joinReports` joins the reports into the report of one run.
|
|
598
650
|
|
|
599
|
-
|
|
651
|
+
Three options of `runSuite` keep each part short (BENCH-GREEN):
|
|
652
|
+
|
|
653
|
+
- `shard` runs one shard of the cells of the steps `router` and `highway`. The strategy at place `s` on the seed `k` belongs to the shard `(s + k) % count`.
|
|
654
|
+
- `caps` stops a strategy above a fixture size. The report lists each such cell in `capped`.
|
|
655
|
+
- `pair` names a baseline router, for example `shared`. On the first seed of each fixture to `pairMax` nodes, the baseline routes in turn with each strategy. The row gets `paired`, with the two medians and their ratio.
|
|
656
|
+
|
|
657
|
+
`compareStep` runs each strategy of one step on one board, with the measures of the suite. It gives one row for each strategy and the Pareto front of the step. The options give each strategy its own options.
|
|
658
|
+
|
|
659
|
+
`compareAnyStep` does the same for each step of `COMPARE_ALL_STEPS`, which is `STEPS`. The compare page of the site uses it.
|
|
660
|
+
|
|
661
|
+
- The step `highway` makes the plan of each strategy, and `follow` routes the plan, as in the screen. `highwayRouters` gives these routers.
|
|
662
|
+
- The steps `plugs`, `levels` and `whole` run each strategy as a router (`stepRouterStrategy`), and measure the routes as the step `router`.
|
|
663
|
+
- The step `room` opens the gaps of a packed board with each strategy and measures the open board with `roomValues`.
|
|
664
|
+
- The option `onRow` gets each row when its strategy is done, so a host can show the progress.
|
|
600
665
|
|
|
601
666
|
With the option `lanes`, the step `curve` opens each shared way of the routes of `curveRouter` into lanes, and each curve draws the lanes. Each input then has its `lane`, so the curve `highway` bends the lanes of a bundle as one with each of its options.
|
|
602
667
|
|
|
@@ -615,6 +680,7 @@ A transcendental Math function, for example `Math.atan2` or `Math.hypot`, can gi
|
|
|
615
680
|
- For a new decision, use exact arithmetic: a cross product, a dot product or a squared length.
|
|
616
681
|
- A compare function of a sort must be a total order. Otherwise, two engines can give two orders.
|
|
617
682
|
- The lane order of a run comes from a merge sort of the package, so each engine gives the same order (LANE-ORDER).
|
|
683
|
+
- Each sort of the stretch orders (LANE-STRETCH) has a total order. Its ties break by the key of the edge or of the run. Thus the 4 cells of `Xplat` agree.
|
|
618
684
|
- Version 0.8.0 changes the default lane order of some shared runs. No route point moves. [The lane order](../../docs/research/XPLAT.md#the-lane-order-lane-order) gives the changes.
|
|
619
685
|
- The note [`XPLAT.md`](../../docs/research/XPLAT.md) gives the result of the item XPLAT-HASH.
|
|
620
686
|
|