def solve_restricted_primal(self, demands, demands_next, p):
        self.obj = 0.
        m = Model("multi-unit-auction")
        # self.m.params.LogToConsole = 0
        self.allocation_vars = dict()
        for agent in self.agents:
            for i in range(1, self.supply + 1):
                self.allocation_vars[agent.id, i] = m.addVar(lb=0., ub=1., vtype=GRB.CONTINUOUS,
                                                                  name='x_%s_%s' % (agent.id, i))
        m.update()
        for agent in self.agents:
            if len(demands[agent.id]) > 0 and len(demands_next[agent.id]) > 0:
                m.addConstr(quicksum(self.allocation_vars[agent.id, i] for i in range(1, self.supply + 1)),
                                 GRB.EQUAL, 1, name="u_%s_strict" % agent.id)
            else:
                m.addConstr(quicksum(self.allocation_vars[agent.id, i] for i in range(1, self.supply + 1)),
                                 GRB.LESS_EQUAL, 1, name="u_%s" % agent.id)
            for j in range(1, self.supply + 1):
                if j not in [demand.quantity for demand in demands[agent.id]]:
                    m.addConstr(self.allocation_vars[agent.id, j], GRB.EQUAL, 0, name='x_%s_%s_undemanded' % (agent.id, j))

        if p > 0:
            m.addConstr(
                quicksum(self.allocation_vars[agent.id, i] * i for i in range(1, self.supply + 1) for agent in self.agents),
                GRB.EQUAL, self.supply, name="price_strict")
        else:
            m.addConstr(
                quicksum(self.allocation_vars[agent.id, i] * i for i in range(1, self.supply + 1) for agent in self.agents),
                GRB.LESS_EQUAL, self.supply, name="price")
        obj_expr = LinExpr()
        for agent in self.agents:
            for valuation in agent.valuations:
                obj_expr.addTerms(valuation.quantity, self.allocation_vars[agent.id, valuation.quantity])
        m.setObjective(obj_expr, GRB.MAXIMIZE)
        m.update()
        m.optimize()

        m.write('optimal-lp.lp')

        if m.status == GRB.OPTIMAL:
            m.write('optimal-lp.sol')
            for v in [v for v in m.getVars() if v.x != 0.]:
                print('%s %g' % (v.varName, v.x))

            print ''
            print 'CONSTRAINTS:'

            for l in m.getConstrs():
                if l.Pi > 0:
                    print('%s %g' % (l.constrName, l.Pi))

            print m.getObjective().getValue()

        return m
m.addConstr(x11 + x12 + x13 + x14 + x21 + x22 + x23 + x24, GRB.LESS_EQUAL, 2, name="all")
m.addConstr(x12, GRB.LESS_EQUAL, x11, name="c11")
m.addConstr(x13, GRB.LESS_EQUAL, x12, name="c12")
m.addConstr(x14, GRB.LESS_EQUAL, x13, name="c13")
m.addConstr(x22, GRB.LESS_EQUAL, x21, name="c21")
m.addConstr(x23, GRB.LESS_EQUAL, x22, name="c22")
m.addConstr(x24, GRB.LESS_EQUAL, x23, name="c23")
m.addConstr(x14, GRB.GREATER_EQUAL, 0, name="11")
m.addConstr(x24, GRB.GREATER_EQUAL, 0, name="12")
m.addConstr(x11, GRB.LESS_EQUAL, .5, name="u1")
m.addConstr(x21, GRB.LESS_EQUAL, .5, name="u2")
#m.addConstr(x11 + 2*x12 + 3*x13 + 4*x14 + x21 + 2*x22 + 3*x23 + 4*x24, GRB.LESS_EQUAL, 4, name="p_an")

m.setObjective(x11 * 6 + x12 * 0 + x13 * 0 + x14 * 3 + x21 * 1 + x22 * 3 + x23 * 0 + x24 * 2, GRB.MAXIMIZE)



m.optimize()

for v in [v for v in m.getVars() if v.x != 0.]:
    print('%s %g' % (v.varName, v.x))

print 'CONSTRS'

for l in m.getConstrs():
    if l.Pi > 0:
        print('%s %g' % (l.constrName, l.Pi))

