Exemplo n.º 1
0
    def constructProblem(self):
        self.instance.print()
        self.model = Model('flow')
        self.fIdx = [[
            self.model.add_var('f({},{})'.format(i + 1, t), var_type='B')
            for i in range(self.instance.m())
        ] for t in range(self.instance.h())]
        self.xIdx = [[[
            self.model.add_var('x({},{},{})'.format(i + 1, j + 1, t))
            for t in range(self.instance.est(i, j),
                           self.instance.lst(i, j) + 1)
        ] for i in range(self.instance.m())] for j in range(self.instance.n())]
        self.eIdx = [[[
            self.model.add_var('e({},{},{})'.format(i + 1, j + 1, t))
            for t in range(self.instance.est(i, j),
                           self.instance.lst(i, j) + 1)
        ] for i in range(self.instance.m())] for j in range(self.instance.n())]
        self.cIdx = self.model.add_var('C', var_type='I')

        for aux in self.fIdx:
            for f in aux:
                print(f.name, " ", end='')
            print()
        for aux in self.xIdx:
            for aux2 in aux:
                for x in aux2:
                    print(x.name, " ", end='')
                print()
        for aux in self.xIdx:
            for aux2 in aux:
                for e in aux2:
                    print(e.name, " ", end='')
                print()
Exemplo n.º 2
0
    def generate_cuts(self, model: Model):
        G = nx.DiGraph()
        r = [(v, v.x) for v in model.vars if v.name.startswith('x(')]
        U = [int(v.name.split('(')[1].split(',')[0]) for v, f in r]
        V = [int(v.name.split(')')[0].split(',')[1]) for v, f in r]

        for v in model.vars:
            print('{} = {} '.format(v.name, v.x), end='')
        print()
        input()
        cp = CutPool()
        for i in range(len(U)):
            G.add_edge(U[i], V[i], capacity=r[i][1])
        for (u, v) in F:
            if u not in U or v not in V:
                continue
            val, (S, NS) = nx.minimum_cut(G, u, v)
            if val <= 0.99:
                arcsInS = [(v, f) for i, (v, f) in enumerate(r)
                           if U[i] in S and V[i] in S]
                if sum(f for v, f in arcsInS) >= (len(S) - 1) + 1e-4:
                    cut = xsum(1.0 * v for v, fm in arcsInS) <= len(S) - 1
                    cp.add(cut)
                    if len(cp.cuts) > 256:
                        for cut in cp.cuts:
                            model.add_cut(cut)
                        return
        for cut in cp.cuts:
            model.add_cut(cut)
        return
Exemplo n.º 3
0
 def generate_constrs(self, model: Model):
     G = nx.DiGraph()
     r = [(v, v.x) for v in model.vars if v.name.startswith('x(')]
     U = [v.name.split('(')[1].split(',')[0] for v, f in r]
     V = [v.name.split(')')[0].split(',')[1] for v, f in r]
     N = list(set(U + V))
     cp = CutPool()
     for i in range(len(U)):
         G.add_edge(U[i], V[i], capacity=r[i][1])
     for (u, v) in product(N, N):
         if u == v:
             continue
         val, (S, NS) = nx.minimum_cut(G, u, v)
         if val <= 0.99:
             arcsInS = [(v, f) for i, (v, f) in enumerate(r)
                        if U[i] in S and V[i] in S]
             if sum(f for v, f in arcsInS) >= (len(S) - 1) + 1e-4:
                 cut = xsum(1.0 * v for v, fm in arcsInS) <= len(S) - 1
                 cp.add(cut)
                 if len(cp.cuts) > 256:
                     for cut in cp.cuts:
                         model.add_cut(cut)
                     return
     for cut in cp.cuts:
         model.add_cut(cut)
     return
Exemplo n.º 4
0
    def __init__(self, generators, demand):

        self.generators = generators
        self.demand = demand

        self.period = range(1, len(self.demand) + 1)

        self.model = Model(name='UnitCommitment')
        self.p, self.u = {}, {}
