from otree.api import ( models, widgets, BaseConstants, BaseSubsession, BaseGroup, BasePlayer, Currency as c, currency_range ) import random doc = """ Здесь воспроизводим модель аукциона функций предложения. """ class Constants(BaseConstants): name_in_url = 'parks_auction' players_per_group = 9 num_rounds = 10 instructions_template = 'parks_auction/Instructions.html' # Всего распределяем максимум 1000 мест total_capacity = 1000 marginal_price = 2 #D(p) = 500-2*p; marginal_cost = 6400 class Subsession(BaseSubsession): def creating_session(self): playrs = self.get_players() for p in playrs: if self.round_number == 1: for p in playrs: p.marginal_cost = 10 * random.randint(1, 20) p.maximal_capacity = random.randint(1, 300) p.participant.vars['marginal_cost'] = p.marginal_cost p.participant.vars['maximal_capacity'] = p.maximal_capacity p.indiv_demand_coeff = random.randint(15, 35) p.indiv_demand_intercept = random.randint(20000, 25000) p.generate_rnd_demand() p.participant.vars['indiv_demand_coeff'] = p.indiv_demand_coeff p.participant.vars['indiv_demand_intercept'] = p.indiv_demand_intercept else: print('Раунд номер ') print(self.round_number) for p in playrs: p.indiv_demand_coeff = p.participant.vars.get('indiv_demand_coeff') p.indiv_demand_intercept = p.participant.vars.get('indiv_demand_intercept') class Group(BaseGroup): price = models.CurrencyField( doc="""Единая цена, которая установится на рынке""" ) total_units = models.PositiveIntegerField( doc="""Общий объем заявок всех участников вашего рынка""" ) active_players = models.IntegerField() volume_cap = models.IntegerField() def set_payoffs(self): #self.session.vars['r_lower'] = [0] #self.session.vars['r_higher'] = [0] #self.price = (Constants.total_capacity - self.total_units )/Constants.marginal_price #if self.price < 0: # self.price = 0 i = 0 jumps = [] capacities = [] r_plus = [] r_minus = [] added_supply = 0 sum_units = 0 self.volume_cap = 100 + 100*self.active_players for p in self.get_players(): if p.bids_quant >= 1: jumps.append(p.first_bid_price) capacities.append(p.first_bid_vol) if p.bids_quant >= 2: jumps.append(p.second_bid_price) capacities.append(p.second_bid_vol) if p.bids_quant >= 3: jumps.append(p.third_bid_price) capacities.append(p.third_bid_vol) print(jumps) print(capacities) print(len(jumps)) print(capacities[len(jumps)-1]) self.total_units = sum(capacities) print(len(jumps) - 1) print(self.total_units) for i in range(len(jumps) - 1): for j in range(len(jumps) - i - 1): if jumps[j] > jumps[j + 1]: jumps[j], jumps[j + 1] = jumps[j + 1], jumps[j] capacities[j], capacities[j + 1] = capacities[j + 1], capacities[j] print(jumps) print(capacities) print(len(jumps)) print(len(capacities)) print(capacities[len(jumps)-1]) r_plus.append(self.total_units) for i in range(len(jumps)-1): print(i) print(r_plus[i]) r_minus.append(r_plus[i]-capacities[i]) r_plus.append(r_minus[i]) r_minus.append(0) print(r_plus) print(r_minus) print(jumps) self.session.vars['jumps'] = jumps self.session.vars['r_plus'] = r_plus self.session.vars['r_minus'] = r_minus self.session.vars['capacities'] = capacities i = 0 while (r_plus[i] < self.volume_cap) or (r_minus[i] > self.volume_cap): i = i + 1 print('ЦЕНА ОТСЕЧЕНИЯ') print(jumps[i]) self.price = jumps[i] for p in self.get_players(): p.count_quota() sum_units = sum_units + p.units added_supply = self.volume_cap - sum_units for p in self.get_players(): p.share = p.units/sum_units p.units = p.units + int(added_supply*p.share) class Player(BasePlayer): units = models.PositiveIntegerField() reserve_price = models.PositiveIntegerField() marginal_cost = models.PositiveIntegerField() maximal_capacity = models.PositiveIntegerField() chosen_capacity = models.PositiveIntegerField() share = models.FloatField() user_price = models.IntegerField(initial=0, label="Цена путевки для конечного потребителя") indiv_demand_coeff = models.IntegerField() indiv_demand_intercept = models.IntegerField() is_active = models.BooleanField() bids_quant = models.IntegerField( choices=[ [1, 'Одна'], [2, 'Две'], [3, 'Три'] ], widget=widgets.RadioSelectHorizontal, label="Количество подаваемых Вами заявок (фактически, это количество ступеней в Вашей функции спроса):" ) first_bid_price = models.IntegerField(initial=0, label="Цена путевки в первой заявке") first_bid_vol = models.IntegerField(initial=0, label="Количество путевок в первой заявке") second_bid_price = models.IntegerField(initial=-1, label="Цена путевки во второй заявке") second_bid_vol = models.IntegerField(initial=-1, label="Количество путевок во второй заявке") third_bid_price = models.IntegerField(initial=-1, label="Цена путевки в третьей заявке") third_bid_vol = models.IntegerField(initial=-1, label="Количество путевок в первой заявке") def other_players(self): return self.get_others_in_group() def generate_rnd_demand(self): self.participant.vars['rnd_demand_p'] = [] self.participant.vars['rnd_demand_q'] = [] for i in range(10): self.participant.vars['rnd_demand_q'].append(random.randint(0,int(self.indiv_demand_intercept/self.indiv_demand_coeff))) self.participant.vars['rnd_demand_p'].append(max(0, self.indiv_demand_intercept-self.indiv_demand_coeff*self.participant.vars['rnd_demand_q'][i]+ random.randint(-2500,2500))) print(self.participant.vars['rnd_demand_q'][i]) print(self.participant.vars['rnd_demand_p'][i]) def count_quota(self): self.units = 0 if self.bids_quant >= 3: if self.third_bid_price > self.group.price: self.units = self.units + self.third_bid_vol if self.bids_quant >= 2: if self.second_bid_price > self.group.price: self.units = self.units + self.second_bid_vol if self.bids_quant >= 1: if self.first_bid_price > self.group.price: self.units = self.units + self.first_bid_vol