print m.getObjective().getValue()
class OptimalSolver:
    def __init__(self, supply, agents, gap, restriced=False):
        print ''
        print 'Optimal Solver:'

        self.m = Model("multi-unit-auction")
        self.m.params.LogToConsole = 0
        self.allocation_vars = dict()
        for agent in agents:
            for i in range(1, supply + 1):
                self.allocation_vars[agent.id, i] = self.m.addVar(lb=0., ub=1., vtype=GRB.CONTINUOUS, name='x_%s_%s' % (agent.id, i))

        self.m.update()

        for agent in agents:
            self.m.addConstr(quicksum(self.allocation_vars[agent.id, i] for i in range(1, supply + 1)), GRB.LESS_EQUAL, 1, name="u_%s" % agent.id)
            if restriced:
                for valuation in agent.valuations:
                    if valuation.valuation > 0:
                        self.m.addConstr(self.allocation_vars[agent.id, valuation.quantity] >= epsilon, name="not_zero_%s_%s" % (agent.id, valuation.quantity))


        self.m.addConstr(quicksum(self.allocation_vars[agent.id, i]*i for i in range(1, supply + 1) for agent in agents), GRB.LESS_EQUAL, supply, name="price")

        obj_expr = LinExpr()
        for agent in agents:
            for valuation in agent.valuations:
                obj_expr.addTerms(valuation.valuation, self.allocation_vars[agent.id, valuation.quantity])
        self.m.setObjective(obj_expr, GRB.MAXIMIZE)

        self.m.update()

        self.m.optimize()
        #
        # for agent in agents:
        #     for i in range(1, supply + 1):
        #         self.allocation_vars[agent.id, i] = self.m.addVar(vtype=GRB.CONTINUOUS, lb=0,
        #                                                           name='x_%s_%s' % (agent.id, i))
        #
        # self.m.update()
        #
        # self.m.addConstr(quicksum(self.allocation_vars[agent.id, i] for i in range(1, supply + 1) for agent in agents),
        #                  GRB.LESS_EQUAL, supply / gap, name="price")
        # for agent in agents:
        #     for i in range(1, supply):
        #         self.m.addConstr(self.allocation_vars[agent.id, i + 1] - self.allocation_vars[agent.id, i],
        #                          GRB.LESS_EQUAL, 0, name="chain_%s_%s" % (agent.id, i))
        #         self.m.addConstr(self.allocation_vars[agent.id, i], GRB.LESS_EQUAL, 1. / gap,
        #                          name="p_%s_%s" % (agent.id, i))
        #     self.m.addConstr(self.allocation_vars[agent.id, supply], GRB.GREATER_EQUAL, 0, name="greater_%s" % agent.id)
        #     self.m.addConstr(self.allocation_vars[agent.id, 1], GRB.LESS_EQUAL, 1. / gap, name="u_%s" % agent.id)
        #
        # # m.addConstr(x11 + 2*x12 + 3*x13 + 4*x14 + x21 + 2*x22 + 3*x23 + 4*x24, GRB.LESS_EQUAL, 4, name="p_an")
        #
        # obj_expr = LinExpr()
        # for agent in agents:
        #     prev_val = None
        #     for valuation in agent.valuations:
        #         try:
        #             prev_val = next(val for val in agent.valuations if val.quantity == valuation.quantity - 1)
        #         except StopIteration:
        #             pass
        #         marginal_value = valuation.valuation - (prev_val.valuation if prev_val else 0)
        #         obj_expr.addTerms(marginal_value, self.allocation_vars[agent.id, valuation.quantity])
        # self.m.setObjective(obj_expr, GRB.MAXIMIZE)
        #
        # self.m.optimize()

        for v in [v for v in self.m.getVars() if v.x != 0.]:
            print('%s %g' % (v.varName, v.x))

        print ''
        print 'CONSTRAINTS:'

        for l in self.m.getConstrs():
            if l.Pi > 0:
                print('%s %g' % (l.constrName, l.Pi))

        print self.m.getObjective().getValue()

        # print 'Optimal solution:'
        # for v in self.m.getVars():
        #     print('%s %g' % (v.varName, v.x))
        # for l in self.m.getConstrs():
        #     if l.Pi > 0:
        #         print('%s %g' % (l.constrName, l.Pi))
        print 'OPT social welfare %s | %s/%s=%s' % (
        self.m.getObjective().getValue(), self.m.getObjective().getValue(), gap,
        self.m.getObjective().getValue() / gap)

        self.m.write('optimal-lp.lp')
        self.m.write('optimal-lp.sol')