Remove ratio_circulation: the score is already a ratio
Owner: "I think a corridor could be worth a sixth of a room, this is ok. maybe we should dump the ratio_circulation altogether if there is already a pressure in circulation caused by the cost benefit ratio per msq. this is the kind of thing we want to root out of the scoring model: anything that is double counting, or using a gaussian where a linear ramp is appropriate, etc." value_circulation = 50 stands; hxi's rate question is closed. The duplication argument is stronger than it first looks. score = value/cost is already a ratio, so the per-m2 economics (50 against a build cost of 200) is not merely an absolute pressure -- adding corridor moves value/cost by an amount that depends on how much of the building is already corridor. It is ALREADY proportional. ratio_circulation said the same thing again as a whole-building multiplier, on a curve where twice the corridor is far more than twice as bad. Correction to my own first measurement: I overrode ratio_circulation and got scores going DOWN when a <=1 multiplier was removed, which is impossible. All four corpus programmes DECLARE ratio_circulation, so the CONF_DEFAULTS value I had changed was never in play and the two arms differed only in sigma. Same trap as value_supported in 39.19. Against the keep-it case, recorded because it is the one real argument: three of four declare a POSITIVE target (harbor/maple 0.08, health-centre 0.10), making the term formally two-sided rather than "less is better". It does not survive the numbers -- the lower side is worth at most 13.3% on the large programmes against 99% on the upper side, and "a building needs some circulation" is enforced structurally by access and connectivity, which no amount of value can buy off. Disabled in CONF_DEFAULTS and the four corpus configs, each with the reason inline and a note that a [target, sigma] pair re-enables it. Fail sets unchanged; it was always a value multiplier. Scores +42% to +7712%. 39.24 also sweeps every remaining term against the owner's two tests. Verdicts: perpendicular, proportion, width, crinkliness, access, size's lower side, ratio_outside, staircase volume and the count/limit fails are all sound. Filed as homemaker-py-dpt: size's UPPER side (cost already charges area; 82% of size fails are over-target), the minimum-internal-area factor (a third statement of "build the rooms"), the 0.5**n_fails curve (a ruling, not a measurement), and two dead paths -- ratio_public/private_outside, which no config declares, and the daylight factor pinned to 1.0 since the descope. Also updated a test I added last turn which asserted ratio_circulation was the second charge; it now pins that the linear ramp is the ONLY one. 419 passed. Closes homemaker-py-hxi. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MJ84Feep79Hhm3E4zZJmnB
This commit is contained in:
parent
f07b3865ef
commit
a7ef9e2fa0
7 changed files with 144 additions and 16 deletions
80
DESIGN.md
80
DESIGN.md
|
|
@ -7971,3 +7971,83 @@ untouched and unruled: `value_circulation` = 50 against `value_inside` = 300, a
|
|||
room per square metre is a design judgement, not something measurement settles,
|
||||
and the linear ramp the owner describes is only as steep as that number makes
|
||||
it. Left open on the bead.
|
||||
|
||||
### 39.24 `ratio_circulation` removed, and a sweep for the rest of its kind (`homemaker-py-hxi`)
|
||||
|
||||
Owner, closing the rate question and opening a general one:
|
||||
|
||||
> I think a corridor could be worth a sixth of a room, this is ok. maybe we
|
||||
> should dump the ratio_circulation altogether if there is already a pressure in
|
||||
> circulation caused by the cost benefit ratio per msq. this is the kind of
|
||||
> thing we want to root out of the scoring model: anything that is double
|
||||
> counting, or using a gaussian where a linear ramp is appropriate, etc.
|
||||
|
||||
So `value_circulation = 50` stands, and `hxi`'s rate question is closed.
|
||||
|
||||
**`ratio_circulation` is a duplicate, and the argument is stronger than it first
|
||||
looks.** The score is `value / cost` — already a ratio. So the per-m² economics
|
||||
(50 against a build cost of 200) is not merely an *absolute* pressure against
|
||||
corridor area: adding corridor moves `value/cost` by an amount that depends on
|
||||
how much of the building is already corridor. It is **already proportional**.
|
||||
`ratio_circulation` states the same thing a second time, as a whole-building
|
||||
multiplier, on a curve where twice the corridor is far more than twice as bad.
|
||||
|
||||
**A correction to my own first measurement.** I initially measured this by
|
||||
overriding `ratio_circulation` and comparing — and got scores going *down* when
|
||||
a ≤1 multiplier was removed, which is impossible. The cause: all four corpus
|
||||
programmes **declare** `ratio_circulation` themselves, so the `CONF_DEFAULTS`
|
||||
value I had changed was never in play, and my "with" arm was accidentally
|
||||
comparing two different sigmas. The same trap as `value_supported` in §39.19.
|
||||
Measured properly, disabling it raises every score, by +42% to +7712%
|
||||
(programme-house s2, which is 44% circulation).
|
||||
|
||||
**And the declared values are not what the default suggests:**
|
||||
|
||||
| programme | declared | worst the *lower* side can cost |
|
||||
|---|---|---|
|
||||
| harbor-house | [0.08, 0.15] | 13.3% |
|
||||
| maple-court | [0.08, 0.15] | 13.3% |
|
||||
| health-centre | [0.10, 0.12] | 29.3% |
|
||||
| programme-house | [0.00, 0.15] | 0% |
|
||||
| `CONF_DEFAULTS` | [0.00, 0.20] | 0% |
|
||||
|
||||
Three of the four target a *positive* circulation fraction, so the term is
|
||||
formally two-sided, not "less is better" — and a two-sided target is exactly
|
||||
what a gaussian is for. That is the one argument for keeping it. It does not
|
||||
survive the numbers: the lower side ("a building needs some circulation") is
|
||||
worth at most 13% on the two large programmes, while the upper side reaches
|
||||
99%, and the lower side's job is done structurally anyway by the access and
|
||||
connectivity checks, which no amount of value can buy off. What is left is an
|
||||
upper-side penalty, and the upper side is the duplicated one.
|
||||
|
||||
**Shipped:** `ratio_circulation` disabled — `None` in `CONF_DEFAULTS` and in the
|
||||
four corpus `patterns.config` files, each with the reason inline and a note that
|
||||
a `[target, sigma]` pair re-enables it. Fail sets are unchanged; it was always a
|
||||
value multiplier, never a fail source.
|
||||
|
||||
**The sweep.** Every term in the objective, against the two tests the owner
|
||||
named — does it double-count, and is a gaussian the right curve for what it
|
||||
measures?
|
||||
|
||||
| term | measures | shape | verdict |
|
||||
|---|---|---|---|
|
||||
| perpendicular | corner angle vs 90° | two-sided gaussian | **OK** — a right angle is a genuine optimum |
|
||||
| proportion | aspect vs target | clipped, one free side | **OK** |
|
||||
| width | narrowest vs minimum | clipped, one free side | **OK** |
|
||||
| crinkliness | daylight per unit floor | one-sided since §39.14 | **OK** |
|
||||
| access | has a circulation neighbour | binary | **OK** — not a curve |
|
||||
| size, *lower* side | area vs programme target | gaussian | **OK** — a room has a right size |
|
||||
| size, *upper* side | area over target | gaussian | **SUSPECT** — `cost` already charges floor area, and an oversize room is wasteful in proportion, not quadratically. §39.15 found 82% of size fails are over-target. Not changed: §39.15 also found this upper half is the main brake on growth, so removing it needs the value rates looked at first. |
|
||||
| ratio_outside | outdoor fraction vs target | two-sided gaussian | **OK** — and its binding side counters the economics rather than duplicating it, since outdoor space is profitable |
|
||||
| ratio_circulation | circulation fraction | gaussian, effectively one-sided | **REMOVED** |
|
||||
| min internal area | total room area below 1.2× the programme | one-sided gaussian | **SUSPECT** — "build the rooms you were asked for" is already said by the missing-space fails and again by `quality_size`. A third statement of it. |
|
||||
| staircase volume | stair fit | gaussian | **OK** — a stair has a right size |
|
||||
| stair count, storey limits | counts vs bounds | binary fails | **OK** |
|
||||
| `ratio_public_outside`, `ratio_private_outside` | boundary-length ratios | gaussian | **DEAD** — absent from `CONF_DEFAULTS` and from every corpus config, so the branch never runs |
|
||||
| `daylight` factor | pinned to 1.0 | constant | **DEAD** — `URB_NO_OCCLUSION` (§6); it is a factor that can never be anything but 1 |
|
||||
| `0.5 ** n_fails` | fail count | exponential | **RULING WANTED** — each failure independently halves the building. Coherent as a product of independent defects, but it is not "twice as many failures is twice as bad", and it is the single largest term in the objective. |
|
||||
|
||||
The three SUSPECT entries and the fail multiplier are filed rather than changed
|
||||
— each needs a ruling or a rate change behind it, and §39.16 is the standing
|
||||
reminder about acting on an inherited constant before understanding what it
|
||||
measures. The two DEAD entries are inert and cost nothing but confusion.
|
||||
|
|
|
|||
|
|
@ -267,9 +267,14 @@ storey_limit: 3
|
|||
force_roof_garden: 0
|
||||
|
||||
# Circulation ratio (allow more circulation for larger building)
|
||||
# homemaker-py-hxi (DESIGN.md §39.24): disabled. The score is value/cost, a
|
||||
# ratio, so the per-m2 economics (circulation worth 50 against a build cost of
|
||||
# 200) is ALREADY a proportional pressure against circulation -- this said the
|
||||
# same thing a second time, and with a curve where twice the corridor is far
|
||||
# more than twice as bad. Its other side, "a building needs some circulation",
|
||||
# was worth at most 13% here and is enforced structurally anyway by the access
|
||||
# and connectivity checks. Set a [target, sigma] pair to re-enable.
|
||||
ratio_circulation:
|
||||
- 0.08
|
||||
- 0.15
|
||||
|
||||
# Outside space ratio (courtyard requirement)
|
||||
ratio_outside:
|
||||
|
|
|
|||
|
|
@ -351,9 +351,14 @@ storey_minimum: 1
|
|||
storey_limit: 2
|
||||
force_roof_garden: 0
|
||||
|
||||
# homemaker-py-hxi (DESIGN.md §39.24): disabled. The score is value/cost, a
|
||||
# ratio, so the per-m2 economics (circulation worth 50 against a build cost of
|
||||
# 200) is ALREADY a proportional pressure against circulation -- this said the
|
||||
# same thing a second time, and with a curve where twice the corridor is far
|
||||
# more than twice as bad. Its other side, "a building needs some circulation",
|
||||
# was worth at most 13% here and is enforced structurally anyway by the access
|
||||
# and connectivity checks. Set a [target, sigma] pair to re-enable.
|
||||
ratio_circulation:
|
||||
- 0.10
|
||||
- 0.12
|
||||
|
||||
ratio_outside:
|
||||
- 0.06
|
||||
|
|
|
|||
|
|
@ -406,9 +406,14 @@ storey_limit: 4
|
|||
force_roof_garden: 0
|
||||
|
||||
# Circulation ratio (allow more circulation for larger building)
|
||||
# homemaker-py-hxi (DESIGN.md §39.24): disabled. The score is value/cost, a
|
||||
# ratio, so the per-m2 economics (circulation worth 50 against a build cost of
|
||||
# 200) is ALREADY a proportional pressure against circulation -- this said the
|
||||
# same thing a second time, and with a curve where twice the corridor is far
|
||||
# more than twice as bad. Its other side, "a building needs some circulation",
|
||||
# was worth at most 13% here and is enforced structurally anyway by the access
|
||||
# and connectivity checks. Set a [target, sigma] pair to re-enable.
|
||||
ratio_circulation:
|
||||
- 0.08
|
||||
- 0.15
|
||||
|
||||
# Outside space ratio (courtyard requirement)
|
||||
ratio_outside:
|
||||
|
|
|
|||
|
|
@ -82,9 +82,14 @@ storey_limit: 5
|
|||
force_roof_garden: 0
|
||||
|
||||
# Circulation ratio (penalise excessive corridors)
|
||||
# homemaker-py-hxi (DESIGN.md §39.24): disabled. The score is value/cost, a
|
||||
# ratio, so the per-m2 economics (circulation worth 50 against a build cost of
|
||||
# 200) is ALREADY a proportional pressure against circulation -- this said the
|
||||
# same thing a second time, and with a curve where twice the corridor is far
|
||||
# more than twice as bad. Its other side, "a building needs some circulation",
|
||||
# was worth at most 13% here and is enforced structurally anyway by the access
|
||||
# and connectivity checks. Set a [target, sigma] pair to re-enable.
|
||||
ratio_circulation:
|
||||
- 0.00
|
||||
- 0.15
|
||||
|
||||
# Outside space ratio
|
||||
ratio_outside:
|
||||
|
|
|
|||
|
|
@ -210,7 +210,25 @@ CONF_DEFAULTS: dict = {
|
|||
"door_width": 1.2,
|
||||
"plot_ratio": [2.00, 0.50],
|
||||
"ratio_outside": [0.33, 0.15],
|
||||
"ratio_circulation": [0.00, 0.20],
|
||||
# homemaker-py-hxi (DESIGN.md §39.24). Was [0.00, 0.20] -- a gaussian on
|
||||
# the circulation FRACTION, targeting zero, applied as a multiplier to the
|
||||
# whole building's value (0.013..0.70 across the corpus). `None` disables
|
||||
# it, because it double-counts and does so with the wrong curve.
|
||||
#
|
||||
# The score is `value / cost`, which is already a ratio, so the per-m2
|
||||
# economics -- circulation worth 50 against a build cost of 200 -- is
|
||||
# already a PROPORTIONAL pressure and not merely an absolute one: adding
|
||||
# corridor moves value/cost by an amount that depends on how much of the
|
||||
# building is already corridor. A second, super-linear term on the same
|
||||
# quantity says the same thing twice, and says it with a curve where twice
|
||||
# the corridor is far more than twice as bad (0.10 -> x0.882, 0.20 ->
|
||||
# x0.607, 0.40 -> x0.135).
|
||||
#
|
||||
# Contrast `ratio_outside`, which is KEPT: its target is 0.33, not zero, so
|
||||
# it is a genuine two-sided requirement rather than "less is better", and
|
||||
# its binding side (do not build too much outdoor space) is not something
|
||||
# the economics expresses -- outdoor space is profitable.
|
||||
"ratio_circulation": None,
|
||||
# PROVENANCE (DESIGN.md §39.16). This is Christopher Alexander, A Pattern
|
||||
# Language 159, "Light on Two Sides of Every Room" -- not an arbitrary
|
||||
# constant. The factor is evaluated at `1/crink = A/(L*h)`: floor area per
|
||||
|
|
@ -2048,7 +2066,8 @@ class Fitness:
|
|||
factor *= self.ratio_o(ratios)
|
||||
|
||||
circ_ratio = self.conf("ratio_circulation")
|
||||
factor *= self.ratio_type(ratios, "c", circ_ratio[0], circ_ratio[1])
|
||||
if circ_ratio is not None: # §39.24: off by default
|
||||
factor *= self.ratio_type(ratios, "c", circ_ratio[0], circ_ratio[1])
|
||||
|
||||
min_required = 0.0
|
||||
for req in (self._programme or {}).values():
|
||||
|
|
|
|||
|
|
@ -150,13 +150,22 @@ def test_twice_the_corridor_is_exactly_twice_as_bad():
|
|||
"so, §39.23's justification needs revisiting")
|
||||
|
||||
|
||||
def test_the_amount_of_circulation_is_still_priced():
|
||||
"""Removing the per-leaf cap must not make corridors free. Two charges
|
||||
remain, and they are the ones that do not depend on how it is cut up."""
|
||||
def test_the_amount_of_circulation_is_priced_exactly_once():
|
||||
"""Removing the per-leaf cap must not make corridors free -- but the charge
|
||||
that remains must also be the ONLY one (§39.24).
|
||||
|
||||
The linear ramp is `value_circulation` against the build cost: every square
|
||||
metre of corridor is worth less than it costs, and because the score is
|
||||
`value / cost` that pressure is already proportional to how much of the
|
||||
building is corridor. `ratio_circulation` said the same thing a second time
|
||||
and is disabled; if it comes back, either it has a justification this test
|
||||
does not know about or the double count has returned.
|
||||
"""
|
||||
fit = _fit()
|
||||
assert fit.conf("value_circulation") < fit.cost("inside"), (
|
||||
"a corridor must cost more to build than it is worth, or there is no "
|
||||
"linear ramp pushing the search to use less of it")
|
||||
assert fit.conf("ratio_circulation") is not None, (
|
||||
"the building-level circulation fraction check is the other charge"
|
||||
)
|
||||
assert fit.conf("ratio_circulation") is None, (
|
||||
"ratio_circulation duplicates the per-m2 economics (§39.24)")
|
||||
assert fit.conf("size_circulation") is None, "§39.23"
|
||||
assert fit.conf("proportion_circulation") is None, "§39.22"
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue