WorkersDecideFirmsToApply#
- class bamengine.events.labor_market.WorkersDecideFirmsToApply[source]#
Bases:
EventUnemployed workers choose up to max_M firms to apply to, sorted by wage.
Unemployed workers build an application queue by sampling firms and sorting them by wage offer (descending). Workers apply the loyalty rule: if their contract expired (not fired), they prioritize their previous employer.
The
job_search_methodconfig parameter controls which firms are sampled:"vacancies_only": Sample only from firms with open vacancies."all_firms"(default): Sample from ALL firms. Applications to firms without vacancies are “wasted” (the firm simply doesn’t hire).
Algorithm
For each unemployed worker j:
Sample min(max_M, n_firms) firms randomly from eligible pool
Sort sampled firms by wage offer (descending)
Apply loyalty rule — if worker’s contract expired (not fired) AND previous employer is hiring, move previous employer to position 0 (top priority)
Store sorted application queue in worker’s buffer
Reset contract_expired and fired flags
Mathematical Notation
Let \(H\) be the set of eligible firms:
If
job_search_method="vacancies_only": \(H = \{i : V_i > 0\}\) (firms with vacancies)If
job_search_method="all_firms": \(H = \{1, ..., N\}\) (all firms)
For unemployed worker j:
\[\text{Sample}_j \sim \text{Random}(H, k=\min(M, |H|), \text{replace}=False)\]Then sort by wage:
\[\text{Queue}_j = \text{argsort}_{\text{desc}}(w_i \text{ for } i \in \text{Sample}_j)\]If loyalty applies (contract expired, not fired, previous employer hiring):
\[\text{Queue}_j[0] = \text{employer\_prev}_j\]Examples
Execute this event:
>>> import bamengine as be >>> sim = be.Simulation.init(n_firms=100, n_households=500, seed=42) >>> event = sim.get_event("workers_decide_firms_to_apply") >>> event.execute(sim)
Check unemployed workers prepared applications:
>>> import numpy as np >>> unemployed_mask = ~sim.wrk.employed >>> unemployed_mask.sum() 20
Inspect application queue for unemployed worker:
>>> unemployed_ids = np.where(~sim.wrk.employed)[0] >>> if len(unemployed_ids) > 0: ... worker_id = unemployed_ids[0] ... targets = sim.wrk.job_apps_targets[worker_id] ... # First 3 targets (may include -1 if fewer than max_M firms hiring) ... targets[:3] array([45, 23, 67])
Check loyalty rule application:
>>> # Workers with expired contracts should have previous employer at position 0 >>> # (if previous employer is hiring) >>> expired_mask = (sim.wrk.contract_expired == 1) & (~sim.wrk.employed) >>> expired_mask.sum() 5
Notes
This event must execute after FirmsDecideWageOffer (need wage offers for sorting).
Only unemployed workers prepare applications. Employed workers are skipped.
The loyalty rule implements realistic worker behavior: workers whose contracts expired naturally (not fired) prefer to stay with their previous employer if possible.
Workers sample firms randomly then sort by wage. This means workers may miss the highest-wage firms if they are not in the random sample. The max_M parameter controls how many firms each worker can apply to.
See also
FirmsDecideWageOfferDetermines wage offers used for sorting
LaborMarketRoundProcesses applications from queue
WorkerEmployment state with application queue
bamengine.events._internal.labor_market.workers_decide_firms_to_applyImplementation
- execute(sim)[source]#
Execute the event’s logic.
Mutates simulation state in-place. This method must be implemented by all Event subclasses.
- Parameters:
sim (
Simulation) – The simulation instance containing all state and configuration.- Returns:
All mutations are in-place.
- Return type:
Examples
Implement execute in a custom event:
>>> from bamengine import event, ops >>> >>> @event ... class CustomPricingEvent: ... def execute(self, sim): ... prod = sim.get_role("Producer") ... # Apply 10% markup to all prices ... new_prices = ops.multiply(prod.price, 1.1) ... ops.assign(prod.price, new_prices)
Access configuration and RNG:
>>> @event ... class StochasticEvent: ... def execute(self, sim): ... shock = sim.config.h_rho ... random_values = sim.rng.uniform(0, shock, size=sim.n_firms) ... # Use random_values in calculations
Notes
The execute method receives full Simulation access, including: - All roles: sim.get_role(“RoleName”) or sim.prod, sim.wrk, etc. - Configuration: sim.config - RNG: sim.rng - Economy state: sim.ec
- __init__()#
- name = 'workers_decide_firms_to_apply'#