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: AhlfeldtABMEngine

Pure argmax with LLM-elicited per-type beta_k / kappa_k preferences.

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 to V_ij. For each demographic type k the indirect utility is

V_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 to AhlfeldtMarket.clear is the count of types in each cell. Most users should configure this via HybridDecisionEngine.

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.

  • seed (Optional[int]) – Optional integer seed.

  • **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-type beta_k and kappa_k are stored in self._type_params.

Parameters:
  • agents (list[Agent]) – List of Agent instances.

  • verbose (bool) – When True (default), enables the elicitor’s progress bar and incremental cache writes.

Return type:

None

Returns:

None. Mutates self._type_params and self._elicited_agent_ids.

Raises:
  • ValueError – If self.elicitor is None.

  • 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_ij matrices from log B, log w, log Q, and tau, takes the deterministic argmax for each agent type, and accumulates the empirical choice matrix in self.last_choice_probabilities for consumption by AhlfeldtMarket. Triggers ensure_elicitation() on first call.

Parameters:
  • agents (list[Agent]) – List of Agent instances to decide for.

  • environment – The Environment carrying zones.

  • zone_options (list[str]) – Allowed zone names.

  • prices (dict) – Mapping zone -> Q_i.

Return type:

list[LocationChoice]

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 beta and kappa, 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.

Return type:

dict[int, dict]

Returns:

Dict mapping agent_id -> per-type parameter dict.

Examples

>>> import agent_urban_planning as aup
>>> # engine.ensure_elicitation(agents)
>>> # engine.type_parameters()[0]["beta"]