def __init__(self, agents, supply): self.agents = agents self.supply = supply self.approximator = LaviSwamyGreedyApproximator(supply, agents, ConsoleLogger()) m_range = range(0, len(self.agents) + 2) self.base = [] for i in m_range: row = [] for j in m_range: if i == j: row += [1.] else: row += [0.] self.base.append(row) self.z = [0. for i in m_range] + [0.] self.b = [1 / self.approximator.gap for i in range(0, len(self.agents))] + [supply / self.approximator.gap] + [1.] self.row_names = ['s%s' % i for i, row in enumerate(self.base) if i < len(self.base)-1] + ['l0'] self.cost = 0. self.allocations = dict() self.allocations[0] = Allocation()
class DwSolver: def __init__(self, agents, supply): self.agents = agents self.supply = supply self.approximator = LaviSwamyGreedyApproximator(supply, agents, ConsoleLogger()) m_range = range(0, len(self.agents) + 2) self.base = [] for i in m_range: row = [] for j in m_range: if i == j: row += [1.] else: row += [0.] self.base.append(row) self.z = [0. for i in m_range] + [0.] self.b = [1 / self.approximator.gap for i in range(0, len(self.agents))] + [supply / self.approximator.gap] + [1.] self.row_names = ['s%s' % i for i, row in enumerate(self.base) if i < len(self.base)-1] + ['l0'] self.cost = 0. self.allocations = dict() self.allocations[0] = Allocation() @property def utilities(self): return self.z_to_utilities(self.z) @property def price(self): return self.z_to_price(self.z) def z_to_price(self, z): return -z[len(self.agents)] def z_to_utilities(self, z): return dict(enumerate(z[0:len(self.agents)])) def iterate(self): print '' allocation = self.approximator.approximate(self.price, {k: -u for k,u in self.utilities.iteritems()}) new_base = self.base[:] new_b = self.b[:] new_z = self.z[:] # A*X_j constraints = [1. if any([assignment.agent_id == i for assignment in allocation.assignments]) else 0. for i in range(0, len(self.agents))] + [allocation.quantity_assigned] + [1.] # entering column y_k = [] for row in new_base: y_k += [sum([base_value * constraint_value for base_value, constraint_value in zip(row, constraints)])] self.print_tableau(y_k) # leaving variable row index # print 'Recommendation is row %s' % self.get_leaving_row_index(new_b, y_k) #r = None #while r == None: # input = int(raw_input('row index please: ')) # if True or y_k[input] > 0: # r = input r = self.get_leaving_row_index(new_b, y_k, new_base) # divide selected row by y_kr new_base = [base_row if index != r else [ base_value / y_k[r] for base_value in base_row] for index, base_row in enumerate(new_base)] new_b = [b_value if index != r else b_value / y_k[r] for index, b_value in enumerate(new_b)] # add -y_kr * pivot_row to each row (except pivot row) new_base = [base_row if index == r else [base_cell + (new_cell * -y_k[index]) for base_cell, new_cell in zip(base_row, new_base[r])] for index, base_row in enumerate(new_base)] new_b = [b_value if index == r else b_value + (new_b[r] * -y_k[index]) for index, b_value in enumerate(new_b)] # add (z-c) * new_row + row_z # z - c = sum(valuations) - quantity * price - utility * x_ij social_welfare = sum([assignment.valuation for assignment in allocation.assignments]) \ - allocation.quantity_assigned * self.price \ + sum([self.utilities[agent.id] if any([assignment.agent_id == agent.id for assignment in allocation.assignments]) else 0 for agent in self.agents]) #social_welfare = 1 if new_z[len(new_z)-2] == 0. else 0 new_z = [z_value - (social_welfare * pivot_row_value) for z_value, pivot_row_value in zip(new_z, new_base[r] + [new_b[r]])] print 'z - c = %s' % social_welfare self.allocations[len(self.allocations)] = allocation self.row_names[r] = 'l%s' % (len(self.allocations)-1) self.base = new_base self.b = new_b self.z = new_z self.print_tableau() if social_welfare > 0: return True else: return False def get_leaving_row_index(self, b, y_k, base): # return int(raw_input('leaving var row index: ')) ratios = {index: b_value/y_value for index, (b_value, y_value) in enumerate(zip(b, y_k)) if y_value > 0} row_index = min(ratios.iteritems(), key=lambda r: r[1])[0] print '' print 'Pivoting at row %s' % row_index print '' return row_index def print_tableau(self, y_k = None): print 'z \t | \t', for i, z in enumerate(self.z): if i == len(self.z)-2: print '%s \t | \t' % z, else: print '%s \t' % z, print '' print '-----------------------------------------------------------' for index, row in enumerate(self.base): print '%s \t | \t' % self.row_names[index], for b in row: print '%s \t' % b, print '| \t %s' % self.b[index], if y_k: print '\t | \t %s' % y_k[index] else: print ''