Exemplo n.º 5
0
def solve_tsp_by_mip(tsp_matrix):
    start = time()
    matrix_of_distances = get_matrix_of_distances(tsp_matrix)
    length = len(tsp_matrix)

    model = Model(solver_name='gurobi')
    model.verbose = 1

    x = [[model.add_var(var_type=BINARY) for j in range(length)]
         for i in range(length)]

    y = [model.add_var() for i in range(length)]

    model.objective = xsum(matrix_of_distances[i][j] * x[i][j]
                           for j in range(length) for i in range(length))

    for i in range(length):
        model += xsum(x[j][i] for j in range(length) if j != i) == 1
        model += xsum(x[i][j] for j in range(length) if j != i) == 1

    for i in range(1, length):
        for j in [x for x in range(1, length) if x != i]:
            model += y[i] - (length + 1) * x[i][j] >= y[j] - length

    model.optimize(max_seconds=300)

    arcs = [(i, j) for i in range(length) for j in range(length)
            if x[i][j].x >= 0.99]

    best_distance = calculate_total_dist_by_arcs(matrix_of_distances, arcs)
    time_diff = time() - start
    return arcs, time_diff, best_distance
Exemplo n.º 6
0
    def generate_cuts(self, model: Model):
        def row(vname: str) -> str:
            return int(vname.split('(')[1].split(',')[0].split(')')[0])

        def col(vname: str) -> str:
            return int(vname.split('(')[1].split(',')[1].split(')')[0])

        x = {(row(v.name), col(v.name)): v for v in model.vars}
        for p, k in enumerate(range(2 - n, n - 2 + 1)):
            cut = xsum(x[i, j] for i in range(n)
                       for j in range(n) if i - j == k) <= 1
            if cut.violation > 0.001:
                model.add_cut(cut)

        for p, k in enumerate(range(3, n + n)):
            cut = xsum(x[i, j] for i in range(n)
                       for j in range(n) if i + j == k) <= 1
            if cut.violation > 0.001:
                model.add_cut(cut)
Exemplo n.º 7
0
def solve_tsp_by_mip_with_sub_cycles_2(tsp_matrix):
    start = time()
    matrix_of_distances = get_matrix_of_distances(tsp_matrix)
    total_length = len(tsp_matrix)
    best_distance = sys.float_info.max

    found_cycles = []
    arcs = [(i, i + 1) for i in range(total_length - 1)]

    iteration = 0

    model = Model(solver_name='gurobi')
    model.verbose = 0

    x = [[model.add_var(var_type=BINARY) for j in range(total_length)]
         for i in range(total_length)]

    y = [model.add_var() for i in range(total_length)]

    model.objective = xsum(matrix_of_distances[i][j] * x[i][j]
                           for j in range(total_length)
                           for i in range(total_length))

    for i in range(total_length):
        model += (xsum(x[i][j] for j in range(0, i)) +
                  xsum(x[j][i] for j in range(i + 1, total_length))) == 2

    while len(found_cycles) != 1:
        model.optimize(max_seconds=300)

        arcs = [(i, j) for i in range(total_length)
                for j in range(total_length) if x[i][j].x >= 0.99]
        best_distance = calculate_total_dist_by_arcs(matrix_of_distances, arcs)

        found_cycles = get_cycle(arcs)

        for cycle in found_cycles:
            points = {}
            for arc in cycle:
                points = {*points, arc[0]}
                points = {*points, arc[1]}
            cycle_len = len(cycle)
            model += xsum(x[arc[0]][arc[1]]
                          for arc in permutations(points, 2)) <= cycle_len - 1

        # plot_connected_tsp_points_from_arcs(tsp_matrix, arcs, '../images/mip_xql662/{}'.format(iteration))
        print(iteration)
        iteration += 1

    time_diff = time() - start
    return arcs, time_diff, best_distance
