Commits

howthebodyworks  committed 2f695ae

permute bid order, optionally favouring the current employer, so that firm ordering does not determine place of employment.

  • Participants
  • Parent commits 7e3c4ed

Comments (0)

Files changed (3)

   * move wage attribute into being a relational property between worker and
     firm
   * move stats out of World
+  * key is very unstable - seems to vary with code changes that are not param
+    changes. WTF?
     
 * Sim decisions
 

File src/exp_settings.py

     firm_competitiveness_fn='fns.power_competitiveness',
     firm_returns_fn='fns.linear_market',
     firm_bid_fn='fns.uniform_bid_in_firm_profit_range',
+    favour_own_boss=False,
     firm_initial_funds_pie=1,
     worker_canonical_valuator='fns.assign_worker_k_share_firm_income',
     worker_canonical_valuation_lagger='fns.lag_valuations',
 safeish_workers = dict(
     wage_ratchets=False,
     firm_bid_fn='fns.uniform_bid_in_firm_profit_range_keeping_good_staff',
+    favour_own_boss=True,
 )
 
 default = {}
 
 ################################################################
 # auction functions
+def _massage_bid_order_to_favour_boss(bid_order, firm_list, worker):
+    """this function returns a permutation that references the current boss
+    last, to favour staying put in the event of equal bids"""
+    #operate on a copy:
+    l = list(bid_order)
+    bid_order.append(bid_order.pop(firm_list.index(worker.firm)))
+    return l
+    
+def _leave_bid_order_alone(bid_order, firm_list, worker):
+    return bid_order
 
 def single_random_staff_auction(world):
     """
     wage_ratchets = world.params.get('auction_wage_ratchets', False)
     firm_bid_fn = get_callable(world.params['firm_bid_fn'])
     firm_private_worker_valuator = get_callable(world.params['firm_private_worker_valuator'])
+    favour_own_boss = world.params.get('favour_own_boss', False)
     
+    if favour_own_boss:
+        massage_bid_order = _massage_bid_order_to_favour_boss
+    else:
+        massage_bid_order = _leave_bid_order_alone
+        
     # get a gradual permutation of the firms so that no particular firm is a
     # favoured employer for equal bids
     num_firms = len(world.firms)
-    firm_permutation = sample(range(num_firms), num_firms)
+    bid_order = sample(range(num_firms), num_firms)
     firm_list = world.firms
     
     for worker in world.workers:
         firm_bids = {}
+        #rotate the permutation to keep it fresh
+        bid_order.append(bid_order.pop(0))
         
-        for firm_idx in firm_permutation:
+        for firm_idx in massage_bid_order(bid_order, firm_list, worker):
             firm = firm_list[firm_idx]
             valuation = firm_private_worker_valuator(firm, worker, world)
             bid = firm_bid_fn(firm, worker, valuation, world)
             firm_bids[firm] = bid
         
-        #rotate the permutation to keep it fresh
-        firm_permutation.append(firm_permutation.pop(0))
-        
         #OK, now we have some fair, if naïve, bids.
         #Let's see which worker ends up where
         
         best_firm, best_wage = None, 0.0
         for firm, wage in firm_bids.iteritems():
-            if wage > best_wage:
+            if wage >= best_wage:
                 best_firm, best_wage = firm, wage
         #Do any bids exceed current wage?
         if (wage_ratchets and (best_wage > worker.wage)) or \
                 worker.join(best_firm,
                     wage=best_wage,
                     valuation=valuation)
-            # If best_firm *is* none, we have an unemployed worker.
-            # this is possible if a firm has zero profit, i.e.
-            # the staff all fall out.
+            else:
+                # If best_firm *is* None, we have an unemployed worker.
+                # When does this happen?
+                world.engine.message("no winning bids for %s", worker)
 
 ################################################################
 # bid generating functions