agent_urban_planning.AhlfeldtArgmaxHybridEngine¶
- class AhlfeldtArgmaxHybridEngine(params, elicitor=None, *, preference_cache_dir='.cache/llm_preferences_berlin_v4', clip_warn_threshold=0.05, seed=None, **kwargs)[source]¶
Bases:
AhlfeldtABMEnginePure argmax with LLM-elicited per-type
beta_k/kappa_kpreferences.The V4 engine. Combines per-type heterogeneous preferences from Run 1-H’s elicitation pipeline with the aggregate-from-counts pattern of
AhlfeldtABMEngine, but with no Fréchet / Normal / shock added toV_ij. For each demographic typekthe indirect utility isV_ij(k) = log B_i + log w_j - (1 - beta_k) log Q_i - kappa_k * tau_ij
and the choice
(i*_k, j*_k)is the deterministic argmax. The aggregate empirical choice matrix passed toAhlfeldtMarket.clearis the count of types in each cell. Most users should configure this viaHybridDecisionEngine.- Parameters:
params (
AhlfeldtParams) – Structural Ahlfeldt parameters.elicitor – Object exposing
elicit_batch(agents, cache_dir, verbose)that returns per-agent preference weights (e.g.simulator.decisions.elicitation.LLMPreferenceElicitor).preference_cache_dir (
str|Path) – Directory for caching elicited preferences across runs.clip_warn_threshold (
float) – Fraction of clipped scaling factors above which a warning is logged.**kwargs – Forwarded to
AhlfeldtABMEngine.
Examples
>>> import agent_urban_planning as aup >>> # Prefer the public wrapper: >>> # engine = aup.HybridDecisionEngine(params, elicitor=elicitor)
- ensure_elicitation(agents, verbose=True)[source]¶
Elicit LLM preferences and compute per-type
beta_k,kappa_k.Idempotent: re-calling with the same agent set is a no-op. On first call the configured elicitor is invoked once per agent type, results are cached on disk under
self.preference_cache_dir, and weight-weighted renormalization is applied across the four preference axes (housing, commute, services, amenities). Per-typebeta_kandkappa_kare stored inself._type_params.- Parameters:
- Return type:
- Returns:
None. Mutates
self._type_paramsandself._elicited_agent_ids.- Raises:
ValueError – If
self.elicitorisNone.RuntimeError – If a per-axis renormalization mean is non-positive (indicates degenerate elicitation).
Examples
>>> import agent_urban_planning as aup >>> # engine = aup.HybridDecisionEngine(params, elicitor=el) >>> # engine.ensure_elicitation(list(population))
- decide_batch(agents, environment, zone_options, prices)[source]¶
Pure argmax over per-type
V_ij(k)with LLM-elicited preferences.Builds per-type
V_ijmatrices from log B, log w, log Q, andtau, takes the deterministic argmax for each agent type, and accumulates the empirical choice matrix inself.last_choice_probabilitiesfor consumption byAhlfeldtMarket. Triggersensure_elicitation()on first call.- Parameters:
- Return type:
- Returns:
List of
LocationChoice, one per input agent and in the same order.
Examples
>>> import agent_urban_planning as aup >>> # engine = aup.HybridDecisionEngine(params, elicitor=el) >>> # choices = engine.decide_batch(agents, env, zones, prices)
- type_parameters()[source]¶
Return a snapshot of the per-type scaling parameters.
Each type’s record contains the scaled
betaandkappa, the raw LLM scores per axis (alpha_Q,alpha_tau,alpha_B,alpha_w), and the per-axis renormalized scaling factors (scaling_Q,scaling_tau). Used for diagnostic output and for paper tables.Examples
>>> import agent_urban_planning as aup >>> # engine.ensure_elicitation(agents) >>> # engine.type_parameters()[0]["beta"]