Exemplo n.º 8
0
def get_pricing(m, w, L):
    # creating the pricing problem
    pricing = Model()

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

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

    pricing.write('pricing.lp')

    return a, pricing
Exemplo n.º 9
0
def test_queens(solver: str):
    """MIP model n-queens"""
    n = 50
    announce_test("n-Queens", solver)

    queens = Model('queens', MAXIMIZE, solver_name=solver)
    queens.verbose = 0

    x = [[
        queens.add_var('x({},{})'.format(i, j), var_type=BINARY)
        for j in range(n)
    ] for i in range(n)]

    # one per row
    for i in range(n):
        queens += xsum(x[i][j] for j in range(n)) == 1, 'row({})'.format(i)

    # one per column
    for j in range(n):
        queens += xsum(x[i][j] for i in range(n)) == 1, 'col({})'.format(j)

    # diagonal \
    for p, k in enumerate(range(2 - n, n - 2 + 1)):
        queens += xsum(x[i][j] for i in range(n) for j in range(n)
                       if i - j == k) <= 1, 'diag1({})'.format(p)

    # diagonal /
    for p, k in enumerate(range(3, n + n)):
        queens += xsum(x[i][j] for i in range(n) for j in range(n)
                       if i + j == k) <= 1, 'diag2({})'.format(p)

    queens.optimize()

    check_result("model status", queens.status == OptimizationStatus.OPTIMAL)

    # querying problem variables and checking opt results
    total_queens = 0
    for v in queens.vars:
        # basic integrality test
        assert v.x <= 0.0001 or v.x >= 0.9999
        total_queens += v.x

    # solution feasibility
    rows_with_queens = 0
    for i in range(n):
        if abs(sum(x[i][j].x for j in range(n)) - 1) <= 0.001:
            rows_with_queens += 1

    check_result("feasible solution",
                 abs(total_queens - n) <= 0.001 and rows_with_queens == n)
    print('')
Exemplo n.º 10
0
"""Job Shop Scheduling Problem Python-MIP exaxmple
   To execute it on the example instance ft03.jssp call
   python jssp.py ft03.jssp
   by Victor Silva"""

from itertools import product
from sys import argv
from jssp_instance import JSSPInstance
from mip.model import Model
from mip.constants import BINARY

inst = JSSPInstance(argv[1])
n, m, machines, times, M = inst.n, inst.m, inst.machines, inst.times, inst.M

model = Model('JSSP')

c = model.add_var(name="C")
x = [[model.add_var(name='x({},{})'.format(j + 1, i + 1)) for i in range(m)]
     for j in range(n)]
y = [[[
    model.add_var(var_type=BINARY,
                  name='y({},{},{})'.format(j + 1, k + 1, i + 1))
    for i in range(m)
] for k in range(n)] for j in range(n)]

model.objective = c

for (j, i) in product(range(n), range(1, m)):
    model += x[j][machines[j][i]] - x[j][machines[j][i-1]] >= \
        times[j][machines[j][i-1]]
Exemplo n.º 11
0
                if sum(f for v, f in arcsInS) >= (len(S) - 1) + 1e-4:
                    cut = xsum(1.0 * v for v, fm in arcsInS) <= len(S) - 1
                    cp.add(cut)
                    if len(cp.cuts) > 256:
                        for cut in cp.cuts:
                            model.add_cut(cut)
                        return
        for cut in cp.cuts:
            model.add_cut(cut)
        return


inst = TSPData(argv[1])
n, d = inst.n, inst.d

model = Model()

x = [[
    model.add_var(name='x({},{})'.format(i, j), var_type=BINARY)
    for j in range(n)
] for i in range(n)]
y = [model.add_var(name='y({})'.format(i), lb=0.0, ub=n) for i in range(n)]

model.objective = xsum(d[i][j] * x[i][j] for j in range(n) for i in range(n))

for i in range(n):
    model += xsum(x[j][i] for j in range(n) if j != i) == 1
    model += xsum(x[i][j] for j in range(n) if j != i) == 1
