def average_white_needs(): average_needs = GoodsVector(self.goods) for pop in self.pops.values(): if type(pop) is WhiteCollar: needs = pop.cumulated_needs({0, 1}) for good, qty in needs.items(): average_needs[good] += qty / initial_white_collars return average_needs
def compute_production_capacity(self): """ Sum of all production in a period for each good """ prod_capacity = GoodsVector(self.goods) for firm in self.firms.values(): productivity = firm.adjusted_productivity() good = firm.product prod_capacity[good] += firm.workers_for(0) * productivity return prod_capacity
def compute_cum_needs(self, level=2): """ Sum of all the needs of everyone up to a certain level """ cumulated_needs = GoodsVector(self.goods) for pop in self.pops.values(): cumulated_needs += pop.cumulated_needs( {l for l in range(level + 1)}) return cumulated_needs
def cumulated_needs(self, levels=None): cum_needs = {good: 0 for good in self.goods} for good, l, qty in self.needs: if levels is None: cum_needs[good] += self.population * qty elif l in levels: cum_needs[good] += self.population * qty return GoodsVector(self.goods, cum_needs)
def compute_ratio_needs(self, level=2): """ Finds how much of the cumulated needs up to a level can be satisfied by actual production """ ratio_needs_prod = GoodsVector(self.goods) cum_needs = self.compute_cum_needs(level) prod_capacity = self.compute_production_capacity() for good in self.goods: ratio_needs_prod[good] = prod_capacity[good] / cum_needs[good] return ratio_needs_prod
def __init__(self, id_pop, pop_type, goods, needs, population, employed, savings, thrift, investment_propensity): super().__init__() self.id_pop = id_pop self.pop_type = pop_type self.goods = goods self.needs = needs self._levels = sorted(list(set(l for _, l, _ in needs))) self.population = population self.demand = GoodsVector(self.goods) self.consumption = GoodsVector(self.goods) self.employed = employed # Cash accounts self.income = 0 self.savings = savings self.available_income = self.income self.thrift = thrift self.investment_propensity = investment_propensity self._world = None
def ideal_economy(self): def adjusted_productivity(productivity, blue_workers, white_workers): def productivity_boost(x): x = min(x, 0.15) return math.log(1 + 4 * x - 10 * x**2) ratio = white_workers / (white_workers + blue_workers) if white_workers != 0 else 0 return (1 + productivity_boost(ratio)) * productivity cum_needs = {i: GoodsVector(self.goods) for i in range(3)} for level in range(3): for pop in self.pops.values(): if type(pop) is not Capitalist: cum_needs[level] += pop.cumulated_needs({level}) # For each good, retain the best productivity that the firms can offer productivities = { good: max(firm.productivity for firm in self.firms.values() if firm.product == good) for good in self.goods } blue_collars = sum(pop.population for pop in self.pops.values() if type(pop) is BlueCollar) white_collars = sum(pop.population for pop in self.pops.values() if type(pop) is WhiteCollar) initial_blue_collars = blue_collars initial_white_collars = white_collars blue_workers = GoodsVector(self.goods) white_workers = GoodsVector(self.goods) # Try to maximise the output (total production) # and also matching needs according prioritizing the lowest need levels for level in range(3): for good, needs in cum_needs[level].items(): productivity = productivities[good] # Get a rough estimate of the number of blue workers blue_w = min(int(needs / productivity), blue_collars) # Number of white workers that maximizes the productivity white_w = min(int(0.15 * 1.15 * blue_w), white_collars) # A better estimate of the blue workers, based on the adjusted productivity blue_w = min( int(needs / adjusted_productivity(productivity, blue_w, white_w)), blue_collars) # Try to set the white workers at the optimal level white_w = min(int(0.15 * 1.15 * blue_w), white_collars) blue_workers[good] += blue_w white_workers[good] += white_w blue_collars -= blue_w white_collars -= white_w # Ratio of white_workers w_b_ratio = { good: (white_workers[good] / (blue_workers[good] + white_workers[good])) for good in self.goods } # Total production production = GoodsVector(self.goods) for good in self.goods: production[good] = blue_workers[good] * adjusted_productivity( productivities[good], blue_workers[good], white_workers[good]) # Compute cumulated needs and ratio of production vs needs cum_needs_tot = cum_needs[0] + cum_needs[1] + cum_needs[2] cum_needs01 = cum_needs[0] + cum_needs[1] ratio_needs_prod = GoodsVector(self.goods) ratio_needs_prod_01 = GoodsVector(self.goods) for good in self.goods: ratio_needs_prod[good] = production[good] / cum_needs_tot[good] ratio_needs_prod_01[good] = production[good] / cum_needs01[good] def average_blue_needs(): average_needs = GoodsVector(self.goods) for pop in self.pops.values(): if type(pop) is BlueCollar: needs = pop.cumulated_needs({0, 1}) for good, qty in needs.items(): average_needs[good] += qty / initial_blue_collars return average_needs def average_white_needs(): average_needs = GoodsVector(self.goods) for pop in self.pops.values(): if type(pop) is WhiteCollar: needs = pop.cumulated_needs({0, 1}) for good, qty in needs.items(): average_needs[good] += qty / initial_white_collars return average_needs fixed_good = 'food' goods = list(self.goods) goods.sort() avg_blue_n = average_blue_needs() avg_white_n = average_white_needs() a = [[ blue_workers[good] * avg_blue_n[g] + white_workers[good] * avg_white_n[g] - (production[good] if g == good else 0) for g in goods if g != fixed_good ] for good in goods if good != fixed_good] b = [ -(blue_workers[g] * avg_blue_n[fixed_good] + white_workers[g] * avg_white_n[fixed_good]) for g in goods if g != fixed_good ] a = np.array(a) b = np.array(b) p = np.linalg.solve(a, b) ideal_prices = { 'food': 1, 'lodging': p[0], 'clothes': p[1], 'luxury': p[2] } def ideal_wages(prices): wages = {} for pop in self.pops.values(): needs = pop.cumulated_needs({0, 1}) wages[pop.id_pop] = sum([ price * qty / pop.population for good, qty in needs.items() for g, price in prices.items() if g == good ]) return wages ideal_w = ideal_wages(ideal_prices) return { 'white_workers': white_workers, 'blue_workers': blue_workers, 'initial_blue_collars': initial_blue_collars, 'initial_white_collars': initial_white_collars, 'residual_blue_collars': blue_collars, 'residual_white_collars': white_collars, 'white_blue_ratio': w_b_ratio, 'cumulated_needs_01': cum_needs01, 'cumulated_needs': cum_needs, 'cumulated_needs_tot': cum_needs_tot, 'production': production, 'ratio_needs_prod': ratio_needs_prod, 'ratio_needs_prod_01': ratio_needs_prod_01, 'ideal_prices': ideal_prices, 'ideal_wages': ideal_w }
def start_period(self): self.available_income = 0 self.consumption = GoodsVector(self.goods)