Esempio n. 1
0
def test_add_column(solver: str):
    """Simple test which add columns in a specific way"""
    m = Model()
    x = m.add_var()

    example_constr1 = m.add_constr(x >= 1, "constr1")
    example_constr2 = m.add_constr(x <= 2, "constr2")
    column1 = Column()
    column1.constrs = [example_constr1]
    column1.coeffs = [1]
    second_var = m.add_var("second", column=column1)
    column2 = Column()
    column2.constrs = [example_constr2]
    column2.coeffs = [2]
    m.add_var("third", column=column2)

    vthird = m.vars["third"]
    assert vthird is not None
    assert len(vthird.column.coeffs) == len(vthird.column.constrs)
    assert len(vthird.column.coeffs) == 1

    pconstr2 = m.constrs["constr2"]
    assert vthird.column.constrs[0].name == pconstr2.name
    assert len(example_constr1.expr.expr) == 2
    assert second_var in example_constr1.expr.expr
    assert x in example_constr1.expr.expr
Esempio n. 2
0
    def var_get_column(self, var: Var) -> Column:
        self.update()

        nnz = ffi.new('int*')

        # obtaining number of non-zeros
        error = GRBgetvars(self._model, nnz, ffi.NULL, ffi.NULL, ffi.NULL,
                           var.idx, 1)
        if error != 0:
            raise Exception('Error querying gurobi model information')

        nz = nnz[0]

        # creating arrays to hold indices and coefficients
        cbeg = ffi.new('int[2]')
        cind = ffi.new('int[{}]'.format(nz))
        cval = ffi.new('double[{}]'.format(nz))

        # obtaining variables and coefficients
        error = GRBgetvars(self._model, nnz, cbeg, cind, cval, var.idx, 1)
        if error != 0:
            raise Exception('Error querying gurobi model information')

        constr = [self.model.constrs[cind[i]] for i in range(nz)]
        coefs = [float(cval[i]) for i in range(nz)]

        return Column(constr, coefs)
Esempio n. 3
0
def test_column_generation(solver: str):
    L = 250  # bar length
    m = 4  # number of requests
    w = [187, 119, 74, 90]  # size of each item
    b = [1, 2, 2, 1]  # demand for each item

    # creating master model
    master = Model(solver_name=solver)

    # creating an initial set of patterns which cut one item per bar
    # to provide the restricted master problem with a feasible solution
    lambdas = [
        master.add_var(obj=1, name="lambda_%d" % (j + 1)) for j in range(m)
    ]

    # creating constraints
    constraints = []
    for i in range(m):
        constraints.append(
            master.add_constr(lambdas[i] >= b[i], name="i_%d" % (i + 1)))

    # creating the pricing problem
    pricing = Model(solver_name=solver)

    # creating pricing variables
    a = [
        pricing.add_var(obj=0, var_type=INTEGER, name="a_%d" % (i + 1))
        for i in range(m)
    ]

    # creating pricing constraint
    pricing += xsum(w[i] * a[i] for i in range(m)) <= L, "bar_length"

    new_vars = True
    while new_vars:
        ##########
        # STEP 1: solving restricted master problem
        ##########
        master.optimize()

        ##########
        # STEP 2: updating pricing objective with dual values from master
        ##########
        pricing += 1 - xsum(constraints[i].pi * a[i] for i in range(m))

        # solving pricing problem
        pricing.optimize()

        ##########
        # STEP 3: adding the new columns (if any is obtained with negative reduced cost)
        ##########
        # checking if columns with negative reduced cost were produced and
        # adding them into the restricted master problem
        if pricing.objective_value < -TOL:
            pattern = [a[i].x for i in range(m)]
            column = Column(constraints, pattern)
            lambdas.append(
                master.add_var(obj=1,
                               column=column,
                               name="lambda_%d" % (len(lambdas) + 1)))

        # if no column with negative reduced cost was produced, then linear
        # relaxation of the restricted master problem is solved
        else:
            new_vars = False

    # printing the solution
    assert len(lambdas) == 8
    assert round(master.objective_value) == 3
Esempio n. 4
0
    z_val = pricing.objective_value
    print('Pricing solution:')
    print('    z =  {z_val}'.format(**locals()))
    print('    a = ', end='')
    print([v.x for v in pricing.vars])
    print('')

    ##########
    # STEP 3: adding the new columns (if any is obtained with negative reduced cost)
    ##########

    # checking if columns with negative reduced cost were produced and
    # adding them into the restricted master problem
    if pricing.objective_value < -1e-5:
        pattern = [a[i].x for i in range(m)]
        column = Column(constraints, pattern)
        lambdas.append(
            master.add_var(obj=1,
                           column=column,
                           name='lambda_%d' % (len(lambdas) + 1)))

        print('new pattern = {pattern}'.format(**locals()))

    # if no column with negative reduced cost was produced, then linear
    # relaxation of the restricted master problem is solved
    else:
        new_vars = False

    pricing.write('pricing.lp')

# printing the solution