for (i, j) in [(i, j) for (i, j) in product(range(1, n), range(1, n))
               if i != j]:
    model += y[i] - (n + 1) * x[i][j] >= y[j] - n
Exemplo n.º 12
0
def test_tsp_mipstart(solver: str):
    """tsp related tests"""
    announce_test("TSP - MIPStart", solver)
    N = ['a', 'b', 'c', 'd', 'e', 'f', 'g']
    n = len(N)
    i0 = N[0]

    A = {
        ('a', 'd'): 56,
        ('d', 'a'): 67,
        ('a', 'b'): 49,
        ('b', 'a'): 50,
        ('d', 'b'): 39,
        ('b', 'd'): 37,
        ('c', 'f'): 35,
        ('f', 'c'): 35,
        ('g', 'b'): 35,
        ('b', 'g'): 25,
        ('a', 'c'): 80,
        ('c', 'a'): 99,
        ('e', 'f'): 20,
        ('f', 'e'): 20,
        ('g', 'e'): 38,
        ('e', 'g'): 49,
        ('g', 'f'): 37,
        ('f', 'g'): 32,
        ('b', 'e'): 21,
        ('e', 'b'): 30,
        ('a', 'g'): 47,
        ('g', 'a'): 68,
        ('d', 'c'): 37,
        ('c', 'd'): 52,
        ('d', 'e'): 15,
        ('e', 'd'): 20
    }

    # input and output arcs per node
    Aout = {n: [a for a in A if a[0] == n] for n in N}
    Ain = {n: [a for a in A if a[1] == n] for n in N}
    m = Model(solver_name=solver)
    m.verbose = 0

    x = {
        a: m.add_var(name='x({},{})'.format(a[0], a[1]), var_type=BINARY)
        for a in A
    }

    m.objective = xsum(c * x[a] for a, c in A.items())

    for i in N:
        m += xsum(x[a] for a in Aout[i]) == 1, 'out({})'.format(i)
        m += xsum(x[a] for a in Ain[i]) == 1, 'in({})'.format(i)

    # continuous variable to prevent subtours: each
    # city will have a different "identifier" in the planned route
    y = {i: m.add_var(name='y({})'.format(i), lb=0.0) for i in N}

    # subtour elimination
    for (i, j) in A:
        if i0 not in [i, j]:
            m.add_constr(y[i] - (n + 1) * x[(i, j)] >= y[j] - n)

    route = ['a', 'g', 'f', 'c', 'd', 'e', 'b', 'a']
    m.start = [(x[route[i - 1], route[i]], 1.0) for i in range(1, len(route))]
    m.optimize()

    check_result("mip model status", m.status == OptimizationStatus.OPTIMAL)
    check_result("mip model objective",
                 (abs(m.objective_value - 262)) <= 0.0001)
    print('')
Exemplo n.º 13
0
   to solve P1 instance (included in the examples) call python bmcp.py P1.col
"""

from itertools import product
import bmcp_data
import bmcp_greedy
from mip.model import Model, xsum, minimize
from mip.constants import MINIMIZE, BINARY

data = bmcp_data.read('P1.col')
N, r, d = data.N, data.r, data.d
S = bmcp_greedy.build(data)
C, U = S.C, [i for i in range(S.u_max + 1)]

m = Model(sense=MINIMIZE)

x = [[m.add_var('x({},{})'.format(i, c), var_type=BINARY) for c in U]
     for i in N]

z = m.add_var('z')
m.objective = minimize(z)

for i in N:
    m += xsum(x[i][c] for c in U) == r[i]

for i, j, c1, c2 in product(N, N, U, U):
    if i != j and c1 <= c2 < c1 + d[i][j]:
        m += x[i][c1] + x[j][c2] <= 1

for i, c1, c2 in product(N, U, U):
Exemplo n.º 14
0
from tspdata import TSPData
from sys import argv
from mip.model import Model
from mip.constants import *
from matplotlib.pyplot import plot

if len(argv) <= 1:
    print('enter instance name.')
    exit(1)

inst = TSPData(argv[1])
n = inst.n
d = inst.d
print('solving TSP with {} cities'.format(inst.n))

model = Model()

# binary variables indicating if arc (i,j) is used on the route or not
x = [[model.add_var(type=BINARY) for j in range(n)] for i in range(n)]

# continuous variable to prevent subtours: each
# city will have a different "identifier" in the planned route
y = [model.add_var(name='y({})'.format(i), lb=0.0, ub=n) for i in range(n)]

# objective funtion: minimize the distance
model += sum(d[i][j] * x[i][j] for j in range(n) for i in range(n))

# constraint : enter each city coming from another city
for i in range(n):
    model += sum(x[j][i] for j in range(n)
                 if j != i) == 1, 'enter({})'.format(i)
Exemplo n.º 15
0
def cg():
    """
    Simple column generation implementation for a Cutting Stock Problem
    """

    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 models and auxiliary lists
    master = Model()
    lambdas = []
    constraints = []

    # creating an initial pattern (which cut one item per bar)
    # to provide the restricted master problem with a feasible solution
    for i in range(m):
        lambdas.append(master.add_var(obj=1, name='lambda_%d' %
                                      (len(lambdas) + 1)))

    # creating 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)

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

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

    pricing.write('pricing.lp')

    new_vars = True
    while new_vars:

        ##########
        # STEP 1: solving restricted master problem
        ##########

        master.optimize()

        # printing dual values
        print_solution(master)
        print('pi = ', end='')
        print([constraints[i].pi for i in range(m)])
        print('')

        ##########
        # STEP 2: updating pricing objective with dual values from master
        ##########

        pricing.objective = 1
        for i in range(m):
            a[i].obj = -constraints[i].pi

        # solving pricing problem
        pricing.optimize()

        # printing pricing solution
        z_val = pricing.objective_value
        print('Pricing:')
        print('    z =  {z_val}'.format(**locals()))
        print('    a = ', end='')
        print([v.x for v in pricing.vars])
        print('')

        ##########
        # STEP 3: adding the new columns
        ##########

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

            print('new pattern = {coeffs}'.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')

    print_solution(master)
Exemplo n.º 16
0
# set of edges leaving a node
OUT = defaultdict(set)

# set of edges entering a node
IN = defaultdict(set)

# an arbitrary initial point
n0 = min(i for i in N)

for a in A:
    OUT[a[0]].add(a)
    IN[a[1]].add(a)

print('solving TSP with {} cities'.format(len(N)))

model = Model()

# binary variables indicating if arc (i,j) is used on the route or not
x = {
    a: model.add_var('x({},{})'.format(a[0], a[1]), var_type=BINARY)
    for a in A
}

# continuous variable to prevent subtours: each
# city will have a different "identifier" in the planned route
y = {i: model.add_var(name='y({})') for i in N}

# objective function: minimize the distance
model.objective = minimize(xsum(A[a] * x[a] for a in A))

# constraint : enter each city coming from another city
Exemplo n.º 17
0
# set of edges leaving a node
OUT = defaultdict(set)

# set of edges entering a node
IN = defaultdict(set)

# an arbitrary initial point
n0 = min(i for i in N)

for a in A:
    OUT[a[0]].add(a)
    IN[a[1]].add(a)

print('solving TSP with {} cities'.format(len(N)))

model = Model()

# binary variables indicating if arc (i,j) is used on the route or not
x = {
    a: model.add_var('x({},{})'.format(a[0], a[1]), var_type=BINARY)
    for a in A.keys()
}

# continuous variable to prevent subtours: each
# city will have a different "identifier" in the planned route
y = {i: model.add_var(name='y({})') for i in N}

# objective function: minimize the distance
model.objective = minimize(xsum(A[a] * x[a] for a in A.keys()))

# constraint : enter each city coming from another city
Exemplo n.º 18
0
def kantorovich():
    """
    Simple implementation of the compact formulation from Kantorovich for the problem
    """

    N = 10  # maximum number of bars
    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 the model (note that the linear relaxation is solved)
    model = Model(SOLVER)
    x = {(i, j): model.add_var(obj=0, var_type=CONTINUOUS, name="x[%d,%d]" % (i, j)) for i in range(m) for j in range(N)}
    y = {j: model.add_var(obj=1, var_type=CONTINUOUS, name="y[%d]" % j) for j in range(N)}

    # constraints
    for i in range(m):
        model.add_constr(xsum(x[i, j] for j in range(N)) >= b[i])
        for j in range(N):
            model.add_constr(xsum(w[i] * x[i, j] for i in range(m)) <= L * y[j])

    # additional constraint to reduce symmetry
    for j in range(1, N):
        model.add_constr(y[j - 1] >= y[j])

    # optimizing the model and printing solution
    model.optimize()
    print_solution(model)
Exemplo n.º 19
0
from mip.constants import BINARY

p = [0, 3, 2, 5, 4, 2, 3, 4, 2, 4, 6, 0]

u = [[0, 0], [5, 1], [0, 4], [1, 4], [1, 3], [3, 2], [3, 1], [2, 4], [4, 0],
     [5, 2], [2, 5], [0, 0]]

c = [6, 8]

S = [[0, 1], [0, 2], [0, 3], [1, 4], [1, 5], [2, 9], [2, 10], [3, 8], [4, 6],
     [4, 7], [5, 9], [5, 10], [6, 8], [6, 9], [7, 8], [8, 11], [9, 11],
     [10, 11]]

(R, J, T) = (range(len(c)), range(len(p)), range(sum(p)))

model = Model()

x = [[model.add_var(name='x({},{})'.format(j, t), var_type=BINARY) for t in T]
     for j in J]

model.objective = xsum(x[len(J) - 1][t] * t for t in T)

for j in J:
    model += xsum(x[j][t] for t in T) == 1

for (r, t) in product(R, T):
    model += xsum(u[j][r] * x[j][t2] for j in J
                  for t2 in range(max(0, t - p[j] + 1), t + 1)) <= c[r]

for (j, s) in S:
    model += xsum(t * x[s][t] - t * x[j][t] for t in T) >= p[j]
Exemplo n.º 20
0
            cut = xsum(x[i, j] for i in range(n)
                       for j in range(n) if i - j == k) <= 1
            if cut.violation > 0.001:
                model.add_cut(cut)

        for p, k in enumerate(range(3, n + n)):
            cut = xsum(x[i, j] for i in range(n)
                       for j in range(n) if i + j == k) <= 1
            if cut.violation > 0.001:
                model.add_cut(cut)


# number of queens
n = 60

queens = Model('queens', MAXIMIZE)

x = [[
    queens.add_var('x({},{})'.format(i, j), var_type=BINARY) for j in range(n)
] for i in range(n)]

# one per row
for i in range(n):
    queens += xsum(x[i][j] for j in range(n)) == 1, 'row({})'.format(i)

# one per column
for j in range(n):
    queens += xsum(x[i][j] for i in range(n)) == 1, 'col({})'.format(j)

queens.cuts_generator = DiagonalCutGenerator()
queens.cuts_generator.lazy_constraints = True
Exemplo n.º 21
0
"""Example of a solver to the n-queens problem:
   n chess queens should be placed in a n x n
   chess board so that no queen can attack another,
   i.e., just one queen per line, column and diagonal.
"""

from sys import stdout
from mip.model import Model, xsum
from mip.constants import MAXIMIZE, BINARY

# number of queens
n = 75

queens = Model('queens', MAXIMIZE)

x = [[
    queens.add_var('x({},{})'.format(i, j), var_type=BINARY) for j in range(n)
] for i in range(n)]

# one per row
for i in range(n):
    queens += xsum(x[i][j] for j in range(n)) == 1, 'row({})'.format(i)

# one per column
for j in range(n):
    queens += xsum(x[i][j] for i in range(n)) == 1, 'col({})'.format(j)

# diagonal \
for p, k in enumerate(range(2 - n, n - 2 + 1)):
    queens += xsum(x[i][j] for i in range(n)
                   for j in range(n) if i - j == k) <= 1, 'diag1({})'.format(p)
Exemplo n.º 22
0
"""0/1 Knapsack example"""

from mip.model import Model, xsum, maximize
from mip.constants import BINARY

p = [10, 13, 18, 31, 7, 15]
w = [11, 15, 20, 35, 10, 33]
c = 47
n = len(w)

m = Model('knapsack')

x = [m.add_var(var_type=BINARY) for i in range(n)]

m.objective = maximize(xsum(p[i] * x[i] for i in range(n)))

m += xsum(w[i] * x[i] for i in range(n)) <= c

m.optimize()

selected = [i for i in range(n) if x[i].x >= 0.99]
print('selected items: {}'.format(selected))
Exemplo n.º 23
0
class UnitCommitment:
    def __init__(self, generators, demand):

        self.generators = generators
        self.demand = demand

        self.period = range(1, len(self.demand) + 1)

        self.model = Model(name='UnitCommitment')
        self.p, self.u = {}, {}

    def build_model(self, fixed=False, u_fixed=None):

        for t in self.period:
            for g in self.generators.index:
                if fixed:
                    self.u[t, g] = self.model.add_var(lb=u_fixed[t, g],
                                                      ub=u_fixed[t, g])
                else:
                    self.u[t, g] = self.model.add_var(var_type=BINARY)
                self.p[t, g] = self.model.add_var()

        # Max/min power
        for t in self.period:
            for g in self.generators.index:
                self.model.add_constr(
                    self.p[t, g] <=
                    self.generators.loc[g, 'p_max'] * self.u[t, g],
                    name=f'pmax_constr[{t},{g}]')
                self.model.add_constr(
                    self.p[t, g] >=
                    self.generators.loc[g, 'p_min'] * self.u[t, g],
                    name=f'pmin_constr[{t},{g}]')

        # Power balance
        for t in self.period:
            self.model.add_constr(xsum(
                self.p[t, g]
                for g in self.generators.index) == self.demand.loc[t,
                                                                   'demand'],
                                  name=f'power_bal_constr[{t}]')

        # Min on
        for t in self.period[1:]:
            for g in self.generators.index:
                min_on_time = min(t + self.generators.loc[g, 'min_on'] - 1,
                                  len(self.period))
                for tau in range(t, min_on_time + 1):
                    self.model.add_constr(
                        self.u[tau, g] >= self.u[t, g] - self.u[t - 1, g],
                        name=f'min_on_constr[{t},{g}]')

        # Min off
        for t in self.period[1:]:
            for g in self.generators.index:
                min_off_time = min(t + self.generators.loc[g, 'min_off'] - 1,
                                   len(self.period))
                for tau in range(t, min_off_time + 1):
                    self.model.add_constr(
                        1 - self.u[tau, g] >= self.u[t - 1, g] - self.u[t, g],
                        name=f'min_off_constr[{t},{g}]')

        # Objective function
        self.model.objective = minimize(
            xsum(
                xsum(self.p[t, g] * self.generators.loc[g, 'c_var'] +
                     self.u[t, g] * self.generators.loc[g, 'c_fix']
                     for g in self.generators.index) for t in self.period))

    def optimize(self):

        self.model.optimize()

        return self.u, self.p, self.model.objective.x, self.model.status.name

    def get_prices(self):

        u_fixed = {(t, g): self.u[t, g].x
                   for g in self.generators.index for t in self.period}
        self.model.clear()
        self.build_model(fixed=True, u_fixed=u_fixed)
        self.optimize()

        return [
            self.model.constr_by_name(f'power_bal_constr[{t}]').pi
            for t in self.period
        ]