Пример #1
0
def initialize_model(cost_matrix, cutoff, model=None):
    #Add dummy detection
    cost_matrix = np.insert(cost_matrix,
                            0,
                            np.ones(cost_matrix.shape[0]) * cutoff,
                            axis=1)
    M, N = cost_matrix.shape
    if model is None:
        model = Model()
    else:
        model.remove(model.getVars())
        model.remove(model.getConstrs())
    model.setParam('OutputFlag', False)
    # y = []
    # for i in range(M):
    #     y.append([])
    #     for j in range(N):
    #         y[i].append(m.addVar(vtype=GRB.BINARY, name = 'y_%d%d'%(i,j)))
    y = model.addVars(M, N, vtype=GRB.BINARY, name='y')
    model.setObjective(
        quicksum(
            quicksum([y[i, j] * cost_matrix[i][j] for j in range(N)])
            for i in range(M)), GRB.MINIMIZE)
    # for i in range(M):
    model.addConstrs(
        (quicksum(y[i, j] for j in range(N)) == 1 for i in range(M)),
        name='constraint for track')
    # for j in range(1,N):
    model.addConstrs(
        (quicksum(y[i, j] for i in range(M)) <= 1 for j in range(1, N)),
        name='constraint for detection')
    y = list(y.values())
    return model, M, N, y
Пример #2
0
class Master:
    """ Master Object for initialising, solving, updating, and column creation
     of the tail assignment master problem"""
    def __init__(self, Data):
        """Formulate the master problem.
        INPUTS
            Data    :: object, classes.Data; problem data.
        """
        self.Data = Data
        self.duals = []
        self.master = Model("master LP")  # Init master model
        self.master.Params.OutputFlag = 0  # No output

        self._formulate_master()

    def _formulate_master(self):
        """ Formulate set partitioning model for tail assignment"""
        # Variable dicts #
        a_dict = {(s_label[1], s): s.cost
                  for s_label, s in self.Data.scheds.items()}
        dum_dict = {
            f: 20000 + 20000 * (f.arrival - f.departure)
            for f in self.Data.flights
        }
        # VARIABLES #
        a = self.master.addVars(a_dict.keys(), name="a", vtype="B")
        dummy = self.master.addVars(dum_dict.keys(), name="dummy", vtype="B")
        # OBJECTIVE FUNCTION #
        self.master.setObjective(dummy.prod(dum_dict))
        # FLIGHT CONSTRAINTS #
        self.master.addConstrs((dummy[key] >= 1 for key in dum_dict),
                               name='flight')
        # AIRCRAFT CONSTRAINTS #
        self.master.addConstrs(
            (a.sum(k, '*') <= 1 for k in self.Data.aircraft),
            name='aircraft_schedule')
        self.master.update()
        # write to file
        self.master.write("./output/init.lp")

    def _solve_relax(self):
        """
        Relaxes and solves the master problem.
        INPUTS
            master  :: object, gurobipy.Model; master problem.
        RETURNS
            duals   :: list of tuples, (dual, classes.Flight)
            relax   :: object, gurobipy.Model; relaxed master problem.
        """
        self.relax = self.master.relax()
        self.relax.update()
        self.relax.optimize()
        duals = [(float(c.Pi), [
            f for f in self.Data.flights if f.i_d == self._split(c.ConstrName)
        ][0]) for c in self.relax.getConstrs() if "flight" in c.ConstrName]
        duals = sorted(duals, key=lambda x: x[1].i_d)
        self.duals.append([d[0] for d in duals])
        return self.relax, duals

    def _generate_column(self, k, it, path):
        """
        Adds column using shortest path from extended TSN.

        Parameters
        ----------
        k : str,
            aircraft in subproblem

        it : int,
            iteration number

        path : list,
            edges in shortest path [(edge_dict, edge_weight), ..]

        Returns
        -------
        master : object,
            gurobipy.Model; updated master problem with new column
        """

        col = Column()  # Init Column
        flights = self.Data.flights
        cost_col = 0  # count number of dummy edges for column obj coeff

        for p in path:  # for each flight in the path
            if any(f._full_dict() == p[0] for f in flights):
                flight = [f for f in flights if f._full_dict() == p[0]][0]
                # Get constraints associated with flight
                constrs = [
                    c for c in self.master.getConstrs()
                    if "flight" in c.ConstrName
                    and self._split(c.ConstrName) == flight.i_d
                ]
                # Add terms to column for each constraint
                col.addTerms([1] * len(constrs), constrs)
            else:
                cost_col += p[1]
        # Get constraints associated with aircraft k
        constr = [
            c for c in self.master.getConstrs()
            if "aircraft_schedule" in c.ConstrName and k in c.ConstrName
        ][0]
        col.addTerms(1, constr)
        # Get aircraft dual for cost
        lambda_k = [
            float(c.Pi) for c in self.relax.getConstrs()
            if "aircraft_schedule" in c.ConstrName and k in c.ConstrName
        ][0]
        # cost of path + 2 due to first edge initialisation
        cost = 2 + sum(p[1] for p in path) - lambda_k
        if cost < 0:
            self.master.addVar(obj=cost_col,
                               vtype="B",
                               name="a[%s,s_%s_%s]" % (k, it, k),
                               column=col)
            self.master.update()
        return self, cost

    @staticmethod
    def _split(string):
        """ Split integers in string and return last occurrence"""
        import re
        return list(map(int, re.findall(r'\d+', string)))[-1]
Пример #3
0
        for k in K:
            prt.print_aggregated_fs_aircraft_schedule(airports, N, A,
                                                      last_hour, k, n, y,
                                                      instance, images_dir)

        print("\n########### SECOND STAGE SCHEDULE ##########")
        for s in S:
            print("###### Scenario {} #####".format(s))
            for k in K:
                prt.print_aggregated_ss_aircraft_schedule(
                    airports, N, A, last_hour, k, n, y, s, instance,
                    images_dir)

    if write_cargo_routing:
        wrt.write_cargo_schedule(ods_dir,
                                 "Schedule ODs i-{}.txt".format(instance), A,
                                 S, Cargo, OD, ex, x)

    if write_retimings:
        wrt.write_retimings(retimings_dir,
                            "Retimings i-{}.txt".format(instance), S, AF, V, K,
                            y, r, zplus, zminus)

else:
    print('Optimization was stopped with status {}'.format(status))
    # compute Irreducible Inconsistent Subsystem
    model.computeIIS()
    for constr in model.getConstrs():
        if constr.IISConstr:
            print('Infeasible constraint: {}'.format(constr.constrName))
Пример #4
0
from gurobipy import Model, GRB

m = Model("hw51")

x1 = m.addVar(name="x1")
x2 = m.addVar(name="x2")

m.update()

m.setObjective(5 * x1 + 4 * x2, GRB.MAXIMIZE)

m.addConstr(6 * x1 + 4 * x2 <= 24, 'constraint1')
m.addConstr(x1 + 2 * x2 <= 6, 'constraint2')
m.addConstr(-x1 + x2 <= 1, 'constraint3')
m.addConstr(x2 <= 2, ' constraint4')

m.optimize()

for v in m.getVars():
    print('%s: %f' % (v.varName, v.x))

print('Obj: %f' % m.objVal)

print 'reduced costs: '
print ' ', m.getAttr('rc', m.getVars())
print 'shadow prices: '
print ' ', m.getAttr('pi', m.getConstrs())
Пример #5
0
obj = quicksum(
    quicksum(p[i] * quicksum(v[i, j, t] for j in j_c[:u[i]]) +
             P[i] * quicksum(v[i, j, t] for j in j_c[u[i]:U[i]]) -
             Q[i] * w[i, t] - C[i] * n[i, t] - Z[i] * Gamma[i, t]
             for i in i_c) - E * Beta[t] - k * Lambda[t] for t in t_c[1:])
model.setObjective(obj, GRB.MAXIMIZE)
model.write("model.lp")

# optimizar
model.optimize()

# resultados
# model.printAttr("X")
vars = [(i, var) for i, var in enumerate(model.getVars())]
with open("holguras.txt", "w") as file:
    with open("antiholguras.txt", "w") as antifile:
        for x in model.getConstrs():
            if round(x.slack, 10) == 0:
                if x.sense != "=":
                    file.write(f"{x.ConstrName} {x.slack}\n")
            else:
                antifile.write(f"{x.ConstrName} {x.slack}\n")
with open("resultados.txt", "w") as file:
    file.write(f"{model.objVal}\n")
    for var in vars:
        if ("Beta" in var[1].varName
                or "Gamma" in var[1].varName) or "Lambda" in var[1].varName:
            file.write('%s %g' % (var[1].varName, var[1].x) + "\n")
        if "total" in var[1].varName:
            print('%s %g' % (var[1].varName, var[1].x) + "\n")
def generate_multi_dim_sample(bounds, directory, num_teams, num_md_per_cycle,
                              numSam, numCycle, theoretical):

    # the list of sample dimensions, the +1
    cycle = list(range(numCycle))
    day = list(range(num_md_per_cycle))
    days = list(range(num_md_per_cycle + 1))
    home = away = list(range(num_teams))

    constrList = [
        [(0, ), (1, )],
        [(0, ), (2, )],
        [(0, ), (3, )],
        [(0, ), (1, 2)],
        [(0, ), (1, 3)],
        [(0, ), (2, 3)],
        [(0, ), (1, 2, 3)],
        [(1, ), (0, )],
        [(1, ), (2, )],
        [(1, ), (3, )],
        [(1, ), (0, 2)],
        [(1, ), (0, 3)],
        [(1, ), (2, 3)],
        [(1, ), (0, 2, 3)],
        [(2, ), (0, )],
        [(2, ), (1, )],
        [(2, ), (3, )],
        [(2, ), (0, 1)],
        [(2, ), (0, 3)],
        [(2, ), (1, 3)],
        [(2, ), (0, 1, 3)],
        [(3, ), (0, )],
        [(3, ), (1, )],
        [(3, ), (2, )],
        [(3, ), (0, 1)],
        [(3, ), (0, 2)],
        [(3, ), (1, 2)],
        [(3, ), (0, 1, 2)],
        [(0, 1), (2, )],
        [(0, 1), (3, )],
        [(0, 1), (2, 3)],
        # cons away = 31
        [(0, 2), (1, )],
        [(0, 2), (3, )],
        [(0, 2), (1, 3)],
        # cons home = 34
        [(0, 3), (1, )],
        [(0, 3), (2, )],
        [(0, 3), (1, 2)],
        [(1, 2), (0, )],
        [(1, 2), (3, )],
        [(1, 2), (0, 3)],
        [(1, 3), (0, )],
        [(1, 3), (2, )],
        [(1, 3), (0, 2)],
        [(2, 3), (0, )],
        [(2, 3), (1, )],
        [(2, 3), (0, 1)],
        [(0, 1, 2), (3, )],
        [(0, 1, 3), (2, )],
        [(0, 2, 3), (1, )],
        [(1, 2, 3), (0, )]
    ]

    try:
        model = Model("sspSolver")
        # give verbose logging when 1, otherwise 0
        model.setParam(GRB.param.OutputFlag, 1)

        ### Decision Variables ###
        # 0 = cycles, 1 = days, 2 = away, 3 = home
        # regular combinations over the 4 dimensions
        x = model.addVars(cycle,
                          day,
                          home,
                          away,
                          vtype=GRB.BINARY,
                          name="base")
        n = model.addVars(cycle, day, home, vtype=GRB.BINARY, name="n")
        o = model.addVars(cycle, day, away, vtype=GRB.BINARY, name="o")
        p = model.addVars(cycle, home, away, vtype=GRB.BINARY, name="p")
        q = model.addVars(day, home, away, vtype=GRB.BINARY, name="q")
        r = model.addVars(cycle, day, vtype=GRB.BINARY, name="r")
        s = model.addVars(cycle, home, vtype=GRB.BINARY, name="s")
        t = model.addVars(cycle, away, vtype=GRB.BINARY, name="t")
        u = model.addVars(day, home, vtype=GRB.BINARY, name="u")
        v = model.addVars(day, away, vtype=GRB.BINARY, name="v")
        w = model.addVars(home, away, vtype=GRB.BINARY, name="w")

        #y = model.addVars(cycle, day, home, away, vtype=GRB.BINARY, name="basetrans")
        #yn = model.addVars(cycle, day, home, vtype=GRB.BINARY, name="trans_n")

        cNA = model.addVars(cycle,
                            day,
                            day,
                            away,
                            vtype=GRB.BINARY,
                            name="cons")
        cNAs = model.addVars(cycle,
                             days,
                             day,
                             away,
                             vtype=GRB.BINARY,
                             name="cons_min")
        cNH = model.addVars(cycle,
                            day,
                            day,
                            home,
                            vtype=GRB.BINARY,
                            name="consHome")
        cNHs = model.addVars(cycle,
                             days,
                             day,
                             home,
                             vtype=GRB.BINARY,
                             name="consHomes")

        cZy = model.addVars(cycle,
                            day,
                            day,
                            home,
                            vtype=GRB.BINARY,
                            name="days_betw_games")
        cZys = model.addVars(cycle,
                             days,
                             day,
                             home,
                             vtype=GRB.BINARY,
                             name="days_btw_gamess")

        # transpose function
        #model.addConstrs(
        #    y[c, d, h, a] == x[c, d, h, a] + x[c, d, a, h] for c in cycle for d in day for a in away for h in home)
        #model.addConstrs((y.sum(c, d, h, '*') == yn[c, d, h] for c in cycle for d in day for h in home), "yn_y")

        model.addConstrs((x.sum(c, d, '*', a) == o[c, d, a] for c in cycle
                          for d in day for a in away), "xo")
        model.addConstrs((x.sum(c, d, h, '*') == n[c, d, h] for c in cycle
                          for d in day for h in home), "xn")
        model.addConstrs((x.sum(c, '*', h, a) == p[c, h, a] for c in cycle
                          for h in home for a in away), "xp")
        model.addConstrs((x.sum('*', d, h, a) == q[d, h, a] for d in day
                          for h in home for a in away), "xq")

        model.addConstrs(
            (r[c, d] <= n.sum(c, d, '*') for c in cycle for d in day), "rn")
        model.addConstrs(
            (t[c, a] <= n.sum(c, '*', a) for c in cycle for a in away), "tn")
        model.addConstrs(
            (v[d, a] <= n.sum('*', d, a) for d in day for a in away), "vn")

        model.addConstrs(
            (r[c, d] <= o.sum(c, d, '*') for c in cycle for d in day), "ro")
        model.addConstrs(
            (s[c, h] <= o.sum(c, '*', h) for c in cycle for h in home), "so")
        model.addConstrs(
            (u[d, h] <= o.sum('*', d, h) for d in day for h in home), "uo")

        model.addConstrs(
            (s[c, h] <= p.sum(c, h, '*') for c in cycle for h in home), "sp")
        model.addConstrs(
            (t[c, a] <= p.sum(c, '*', a) for c in cycle for a in away), "tp")
        model.addConstrs(
            (w[h, a] <= p.sum('*', h, a) for h in home for a in away), "wp")

        model.addConstrs(
            (u[d, h] <= q.sum(d, h, '*') for d in day for h in home), "uq")
        model.addConstrs(
            (v[d, a] <= q.sum(d, '*', a) for d in day for a in away), "vq")
        model.addConstrs(
            (w[h, a] <= q.sum('*', h, a) for h in home for a in away), "wq")

        if theoretical:
            ### Hard constraints -- not yet in bounds ###
            # never play yourself
            model.addConstrs(x[c, d, i, i] == 0 for c in cycle for d in day
                             for i in home)
            # only play one game per day
            model.addConstrs((x.sum(c, d, i, '*') + x.sum(c, d, '*', i) <= 1
                              for c in cycle for d in day
                              for i in home), "1gamePerDay")

        # Hard constraints from bounds files ###
        # bounds 0 = countLowerbound
        # bounds 1 = countUpperBound
        # bounds 2 = minConsZero
        # bounds 3 = maxConsZero
        # bounds 4 = minConsNonZero
        # bounds 5 = maxConsNonZero
        for i in range(len(bounds)):
            ### SEED COUNT BOUNDS: bounds[i,0] is the lowerbound, bounds[i,1] is the upperbound
            if bounds[i, 0] > 0:
                # this part covers count lowerbound
                if constrList[i] == [(0, ), (1, )]:
                    model.addConstrs((r.sum(c, '*') >= bounds[i, 0]
                                      for c in cycle), "LWR_constr-(0,), (1,)")
                elif constrList[i] == [(0, ), (2, )]:
                    model.addConstrs((t.sum(c, '*') >= bounds[i, 0]
                                      for c in cycle), "LWR_constr-(0,), (2,)")
                elif constrList[i] == [(0, ), (3, )]:
                    model.addConstrs((s.sum(c, '*') >= bounds[i, 0]
                                      for c in cycle), "LWR_constr-(0,), (3,)")
                elif constrList[i] == [(0, ), (1, 2)]:
                    model.addConstrs(
                        (o.sum(c, '*', '*') >= bounds[i, 0] for c in cycle),
                        "LWR_constr-(0,), (1,2)")
                elif constrList[i] == [(0, ), (1, 3)]:
                    model.addConstrs(
                        (n.sum(c, '*', '*') >= bounds[i, 0] for c in cycle),
                        "LWR_constr-(0,), (1,3)")
                elif constrList[i] == [(0, ), (2, 3)]:
                    model.addConstrs(
                        (p.sum(c, '*', '*') >= bounds[i, 0] for c in cycle),
                        "LWR_constr-(0,), (2,3)")
                elif constrList[i] == [(0, ), (1, 2, 3)]:
                    model.addConstrs((x.sum(c, '*', '*', '*') >= bounds[i, 0]
                                      for c in cycle),
                                     "LWR_constr-(0,), (1,2,3)")

                elif constrList[i] == [(1, ), (0, )]:
                    model.addConstrs((r.sum('*', d) >= bounds[i, 0]
                                      for d in day), "LWR_constr-(1,), (0,)")
                elif constrList[i] == [(1, ), (2, )]:
                    model.addConstrs((v.sum(d, '*') >= bounds[i, 0]
                                      for d in day), "LWR_constr-(1,), (2,)")
                elif constrList[i] == [(1, ), (3, )]:
                    model.addConstrs((u.sum(d, '*') >= bounds[i, 0]
                                      for d in day), "LWR_constr-(1,), (3,)")
                elif constrList[i] == [(1, ), (0, 2)]:
                    model.addConstrs((o.sum('*', d, '*') >= bounds[i, 0]
                                      for d in day), "LWR_constr-(1,), (0,2)")
                elif constrList[i] == [(1, ), (0, 3)]:
                    model.addConstrs((n.sum('*', d, '*') >= bounds[i, 0]
                                      for d in day), "LWR_constr-(1,), (0,3)")
                elif constrList[i] == [(1, ), (2, 3)]:
                    model.addConstrs((q.sum(d, '*', '*') >= bounds[i, 0]
                                      for d in day), "LWR_constr-(1,), (2,3)")
                elif constrList[i] == [(1, ), (0, 2, 3)]:
                    model.addConstrs(
                        (x.sum('*', d, '*', '*') >= bounds[i, 0] for d in day),
                        "LWR_constr-(1,), (0,2,3)")

                elif constrList[i] == [(2, ), (0, )]:
                    model.addConstrs((t.sum('*', h) >= bounds[i, 0]
                                      for h in home), "LWR_constr-(2,), (0,)")
                elif constrList[i] == [(2, ), (1, )]:
                    model.addConstrs((v.sum('*', h) >= bounds[i, 0]
                                      for h in home), "LWR_constr-(2,), (1,)")
                elif constrList[i] == [(2, ), (3, )]:
                    model.addConstrs((w.sum(h, '*') >= bounds[i, 0]
                                      for h in home), "LWR_constr--(2,), (3,)")
                elif constrList[i] == [(2, ), (0, 1)]:
                    model.addConstrs(
                        (o.sum('*', '*', h) >= bounds[i, 0] for h in home),
                        "LWR_constr--(2,), (0,1)")
                elif constrList[i] == [(2, ), (0, 3)]:
                    model.addConstrs(
                        (p.sum('*', h, '*') >= bounds[i, 0] for h in home),
                        "LWR_constr--(2,), (0,3)")
                elif constrList[i] == [(2, ), (1, 3)]:
                    model.addConstrs((q.sum('*', h, '*') >= bounds[i, 0]
                                      for h in home), "LWR_constr-(2,), (1,3)")
                elif constrList[i] == [(2, ), (0, 1, 3)]:
                    model.addConstrs((x.sum('*', '*', h, '*') >= bounds[i, 0]
                                      for h in home),
                                     "LWR_constr-(2,), (0,1,3)")

                elif constrList[i] == [(3, ), (0, )]:
                    model.addConstrs((s.sum('*', a) >= bounds[i, 0]
                                      for a in away), "LWR_constr-(3,), (0,)")
                elif constrList[i] == [(3, ), (1, )]:
                    model.addConstrs((u.sum('*', a) >= bounds[i, 0]
                                      for a in away), "LWR_constr-(3,), (1,)")
                elif constrList[i] == [(3, ), (2, )]:
                    model.addConstrs((w.sum('*', a) >= bounds[i, 0]
                                      for a in away), "LWR_constr-(3,), (2,)")
                elif constrList[i] == [(3, ), (0, 1)]:
                    model.addConstrs((n.sum('*', '*', a) >= bounds[i, 0]
                                      for a in away), "LWR_constr-(3,), (0,1)")
                elif constrList[i] == [(3, ), (0, 2)]:
                    model.addConstrs((p.sum('*', '*', a) >= bounds[i, 0]
                                      for a in away), "LWR_constr-(3,), (0,2)")
                elif constrList[i] == [(3, ), (1, 2)]:
                    model.addConstrs((q.sum('*', '*', a) >= bounds[i, 0]
                                      for a in away), "LWR_constr-(3,), (1,2)")
                elif constrList[i] == [(3, ), (0, 1, 2)]:
                    model.addConstrs((x.sum('*', '*', '*', a) >= bounds[i, 0]
                                      for a in away),
                                     "LWR_constr-(3,), (0,1,2)")

                elif constrList[i] == [(0, 1), (2, )]:
                    model.addConstrs((o.sum(c, d, '*') >= bounds[i, 0]
                                      for c in cycle
                                      for d in day), "LWR_constr-(0,1), (2,)")
                elif constrList[i] == [(0, 1), (3, )]:
                    model.addConstrs((n.sum(c, d, '*') >= bounds[i, 0]
                                      for c in cycle
                                      for d in day), "LWR_constr-(0,1), (3,)")
                elif constrList[i] == [(0, 1), (2, 3)]:
                    model.addConstrs((x.sum(c, d, '*', '*') >= bounds[i, 0]
                                      for c in cycle
                                      for d in day), "LWR_constr-(0,1), (2,3)")

                elif constrList[i] == [(0, 2), (1, )]:
                    bound = bounds[i, 0]
                    model.addConstrs((o.sum(c, '*', a) >= bounds[i, 0]
                                      for c in cycle
                                      for a in away), "LWR_constr-(0,2), (1,)")
                elif constrList[i] == [(0, 2), (3, )]:
                    model.addConstrs((p.sum(c, '*', a) >= bounds[i, 0]
                                      for c in cycle
                                      for a in away), "LWR_constr-(0,2), (3,)")
                elif constrList[i] == [(0, 2), (1, 3)]:
                    model.addConstrs((x.sum(c, '*', a) >= bounds[i, 0]
                                      for c in cycle for a in away),
                                     "LWR_constr-(0,2), (1,3)")

                elif constrList[i] == [(0, 3), (1, )]:
                    model.addConstrs((n.sum(c, '*', h) >= bounds[i, 0]
                                      for c in cycle
                                      for h in home), "LWR_constr-(0,3), (1,)")
                elif constrList[i] == [(0, 3), (2, )]:
                    model.addConstrs((p.sum(c, '*', h) >= bounds[i, 0]
                                      for c in cycle
                                      for h in home), "LWR_constr-(0,3), (2,)")
                elif constrList[i] == [(0, 3), (1, 2)]:
                    model.addConstrs((x.sum(c, '*', '*', h) >= bounds[i, 0]
                                      for c in cycle for h in home),
                                     "LWR_constr-(0,3), (1,2)")

                elif constrList[i] == [(1, 2), (0, )]:
                    model.addConstrs((o.sum('*', d, a) >= bounds[i, 0]
                                      for d in day
                                      for a in away), "LWR_constr-(1,2), (0,)")
                elif constrList[i] == [(1, 2), (3, )]:
                    model.addConstrs((q.sum(d, a, '*') >= bounds[i, 0]
                                      for d in day
                                      for a in away), "LWR_constr-(1,2), (3,)")
                elif constrList[i] == [(1, 2), (0, 3)]:
                    model.addConstrs((x.sum('*', d, a, '*') >= bounds[i, 0]
                                      for d in day for a in away),
                                     "LWR_constr-(1,2), (0,3)")

                elif constrList[i] == [(1, 3), (0, )]:
                    model.addConstrs((n.sum('*', d, h) >= bounds[i, 0]
                                      for d in day
                                      for h in home), "LWR_constr-(1,3), (0,)")
                elif constrList[i] == [(1, 3), (2, )]:
                    model.addConstrs((q.sum(d, '*', h) >= bounds[i, 0]
                                      for d in day
                                      for h in home), "LWR_constr-(1,3), (2,)")
                elif constrList[i] == [(1, 3), (0, 2)]:
                    model.addConstrs((x.sum('*', d, '*', h) >= bounds[i, 0]
                                      for d in day for h in home),
                                     "LWR_constr-(1,3), (0,2)")

                elif constrList[i] == [(2, 3), (0, )]:
                    model.addConstrs((p.sum('*', h, a) >= bounds[i, 0]
                                      for h in home
                                      for a in away), "LWR_constr-(2,3), (0,)")
                elif constrList[i] == [(2, 3), (1, )]:
                    model.addConstrs((q.sum('*', h, a) >= bounds[i, 0]
                                      for h in home
                                      for a in away), "LWR_constr-(2,3), (1,)")
                elif constrList[i] == [(2, 3), (0, 1)]:
                    model.addConstrs((x.sum('*', '*', h, a) >= bounds[i, 0]
                                      for h in home for a in away),
                                     "LWR_constr-(2,3), (0,1)")

                elif constrList[i] == [(0, 1, 2), (3, )]:
                    model.addConstrs((x.sum(c, d, a, '*') >= bounds[i, 0]
                                      for c in cycle for d in day
                                      for a in away),
                                     "LWR_constr-(0,1,2), (3,)")
                elif constrList[i] == [(0, 1, 3), (2, )]:
                    model.addConstrs((x.sum(c, d, '*', h) >= bounds[i, 0]
                                      for c in cycle for d in day
                                      for h in home),
                                     "LWR_constr-(0,1,3), (2,)")
                elif constrList[i] == [(0, 2, 3), (1, )]:
                    model.addConstrs((x.sum(c, '*', a, h) >= bounds[i, 0]
                                      for c in cycle for a in away
                                      for h in home),
                                     "LWR_constr-(0,2,3), (1,)")
                elif constrList[i] == [(1, 2, 3), (0, )]:
                    model.addConstrs((x.sum('*', d, a, h) >= bounds[i, 0]
                                      for d in day for a in away
                                      for h in home),
                                     "LWR_constr-(1,2,3), (0,)")
            if bounds[i, 1] > 0:
                # this part covers count lowerbound
                if constrList[i] == [(0, ), (1, )]:
                    model.addConstrs((r.sum(c, '*') <= bounds[i, 1]
                                      for c in cycle), "constr-(0,), (1,)")
                elif constrList[i] == [(0, ), (2, )]:
                    model.addConstrs((t.sum(c, '*') <= bounds[i, 1]
                                      for c in cycle), "constr-(0,), (2,)")
                elif constrList[i] == [(0, ), (3, )]:
                    model.addConstrs((s.sum(c, '*') <= bounds[i, 1]
                                      for c in cycle), "constr-(0,), (3,)")
                elif constrList[i] == [(0, ), (1, 2)]:
                    model.addConstrs((o.sum(c, '*', '*') <= bounds[i, 1]
                                      for c in cycle), "constr-(0,), (1,2)")
                elif constrList[i] == [(0, ), (1, 3)]:
                    model.addConstrs((n.sum(c, '*', '*') <= bounds[i, 1]
                                      for c in cycle), "constr-(0,), (1,3)")
                elif constrList[i] == [(0, ), (2, 3)]:
                    model.addConstrs((p.sum(c, '*', '*') <= bounds[i, 1]
                                      for c in cycle), "constr-(0,), (2,3)")
                elif constrList[i] == [(0, ), (1, 2, 3)]:
                    model.addConstrs((x.sum(c, '*', '*', '*') <= bounds[i, 1]
                                      for c in cycle), "constr-(0,), (1,2,3)")

                elif constrList[i] == [(1, ), (0, )]:
                    model.addConstrs((r.sum('*', d) <= bounds[i, 1]
                                      for d in day), "LWR_constr-(1,), (0,)")
                elif constrList[i] == [(1, ), (2, )]:
                    model.addConstrs((v.sum(d, '*') <= bounds[i, 1]
                                      for d in day), "LWR_constr-(1,), (2,)")
                elif constrList[i] == [(1, ), (3, )]:
                    model.addConstrs((u.sum(d, '*') <= bounds[i, 1]
                                      for d in day), "LWR_constr-(1,), (3,)")
                elif constrList[i] == [(1, ), (0, 2)]:
                    model.addConstrs((o.sum('*', d, '*') <= bounds[i, 1]
                                      for d in day), "LWR_constr-(1,), (0,2)")
                elif constrList[i] == [(1, ), (0, 3)]:
                    model.addConstrs((n.sum('*', d, '*') <= bounds[i, 1]
                                      for d in day), "LWR_constr-(1,), (0,3)")
                elif constrList[i] == [(1, ), (2, 3)]:
                    model.addConstrs((q.sum(d, '*', '*') <= bounds[i, 1]
                                      for d in day), "LWR_constr-(1,), (2,3)")
                elif constrList[i] == [(1, ), (0, 2, 3)]:
                    model.addConstrs(
                        (x.sum('*', d, '*', '*') <= bounds[i, 1] for d in day),
                        "LWR_constr-(1,), (0,2,3)")

                elif constrList[i] == [(2, ), (0, )]:
                    model.addConstrs((t.sum('*', h) <= bounds[i, 1]
                                      for h in home), "constr-(2,), (0,)")
                elif constrList[i] == [(2, ), (1, )]:
                    model.addConstrs((v.sum('*', h) <= bounds[i, 1]
                                      for h in home), "constr-(2,), (1,)")
                elif constrList[i] == [(2, ), (3, )]:
                    model.addConstrs((w.sum(h, '*') <= bounds[i, 1]
                                      for h in home), "constr--(2,), (3,)")
                elif constrList[i] == [(2, ), (0, 1)]:
                    model.addConstrs((o.sum('*', '*', h) <= bounds[i, 1]
                                      for h in home), "constr--(2,), (0,1)")
                elif constrList[i] == [(2, ), (0, 3)]:
                    model.addConstrs((p.sum('*', h, '*') <= bounds[i, 1]
                                      for h in home), "constr--(2,), (0,3)")
                elif constrList[i] == [(2, ), (1, 3)]:
                    model.addConstrs((q.sum('*', h, '*') <= bounds[i, 1]
                                      for h in home), "constr-(2,), (1,3)")
                elif constrList[i] == [(2, ), (0, 1, 3)]:
                    model.addConstrs((x.sum('*', '*', h, '*') <= bounds[i, 1]
                                      for h in home),
                                     "LWR_constr-(2,), (0,1,3)")

                elif constrList[i] == [(3, ), (0, )]:
                    model.addConstrs((s.sum('*', a) <= bounds[i, 1]
                                      for a in away), "constr-(3,), (0,)")
                elif constrList[i] == [(3, ), (1, )]:
                    model.addConstrs((u.sum('*', a) <= bounds[i, 1]
                                      for a in away), "constr-(3,), (1,)")
                elif constrList[i] == [(3, ), (2, )]:
                    model.addConstrs((w.sum('*', a) <= bounds[i, 1]
                                      for a in away), "constr-(3,), (2,)")
                elif constrList[i] == [(3, ), (0, 1)]:
                    model.addConstrs((n.sum('*', '*', a) <= bounds[i, 1]
                                      for a in away), "constr-(3,), (0,1)")
                elif constrList[i] == [(3, ), (0, 2)]:
                    model.addConstrs((p.sum('*', '*', a) <= bounds[i, 1]
                                      for a in away), "constr-(3,), (0,2)")
                elif constrList[i] == [(3, ), (1, 2)]:
                    model.addConstrs((q.sum('*', '*', a) <= bounds[i, 1]
                                      for a in away), "constr-(3,), (1,2)")
                elif constrList[i] == [(3, ), (0, 1, 2)]:
                    model.addConstrs((x.sum('*', '*', '*', a) <= bounds[i, 1]
                                      for a in away), "constr-(3,), (0,1,2)")

                elif constrList[i] == [(0, 1), (2, )]:
                    model.addConstrs((o.sum(c, d, '*') <= bounds[i, 1]
                                      for c in cycle
                                      for d in day), "constr-(0,1), (2,)")
                elif constrList[i] == [(0, 1), (3, )]:
                    model.addConstrs((n.sum(c, d, '*') <= bounds[i, 1]
                                      for c in cycle
                                      for d in day), "constr-(0,1), (3,)")
                elif constrList[i] == [(0, 1), (2, 3)]:
                    model.addConstrs((x.sum(c, d, '*', '*') <= bounds[i, 1]
                                      for c in cycle
                                      for d in day), "constr-(0,1), (2,3)")

                elif constrList[i] == [(0, 2), (1, )]:
                    model.addConstrs((o.sum(c, '*', a) <= bounds[i, 1]
                                      for c in cycle
                                      for a in away), "constr-(0,2), (1,)")
                elif constrList[i] == [(0, 2), (3, )]:
                    model.addConstrs((p.sum(c, '*', a) <= bounds[i, 1]
                                      for c in cycle
                                      for a in away), "constr-(0,2), (3,)")
                elif constrList[i] == [(0, 2), (1, 3)]:
                    model.addConstrs((x.sum(c, '*', a) <= bounds[i, 1]
                                      for c in cycle
                                      for a in away), "constr-(0,2), (1,3)")

                elif constrList[i] == [(0, 3), (1, )]:
                    model.addConstrs((n.sum(c, '*', h) <= bounds[i, 1]
                                      for c in cycle
                                      for h in home), "constr-(0,3), (1,)")
                elif constrList[i] == [(0, 3), (2, )]:
                    model.addConstrs((p.sum(c, '*', h) <= bounds[i, 1]
                                      for c in cycle
                                      for h in home), "constr-(0,3), (2,)")
                elif constrList[i] == [(0, 3), (1, 2)]:
                    model.addConstrs((x.sum(c, '*', '*', h) <= bounds[i, 1]
                                      for c in cycle
                                      for h in home), "constr-(0,3), (1,2)")

                elif constrList[i] == [(1, 2), (0, )]:
                    model.addConstrs((o.sum('*', d, a) <= bounds[i, 1]
                                      for d in day
                                      for a in away), "constr-(1,2), (0,)")
                elif constrList[i] == [(1, 2), (3, )]:
                    model.addConstrs((q.sum(d, a, '*') <= bounds[i, 1]
                                      for d in day
                                      for a in away), "constr-(1,2), (3,)")
                elif constrList[i] == [(1, 2), (0, 3)]:
                    model.addConstrs((x.sum('*', d, a, '*') <= bounds[i, 1]
                                      for d in day
                                      for a in away), "constr-(1,2), (0,3)")

                elif constrList[i] == [(1, 3), (0, )]:
                    model.addConstrs((n.sum('*', d, h) <= bounds[i, 1]
                                      for d in day
                                      for h in home), "constr-(1,3), (0,)")
                elif constrList[i] == [(1, 3), (2, )]:
                    model.addConstrs((q.sum(d, '*', h) <= bounds[i, 1]
                                      for d in day
                                      for h in home), "constr-(1,3), (2,)")
                elif constrList[i] == [(1, 3), (0, 2)]:
                    model.addConstrs((x.sum('*', d, '*', h) <= bounds[i, 1]
                                      for d in day
                                      for h in home), "constr-(1,3), (0,2)")

                elif constrList[i] == [(2, 3), (0, )]:
                    model.addConstrs((p.sum('*', h, a) <= bounds[i, 1]
                                      for h in home
                                      for a in away), "constr-(2,3), (0,)")
                elif constrList[i] == [(2, 3), (1, )]:
                    model.addConstrs((q.sum('*', h, a) <= bounds[i, 1]
                                      for h in home
                                      for a in away), "constr-(2,3), (1,)")
                elif constrList[i] == [(2, 3), (0, 1)]:
                    model.addConstrs((x.sum('*', '*', h, a) <= bounds[i, 1]
                                      for h in home
                                      for a in away), "constr-(2,3), (0,1)")

                elif constrList[i] == [(0, 1, 2), (3, )]:
                    model.addConstrs((x.sum(c, d, a, '*') <= bounds[i, 1]
                                      for c in cycle for d in day
                                      for a in away), "constr-(0,1,2), (3,)")
                elif constrList[i] == [(0, 1, 3), (2, )]:
                    model.addConstrs((x.sum(c, d, '*', h) <= bounds[i, 1]
                                      for c in cycle for d in day
                                      for h in home), "constr-(0,1,3), (2,)")
                elif constrList[i] == [(0, 2, 3), (1, )]:
                    model.addConstrs((x.sum(c, '*', a, h) <= bounds[i, 1]
                                      for c in cycle for a in away
                                      for h in home), "constr-(0,2,3), (1,)")
                elif constrList[i] == [(1, 2, 3), (0, )]:
                    model.addConstrs((x.sum('*', d, a, h) <= bounds[i, 1]
                                      for d in day for a in away
                                      for h in home), "constr-(1,2,3), (0,)")

        if bounds[34, 5] + bounds[34, 4] > 0:
            # definition for the first day
            model.addConstrs((cNH[c, 0, 0, h] == n[c, 0, h] for c in cycle
                              for h in home), "cNH1")
            model.addConstrs((cNH[c, d1 + 1, 0, h] <= n[c, d1 + 1, h]
                              for c in cycle for h in home
                              for d1 in day if d1 < len(day) - 1), "cNA2")
            model.addConstrs((cNH[c, d1 + 1, 0, h] <= 1 - n[c, d1, h]
                              for c in cycle for h in home
                              for d1 in day if d1 < len(day) - 1), "cNA3")
            model.addConstrs(
                (cNH[c, d1 + 1, 0, h] >= n[c, d1 + 1, h] - n[c, d1, h]
                 for c in cycle for d1 in day
                 for h in home if d1 < len(day) - 1), "cNA4")

            # # definition for the second day and the third, fourth, etc...
            model.addConstrs((cNH[c, 0, d2, h] == 0 for c in cycle
                              for d2 in day for h in home if d2 > 0), "2cNA1")
            model.addConstrs((cNH[c, d1, d2, h] <= cNH[c, d1 - 1, d2 - 1, h]
                              for c in cycle for h in home for d1 in day
                              for d2 in day if d1 > 0 if d2 > 0))
            model.addConstrs((cNH[c, d1, d2, h] <= n[c, d1, h] for c in cycle
                              for d1 in day for d2 in day for h in home
                              if d1 > 0 if d2 > 0))
            model.addConstrs((cNH[c, d1, d2, h] >=
                              n[c, d1, h] + cNH[c, d1 - 1, d2 - 1, h] - 1
                              for c in cycle for d1 in day for d2 in day
                              for h in home if d1 > 0 if d2 > 0))
            if bounds[34, 5] > 0:
                model.addConstr((quicksum(
                    cNH[c, d1, d2, a] for c in cycle for d1 in day
                    for a in away
                    for d2 in range(bounds[34, 5].astype(int), len(day)))
                                 == 0), "cnASum")
            if bounds[34, 4] > 0:
                model.addConstrs((cNHs[c, 0, d2, h] == 0 for c in cycle
                                  for d2 in day for h in home), "minConsPlay")
                model.addConstrs((cNHs[c, d1, d2, h] <= cNH[c, d1 - 1, d2, h]
                                  for c in cycle for h in home for d1 in day
                                  for d2 in day if d1 > 0))
                model.addConstrs((cNHs[c, d1, d2, h] <= 1 - n[c, d1, h]
                                  for c in cycle for d1 in day for d2 in day
                                  for h in home if d1 > 0))
                model.addConstrs(
                    (cNHs[c, d1, d2, h] >= cNH[c, d1 - 1, d2, h] - n[c, d1, h]
                     for c in cycle for d1 in day for d2 in day for h in home
                     if d1 > 0))
                model.addConstrs((cNHs[c, num_md_per_cycle, d2, h] >=
                                  cNH[c, num_md_per_cycle - 1, d2, h]
                                  for c in cycle for d2 in day for h in home))
                model.addConstr((quicksum(
                    cNHs[c, d1, d2, a] * (bounds[34, 4] - 1 - d2)
                    for c in cycle for a in away for d1 in days
                    for d2 in range(bounds[34, 4].astype(int) - 1)) == 0))

        if bounds[31, 5] + bounds[31, 4] > 0:
            # definition for the first day
            model.addConstrs((cNA[c, 0, 0, a] == o[c, 0, a] for c in cycle
                              for a in away), "cNA1")
            model.addConstrs((cNA[c, d1 + 1, 0, a] <= o[c, d1 + 1, a]
                              for c in cycle for a in away
                              for d1 in day if d1 < len(day) - 1), "cNA2")
            model.addConstrs((cNA[c, d1 + 1, 0, a] <= 1 - o[c, d1, a]
                              for c in cycle for a in away
                              for d1 in day if d1 < len(day) - 1), "cNA3")
            model.addConstrs(
                (cNA[c, d1 + 1, 0, a] >= o[c, d1 + 1, a] - o[c, d1, a]
                 for c in cycle for d1 in day
                 for a in away if d1 < len(day) - 1), "cNA4")

            # # definition for the second day and the third, fourth, etc...
            model.addConstrs((cNA[c, 0, d2, a] == 0 for c in cycle
                              for d2 in day for a in away if d2 > 0), "2cNA1")
            model.addConstrs((cNA[c, d1, d2, a] <= cNA[c, d1 - 1, d2 - 1, a]
                              for c in cycle for a in away for d1 in day
                              for d2 in day if d1 > 0 if d2 > 0))
            model.addConstrs((cNA[c, d1, d2, a] <= o[c, d1, a] for c in cycle
                              for d1 in day for d2 in day for a in away
                              if d1 > 0 if d2 > 0))
            model.addConstrs((cNA[c, d1, d2, a] >=
                              o[c, d1, a] + cNA[c, d1 - 1, d2 - 1, a] - 1
                              for c in cycle for d1 in day for d2 in day
                              for a in away if d1 > 0 if d2 > 0))
            if bounds[31, 5] > 0:
                model.addConstr((quicksum(
                    cNA[c, d1, d2, a] for c in cycle for d1 in day
                    for a in away
                    for d2 in range(bounds[31, 5].astype(int), len(day)))
                                 == 0), "cnASum")
            if bounds[31, 4] > 0:
                model.addConstrs((cNAs[c, 0, d2, a] == 0 for c in cycle
                                  for d2 in day for a in away), "minConsPlay")
                model.addConstrs((cNAs[c, d1, d2, a] <= cNA[c, d1 - 1, d2, a]
                                  for c in cycle for a in away for d1 in day
                                  for d2 in day if d1 > 0))
                model.addConstrs((cNAs[c, d1, d2, a] <= 1 - o[c, d1, a]
                                  for c in cycle for d1 in day for d2 in day
                                  for a in away if d1 > 0))
                model.addConstrs(
                    (cNAs[c, d1, d2, a] >= cNA[c, d1 - 1, d2, a] - o[c, d1, a]
                     for c in cycle for d1 in day for d2 in day for a in away
                     if d1 > 0))
                model.addConstrs((cNAs[c, num_md_per_cycle, d2, a] >=
                                  cNA[c, num_md_per_cycle - 1, d2, a]
                                  for c in cycle for d2 in day for a in away))
                model.addConstr((quicksum(
                    cNAs[c, d1, d2, a] * (bounds[31, 4] - 1 - d2)
                    for c in cycle for a in away for d1 in days
                    for d2 in range(bounds[31, 4].astype(int) - 1)) == 0))

        # Sets the number of solutions to be generated
        model.setParam(GRB.Param.PoolSolutions, numSam)
        # grab the most optimal solutions
        model.setParam(GRB.Param.PoolSearchMode, 2)
        model.optimize()
        numSol = model.SolCount
        print("Number of solutions found for the model: " + str(numSol))

        if model.status == GRB.Status.INFEASIBLE:
            model.computeIIS()
            print("Following constraints are infeasible: ")
            for c in model.getConstrs():
                if c.IISConstr:
                    print(c.constrName)
        if model.status == GRB.Status.OPTIMAL:
            model.write('m.sol')
        for i in range(numSol):
            model.setParam(GRB.Param.SolutionNumber, i)
            # get value from subobtimal MIP sol (might change this in X if we dont do soft constraints)
            solution = model.getAttr('xn', x)

            tmp = np.zeros([numCycle, num_md_per_cycle, num_teams, num_teams])
            for key in solution:
                tmp[key] = round(solution[key])
            tmp_sol = tmp.astype(np.int64)
            with open(os.path.join(directory, "sol" + str(i) + ".csv"),
                      "w+",
                      newline='') as sol_csv:
                csv_writer = csv.writer(sol_csv, delimiter=',')

                # writes cycle row
                row = ['']
                for c in range(numCycle):
                    row.extend(['C' + str(c)] * num_md_per_cycle * num_teams)
                csv_writer.writerow(row)

                # writes round row
                row = ['']
                for c in range(numCycle):
                    for d in range(num_md_per_cycle):
                        row.extend(['R' + str(d)] * num_teams)
                csv_writer.writerow(row)

                # writes awayteam row
                row = ['']
                for c in range(numCycle):
                    for d in range(num_md_per_cycle):
                        for t in range(num_teams):
                            row.append('T' + str(t))
                csv_writer.writerow(row)

                # write the actual solution per team
                tmp_sol.astype(int)
                for t in range(num_teams):
                    row = ['T' + str(t)]
                    for c in range(numCycle):
                        for r in range(num_md_per_cycle):
                            for team in range(num_teams):
                                row.append(tmp_sol[c][r][t][team])
                    csv_writer.writerow(row)

    except GurobiError as e:
        raise e
Пример #7
0
def _optimize_gurobi(cobra_model,
                     new_objective=None,
                     objective_sense='maximize',
                     min_norm=0,
                     the_problem=None,
                     tolerance_optimality=1e-6,
                     tolerance_feasibility=1e-6,
                     tolerance_barrier=None,
                     tolerance_integer=1e-9,
                     error_reporting=None,
                     print_solver_time=False,
                     copy_problem=False,
                     lp_method=0,
                     relax_b=None,
                     quad_precision=False,
                     quadratic_component=None,
                     reuse_basis=True,
                     lp_parallel=None,
                     update_problem_reaction_bounds=True):
    """Uses the gurobi (http://gurobi.com) optimizer to perform an optimization on cobra_model
    for the objective_coefficients in cobra_model._objective_coefficients based
    on objective sense.

    cobra_model: A cobra.Model object

    new_objective: Reaction, String, or Integer referring to a reaction in
    cobra_model.reactions to set as the objective.  Currently, only supports single
    objective coeffients.  Will expand to include mixed objectives.

    objective_sense: 'maximize' or 'minimize'

    min_norm: not implemented

    the_problem: None or a problem object for the specific solver that can be used to hot
    start the next solution.

    tolerance_optimality: Solver tolerance for optimality.

    tolerance_feasibility: Solver tolerance for feasibility.

    quad_precision: Boolean.  Whether or not to used quad precision in calculations

    error_reporting: None or True to disable or enable printing errors encountered
    when trying to find the optimal solution.
    
    print_solver_time: False or True.  Indicates if the time to calculate the solution
    should be displayed.


    quadratic_component: None or 
          scipy.sparse.dok of dim(len(cobra_model.reactions),len(cobra_model.reactions))
         If not None:
          Solves quadratic programming problems for cobra_models of the form:
          minimize: 0.5 * x' * quadratic_component * x + cobra_model._objective_coefficients' * x
          such that,
            cobra_model._lower_bounds <= x <= cobra_model._upper_bounds
            cobra_model._S * x (cobra_model._constraint_sense) cobra_model._b

            NOTE: When solving quadratic problems it may be necessary to disable quad_precision
            and use lp_method = 0 for gurobi.

    reuse_basis: Boolean.  If True and the_problem is a model object for the solver,
    attempt to hot start the solution.

    update_problem_reaction_bounds: Boolean.  Set to True if you're providing the_problem
    and you've modified reaction bounds on your cobra_model since creating the_problem.  Only
    necessary for CPLEX
    
    lp_parallel: Not implemented

    lp.optimize() with Salmonella model:
         cold start: 0.063 seconds
         hot start: 0.057 seconds (Slow due to copying the LP)
         

    """
    if relax_b is not None:
        raise Exception('Need to reimplement constraint relaxation')
    from numpy import array, nan, zeros
    #TODO: speed this up
    if objective_sense == 'maximize':
        objective_sense = -1
    else:
        objective_sense = 1
    from gurobipy import Model, LinExpr, GRB, QuadExpr
    sense_dict = {'E': GRB.EQUAL, 'L': GRB.LESS_EQUAL, 'G': GRB.GREATER_EQUAL}
    from cobra.flux_analysis.objective import update_objective
    from cobra.solvers.legacy import status_dict, variable_kind_dict

    variable_kind_dict = eval(variable_kind_dict['gurobi'])
    status_dict = eval(status_dict['gurobi'])

    #Update objectives if they are new.
    if new_objective and new_objective != 'update problem':
        update_objective(cobra_model, new_objective)
    #Create a new problem
    if not the_problem or the_problem in ['return', 'setup'] or \
           not isinstance(the_problem, Model):
        lp = Model("cobra")
        lp.Params.OutputFlag = 0
        lp.Params.LogFile = ''
        # Create variables
        #TODO:  Speed this up
        variable_list = [
            lp.addVar(lb=float(x.lower_bound),
                      ub=float(x.upper_bound),
                      obj=objective_sense * float(x.objective_coefficient),
                      name=x.id,
                      vtype=variable_kind_dict[x.variable_kind])
            for x in cobra_model.reactions
        ]
        reaction_to_variable = dict(zip(cobra_model.reactions, variable_list))
        # Integrate new variables
        lp.update()
        #Set objective to quadratic program
        if quadratic_component is not None:
            if not hasattr(quadratic_component, 'todok'):
                raise Exception(
                    'quadratic component must be a scipy.sparse type array')

            quadratic_objective = QuadExpr()
            for (index_0,
                 index_1), the_value in quadratic_component.todok().items():
                quadratic_objective.addTerms(the_value, variable_list[index_0],
                                             variable_list[index_1])
            lp.setObjective(quadratic_objective, sense=objective_sense)
        #Constraints are based on mass balance
        #Construct the lin expression lists and then add
        #TODO: Speed this up as it takes about .18 seconds
        #HERE
        for the_metabolite in cobra_model.metabolites:
            constraint_coefficients = []
            constraint_variables = []
            for the_reaction in the_metabolite._reaction:
                constraint_coefficients.append(
                    the_reaction._metabolites[the_metabolite])
                constraint_variables.append(reaction_to_variable[the_reaction])
            #Add the metabolite to the problem
            lp.addConstr(
                LinExpr(constraint_coefficients, constraint_variables),
                sense_dict[the_metabolite._constraint_sense.upper()],
                the_metabolite._bound, the_metabolite.id)
    else:
        #When reusing the basis only assume that the objective coefficients or bounds can change
        if copy_problem:
            lp = the_problem.copy()
        else:
            lp = the_problem
        if not reuse_basis:
            lp.reset()
        for the_variable, the_reaction in zip(lp.getVars(),
                                              cobra_model.reactions):
            the_variable.lb = float(the_reaction.lower_bound)
            the_variable.ub = float(the_reaction.upper_bound)
            the_variable.obj = float(objective_sense *
                                     the_reaction.objective_coefficient)

    if the_problem == 'setup':
        return lp
    if print_solver_time:
        start_time = time()
    lp.update()
    lp.setParam("FeasibilityTol", tolerance_feasibility)
    lp.setParam("OptimalityTol", tolerance_optimality)
    if tolerance_barrier:
        lp.setParam("BarConvTol", tolerance_barrier)

    if quad_precision:
        lp.setParam("Quad", 1)
    lp.setParam("Method", lp_method)

    #Different methods to try if lp_method fails
    the_methods = [0, 2, 1]
    if lp_method in the_methods:
        the_methods.remove(lp_method)
    if not isinstance(the_problem, Model):
        lp.optimize()
        if lp.status in status_dict:
            status = status_dict[lp.status]
        else:
            status = 'failed'
        if status != 'optimal':
            #Try to find a solution using a different method
            lp.setParam("MarkowitzTol", 1e-2)
            for lp_method in the_methods:
                lp.setParam("Method", lp_method)
                lp.optimize()
                if status_dict[lp.status] == 'optimal':
                    break
    else:
        lp.setParam("TimeLimit", 0.6)
        lp.optimize()
        lp.setParam("TimeLimit", "default")
        if lp.status in status_dict:
            status = status_dict[lp.status]
        else:
            status = 'failed'
        if status != 'optimal':
            lp.setParam("MarkowitzTol", 1e-2)
            #Try to find a solution using a different method
            for lp_method in the_methods:
                lp.setParam("Method", lp_method)
                lp.optimize()
                if status_dict[lp.status] == 'optimal':
                    break

            if status_dict[lp.status] != 'optimal':
                lp = optimize_gurobi(
                    cobra_model,
                    new_objective=new_objective,
                    objective_sense=objective_sense,
                    min_norm=min_norm,
                    the_problem=None,
                    print_solver_time=print_solver_time)['the_problem']

    if print_solver_time:
        print 'optimize time: %f' % (time() - start_time)
    x_dict = {}
    y_dict = {}
    y = None
    if lp.status in status_dict:
        status = status_dict[lp.status]
    else:
        status = 'failed'
    if status == 'optimal':
        objective_value = objective_sense * lp.ObjVal
        [x_dict.update({v.VarName: v.X}) for v in lp.getVars()]
        x = array([x_dict[v.id] for v in cobra_model.reactions])
        if lp.isMIP:
            y = y_dict = None  #MIP's don't have duals
        else:
            [y_dict.update({c.ConstrName: c.Pi}) for c in lp.getConstrs()]
            y = array([y_dict[v.id] for v in cobra_model.metabolites])
    else:
        y = y_dict = x = x_dict = None
        objective_value = None
        if error_reporting:
            print 'gurobi failed: %s' % lp.status
    cobra_model.solution = the_solution = Solution(objective_value,
                                                   x=x,
                                                   x_dict=x_dict,
                                                   y=y,
                                                   y_dict=y_dict,
                                                   status=status)
    solution = {'the_problem': lp, 'the_solution': the_solution}
    return solution
Пример #8
0
def from_gurobipy(model: Model) -> QuadraticProgram:
    """Translate a gurobipy model into a quadratic program.

    Note that this supports only basic functions of gurobipy as follows:
    - quadratic objective function
    - linear / quadratic constraints
    - binary / integer / continuous variables

    Args:
        model: The gurobipy model to be loaded.

    Returns:
        The quadratic program corresponding to the model.

    Raises:
        QiskitOptimizationError: if the model contains unsupported elements.
        MissingOptionalLibraryError: if gurobipy is not installed.
    """

    _check_gurobipy_is_installed("from_gurobipy")

    if not isinstance(model, Model):
        raise QiskitOptimizationError(f"The model is not compatible: {model}")

    quadratic_program = QuadraticProgram()

    # Update the model to make sure everything works as expected
    model.update()

    # get name
    quadratic_program.name = model.ModelName

    # get variables
    # keep track of names separately, since gurobipy allows to have None names.
    var_names = {}
    for x in model.getVars():
        if x.vtype == gp.GRB.CONTINUOUS:
            x_new = quadratic_program.continuous_var(x.lb, x.ub, x.VarName)
        elif x.vtype == gp.GRB.BINARY:
            x_new = quadratic_program.binary_var(x.VarName)
        elif x.vtype == gp.GRB.INTEGER:
            x_new = quadratic_program.integer_var(x.lb, x.ub, x.VarName)
        else:
            raise QiskitOptimizationError(
                f"Unsupported variable type: {x.VarName} {x.vtype}")
        var_names[x] = x_new.name

    # objective sense
    minimize = model.ModelSense == gp.GRB.MINIMIZE

    # Retrieve the objective
    objective = model.getObjective()
    has_quadratic_objective = False

    # Retrieve the linear part in case it is a quadratic objective
    if isinstance(objective, gp.QuadExpr):
        linear_part = objective.getLinExpr()
        has_quadratic_objective = True
    else:
        linear_part = objective

    # Get the constant
    constant = linear_part.getConstant()

    # get linear part of objective
    linear = {}
    for i in range(linear_part.size()):
        linear[var_names[linear_part.getVar(i)]] = linear_part.getCoeff(i)

    # get quadratic part of objective
    quadratic = {}
    if has_quadratic_objective:
        for i in range(objective.size()):
            x = var_names[objective.getVar1(i)]
            y = var_names[objective.getVar2(i)]
            v = objective.getCoeff(i)
            quadratic[x, y] = v

    # set objective
    if minimize:
        quadratic_program.minimize(constant, linear, quadratic)
    else:
        quadratic_program.maximize(constant, linear, quadratic)

    # check whether there are any general constraints
    if model.NumSOS > 0 or model.NumGenConstrs > 0:
        raise QiskitOptimizationError(
            "Unsupported constraint: SOS or General Constraint")

    # get linear constraints
    for constraint in model.getConstrs():
        name = constraint.ConstrName
        sense = constraint.Sense

        left_expr = model.getRow(constraint)
        rhs = constraint.RHS

        lhs = {}
        for i in range(left_expr.size()):
            lhs[var_names[left_expr.getVar(i)]] = left_expr.getCoeff(i)

        if sense == gp.GRB.EQUAL:
            quadratic_program.linear_constraint(lhs, "==", rhs, name)
        elif sense == gp.GRB.GREATER_EQUAL:
            quadratic_program.linear_constraint(lhs, ">=", rhs, name)
        elif sense == gp.GRB.LESS_EQUAL:
            quadratic_program.linear_constraint(lhs, "<=", rhs, name)
        else:
            raise QiskitOptimizationError(
                f"Unsupported constraint sense: {constraint}")

    # get quadratic constraints
    for constraint in model.getQConstrs():
        name = constraint.QCName
        sense = constraint.QCSense

        left_expr = model.getQCRow(constraint)
        rhs = constraint.QCRHS

        linear = {}
        quadratic = {}

        linear_part = left_expr.getLinExpr()
        for i in range(linear_part.size()):
            linear[var_names[linear_part.getVar(i)]] = linear_part.getCoeff(i)

        for i in range(left_expr.size()):
            x = var_names[left_expr.getVar1(i)]
            y = var_names[left_expr.getVar2(i)]
            v = left_expr.getCoeff(i)
            quadratic[x, y] = v

        if sense == gp.GRB.EQUAL:
            quadratic_program.quadratic_constraint(linear, quadratic, "==",
                                                   rhs, name)
        elif sense == gp.GRB.GREATER_EQUAL:
            quadratic_program.quadratic_constraint(linear, quadratic, ">=",
                                                   rhs, name)
        elif sense == gp.GRB.LESS_EQUAL:
            quadratic_program.quadratic_constraint(linear, quadratic, "<=",
                                                   rhs, name)
        else:
            raise QiskitOptimizationError(
                f"Unsupported constraint sense: {constraint}")

    return quadratic_program
Пример #9
0
def _optimize_gurobi(cobra_model, new_objective=None, objective_sense='maximize',
                    min_norm=0, the_problem=None,
                    tolerance_optimality=1e-6, tolerance_feasibility=1e-6,
                    tolerance_barrier=None, tolerance_integer=1e-9, error_reporting=None,
                    print_solver_time=False, copy_problem=False, lp_method=0,
                    relax_b=None, quad_precision=False, quadratic_component=None,
                    reuse_basis=True, lp_parallel=None, update_problem_reaction_bounds=True):
    """Uses the gurobi (http://gurobi.com) optimizer to perform an optimization on cobra_model
    for the objective_coefficients in cobra_model._objective_coefficients based
    on objective sense.

    cobra_model: A cobra.Model object

    new_objective: Reaction, String, or Integer referring to a reaction in
    cobra_model.reactions to set as the objective.  Currently, only supports single
    objective coeffients.  Will expand to include mixed objectives.

    objective_sense: 'maximize' or 'minimize'

    min_norm: not implemented

    the_problem: None or a problem object for the specific solver that can be used to hot
    start the next solution.

    tolerance_optimality: Solver tolerance for optimality.

    tolerance_feasibility: Solver tolerance for feasibility.

    quad_precision: Boolean.  Whether or not to used quad precision in calculations

    error_reporting: None or True to disable or enable printing errors encountered
    when trying to find the optimal solution.
    
    print_solver_time: False or True.  Indicates if the time to calculate the solution
    should be displayed.


    quadratic_component: None or 
          scipy.sparse.dok of dim(len(cobra_model.reactions),len(cobra_model.reactions))
         If not None:
          Solves quadratic programming problems for cobra_models of the form:
          minimize: 0.5 * x' * quadratic_component * x + cobra_model._objective_coefficients' * x
          such that,
            cobra_model._lower_bounds <= x <= cobra_model._upper_bounds
            cobra_model._S * x (cobra_model._constraint_sense) cobra_model._b

            NOTE: When solving quadratic problems it may be necessary to disable quad_precision
            and use lp_method = 0 for gurobi.

    reuse_basis: Boolean.  If True and the_problem is a model object for the solver,
    attempt to hot start the solution.

    update_problem_reaction_bounds: Boolean.  Set to True if you're providing the_problem
    and you've modified reaction bounds on your cobra_model since creating the_problem.  Only
    necessary for CPLEX
    
    lp_parallel: Not implemented

    lp.optimize() with Salmonella model:
         cold start: 0.063 seconds
         hot start: 0.057 seconds (Slow due to copying the LP)
         

    """
    if relax_b is not None:
        raise Exception('Need to reimplement constraint relaxation')
    from numpy import array, nan, zeros
    #TODO: speed this up
    if objective_sense == 'maximize':
        objective_sense = -1
    else:
        objective_sense = 1
    from gurobipy import Model, LinExpr, GRB, QuadExpr
    sense_dict = {'E': GRB.EQUAL,
                  'L': GRB.LESS_EQUAL,
                  'G': GRB.GREATER_EQUAL}
    from cobra.flux_analysis.objective import update_objective
    from cobra.solvers.legacy import status_dict, variable_kind_dict

    variable_kind_dict = eval(variable_kind_dict['gurobi'])
    status_dict = eval(status_dict['gurobi'])

    #Update objectives if they are new.
    if new_objective and new_objective != 'update problem':
       update_objective(cobra_model, new_objective)
    #Create a new problem
    if not the_problem or the_problem in ['return', 'setup'] or \
           not isinstance(the_problem, Model):
        lp = Model("cobra")
        lp.Params.OutputFlag = 0
        lp.Params.LogFile = ''
        # Create variables
        #TODO:  Speed this up 
        variable_list = [lp.addVar(lb=float(x.lower_bound),
                                   ub=float(x.upper_bound),
                                   obj=objective_sense*float(x.objective_coefficient),
                                   name=x.id,
                                   vtype=variable_kind_dict[x.variable_kind])
                         for x in cobra_model.reactions]
        reaction_to_variable = dict(zip(cobra_model.reactions,
                                        variable_list))
        # Integrate new variables
        lp.update()
        #Set objective to quadratic program
        if quadratic_component is not None:
            if not hasattr(quadratic_component, 'todok'):
                raise Exception('quadratic component must be a scipy.sparse type array')

            quadratic_objective = QuadExpr()
            for (index_0, index_1), the_value in quadratic_component.todok().items():
                quadratic_objective.addTerms(the_value,
                                       variable_list[index_0],
                                       variable_list[index_1])
            lp.setObjective(quadratic_objective, sense=objective_sense)
        #Constraints are based on mass balance
        #Construct the lin expression lists and then add
        #TODO: Speed this up as it takes about .18 seconds
        #HERE
        for the_metabolite in cobra_model.metabolites:
            constraint_coefficients = []
            constraint_variables = []
            for the_reaction in the_metabolite._reaction:
                constraint_coefficients.append(the_reaction._metabolites[the_metabolite])
                constraint_variables.append(reaction_to_variable[the_reaction])
            #Add the metabolite to the problem
            lp.addConstr(LinExpr(constraint_coefficients, constraint_variables),
                         sense_dict[the_metabolite._constraint_sense.upper()],
                         the_metabolite._bound,
                         the_metabolite.id)
    else:
        #When reusing the basis only assume that the objective coefficients or bounds can change
        if copy_problem:
            lp = the_problem.copy()
        else:
            lp = the_problem
        if not reuse_basis:
            lp.reset()
        for the_variable, the_reaction in zip(lp.getVars(),
                                              cobra_model.reactions):
            the_variable.lb = float(the_reaction.lower_bound)
            the_variable.ub = float(the_reaction.upper_bound)
            the_variable.obj = float(objective_sense*the_reaction.objective_coefficient)

    
    if the_problem == 'setup':
        return lp
    if print_solver_time:
        start_time = time()
    lp.update()
    lp.setParam("FeasibilityTol", tolerance_feasibility)
    lp.setParam("OptimalityTol", tolerance_optimality) 
    if tolerance_barrier:
        lp.setParam("BarConvTol", tolerance_barrier)

    if quad_precision:
            lp.setParam("Quad", 1)
    lp.setParam("Method", lp_method)

    #Different methods to try if lp_method fails
    the_methods = [0, 2, 1]
    if lp_method in the_methods:
        the_methods.remove(lp_method)
    if not isinstance(the_problem, Model):
        lp.optimize()
        if lp.status in status_dict:
            status = status_dict[lp.status]
        else:
            status = 'failed'
        if status != 'optimal':
            #Try to find a solution using a different method
            lp.setParam("MarkowitzTol", 1e-2)
            for lp_method in the_methods:
                lp.setParam("Method", lp_method)
                lp.optimize()
                if status_dict[lp.status] == 'optimal':
                    break
    else:
        lp.setParam("TimeLimit", 0.6)
        lp.optimize()
        lp.setParam("TimeLimit", "default")
        if lp.status in status_dict:
            status = status_dict[lp.status]
        else:
            status = 'failed'
        if status != 'optimal':
            lp.setParam("MarkowitzTol", 1e-2)
            #Try to find a solution using a different method
            for lp_method in the_methods:
                lp.setParam("Method", lp_method)
                lp.optimize()
                if status_dict[lp.status] == 'optimal':
                    break
                
            if status_dict[lp.status] != 'optimal':
                lp = optimize_gurobi(cobra_model, new_objective=new_objective, objective_sense=objective_sense,
                                     min_norm=min_norm, the_problem=None, 
                                     print_solver_time=print_solver_time)['the_problem']


    if print_solver_time:
        print 'optimize time: %f'%(time() - start_time)
    x_dict = {}
    y_dict = {}
    y = None
    if lp.status in status_dict:
        status = status_dict[lp.status]
    else:
        status = 'failed'
    if status == 'optimal':
        objective_value = objective_sense*lp.ObjVal
        [x_dict.update({v.VarName: v.X}) for v in lp.getVars()]
        x = array([x_dict[v.id] for v in cobra_model.reactions])
        if lp.isMIP:
            y = y_dict = None #MIP's don't have duals
        else:
            [y_dict.update({c.ConstrName: c.Pi})
             for c in lp.getConstrs()]
            y = array([y_dict[v.id] for v in cobra_model.metabolites])
    else:
        y = y_dict = x = x_dict = None
        objective_value = None
        if error_reporting:
            print 'gurobi failed: %s'%lp.status  
    the_solution = Solution(objective_value, x=x, x_dict=x_dict,
                            y=y, y_dict=y_dict,
                            status=status)
    solution = {'the_problem': lp, 'the_solution': the_solution}
    return solution
Пример #10
0
def _sensitivity_for_constraints(AT, j, project, y_, project_activity, M):
    global _round, _pa_dataset
    m = Model("SingleProject_%d_for_sensitivity" % j)
    m.setParam('OutputFlag', False)
    # m.params.IntFeasTol = 1e-7

    ## Project complete data,Project Tadeness,construction completion time
    CT = m.addVar(obj=0, vtype=GRB.CONTINUOUS, name="CT_%d" % j)

    ## Activity start time
    ST = {}
    project_activities = project_activity[project]
    for row in project_activities.nodes():
        ST[row] = m.addVar(obj=0, vtype=GRB.CONTINUOUS, name="ST_%d_%s" % (j, row))

    ## Review sequence z_ij
    ## move to annealing objective function

    m.update()

    ## Constrain 8: activity starting constrain
    # equation 20
    for a in project_activities.nodes():
        for r in project_activities.node[a]['resources']:
            m.addConstr(ST[a], GRB.GREATER_EQUAL, AT[j, r],
                        name="constraint_8_project_%d_activity_%s_resource_%s" % (j, a, r))

    ## Constrain 9 activity sequence constrain
    # equation 21
    for row1, row2 in project_activities.edges():
        m.addConstr(ST[row1] + project_activities.node[row1]['duration'], GRB.LESS_EQUAL,
                    ST[row2], name="constraint_9_project_%d_activity_%s_activity_%s" % (j, row1, row2))

    ## Constrain 10,11
    for row1 in project_activities.nodes():
        for row2 in project_activities.nodes():
            if row1 != row2 and len(list(
                    set(project_activities.node[row1]['rk_resources']).intersection(
                        project_activities.node[row2]['rk_resources']))) > 0:
                # equation 22
                m.addConstr(ST[row1] + project_activities.node[row1]['duration'] - M * (
                    1 - _get_y_for_activities(y_, row1, row2)), GRB.LESS_EQUAL, ST[row2],
                            name="constraint_10_project_%d_activity_%s_activity_%s" % (j, row1, row2))
                # equation 23
                m.addConstr(
                    ST[row2] + project_activities.node[row2]['duration'] - M * _get_y_for_activities(y_, row1, row2),
                    GRB.LESS_EQUAL, ST[row1],
                    name="constraint_11_project_%d_activity_%s_activity_%s" % (j, row1, row2))
                # m.addConstr(y[j,row1,row2]+y[j,row2,row1],GRB.LESS_EQUAL,1)

    ## Constrain 12
    # equation 24
    for row in project_activities.nodes():
        m.addConstr(CT, GRB.GREATER_EQUAL, ST[row] + project_activities.node[row]['duration'],
                    name="constraint_12_project_%d_activity_%s" % (j, row))

    m.update()

    # Set optimization objective - minimize completion time
    expr = LinExpr()
    expr.add(CT)
    m.setObjective(expr, GRB.MINIMIZE)
    m.update()
    ##########################################
    # m.params.presolve = 1
    m.update()
    m.setParam(GRB.Param.Method, 0)
    m.update()
    # Solve
    # m.params.presolve=0

    m.optimize()

    _skja = {}
    for c in m.getConstrs():
        if c.ConstrName.startswith('constraint_8_project'):
            splits = c.ConstrName.split('_')
            r = splits[7]
            if r not in _skja:
                _skja[r] = []
            _skja[r].append(c.Pi)

            # if c.Pi != 0:
            #     logging.debug('project %d binding resource:%s Pi:%.4g' % (j, splits[-1], c.Pi))
            # else:
            #     logging.debug('project %d not binding resource:%s Pi:%.4g' % (j, splits[-1], c.Pi))

            _pa_dataset.loc[_pa_dataset.shape[0]] = [_round, j, r, splits[5], c.Pi]
    _skj = {}
    for r in _skja:
        _skj[j, r] = max(_skja[r])
        _pa_max_dataset.loc[_pa_max_dataset.shape[0]] = [_round, j, r, max(_skja[r])]
    return _skj
Пример #11
0
def _sensitivity_analysis_for_tardiness(z, CT, D):
    m = Model("model_for_sensitivity_analysis_for_tardiness")
    m.setParam('OutputFlag', False)
    # m.params.IntFeasTol = 1e-7
    DT = {}
    TD = {}
    for j in range(D.project_n):
        ## Project Tadeness,construction completion time
        DT[j] = m.addVar(obj=0, vtype=GRB.CONTINUOUS, name="DT_%d" % j)
        TD[j] = m.addVar(obj=0, vtype=GRB.CONTINUOUS, name="TD_%d" % j)

    DT[-1] = m.addVar(obj=0, vtype=GRB.CONTINUOUS, name="DT_-1")
    m.update();

    #### Add Constraint ####
    ## Constrain 2: project complete data>due data ##
    # equation 17
    for j in range(D.project_n):
        m.addConstr(DT[j] - TD[j], GRB.LESS_EQUAL, D.DD[j], name="constraint_2_project_%d" % j)

    ## Constraint 13
    # equation 12
    for j in range(D.project_n):
        m.addConstr(DT[j], GRB.GREATER_EQUAL, CT[j] + D.review_duration[j],
                    name="constraint_13_project_%d" % j)

    ## Constraint 14
    # equation 13
    for i in range(-1, D.project_n):
        for j in range(D.project_n):
            if i != j:
                m.addConstr(DT[j], GRB.GREATER_EQUAL, DT[i] - D.M * (1 - z[i, j]) + D.review_duration[j],
                            name="constraint_14_project_%d_project_%d" % (i, j))

    m.update()

    # Set optimization objective - minimize sum of
    expr = LinExpr()
    for j in range(D.project_n):
        expr.add(D.w[j] * TD[j])
    m.setObjective(expr, GRB.MINIMIZE)
    m.update()

    # m.params.presolve = 1
    m.update()

    m.optimize()

    # _logger.info("mm binding info:")
    sj = {}
    for c in m.getConstrs():
        if c.ConstrName.startswith('constraint_13'):
            j = int(c.ConstrName.split('_')[-1])
            # if c.Pi != 0:
            # sj[j] = 1
            # _logger.info('%s binding Pi:%.4g' % (c.ConstrName, c.Pi))
            # pass
            # else:
            # sj[j] = 0
            # _logger.info('%s not binding Pi:%.4g' % (c.ConstrName, c.Pi))
            # pass
            sj[j] = c.Pi
    return sj
Пример #12
0
def optmize_single_project(AT, j, project_list, project_activity, M):
    m = Model("SingleProject_%d" % j)
    m.setParam(GRB.Param.Method, 0)
    m.update()

    #### Create variables ####
    project = project_list[j]

    ## Project complete data,Project Tadeness,construction completion time
    CT = m.addVar(obj=0, vtype=GRB.CONTINUOUS, name="(CT%d)" % j)

    ## Activity start time
    ST = {}
    project_activities = project_activity[project]
    # print(project_activities.nodes())
    for row in project_activities.nodes():
        ST[row] = m.addVar(obj=0, vtype=GRB.CONTINUOUS, name="(ST%d,%s)" % (j, row))

    ## Review sequence z_ij
    ## move to annealing objective function

    # y
    y = {}
    for activity_i in project_activities.nodes():
        for activity_j in project_activities.nodes():
            # print(project_activities.node[activity_i])
            # print(dir(project_activities.node[activity_i]))
            if activity_i != activity_j and len(list(
                    set(project_activities.node[activity_i]['rk_resources']).intersection(
                        project_activities.node[activity_j]['rk_resources']))) > 0:
                y[activity_i, activity_j] = m.addVar(obj=0, vtype=GRB.BINARY,
                                                     name="(y%d,%s,%s)" % (j, activity_i, activity_j))
    m.update()

    #### Create constrains ####
    ## Constrain 2: project complete data>due data
    ## move to annealing objective function

    ## Constrain 3: supplier capacity limit
    ## move to annealing neighbor & random generator

    ## Constrain 4,6: project demand require; each project receive from one supplier for each resource
    ## move to annealing neighbor & random generator

    ## constrain 5: shipping constrain
    ## move to annealing neighbor & random generator

    ## Constrain 7:budget limit
    ## move to annealing constraint valid

    ## Constrain 8: activity starting constrain
    for a in project_activities.nodes():
        for r in project_activities.node[a]['resources']:
            m.addConstr(AT[j, r], GRB.LESS_EQUAL, ST[a],
                        name="constraint_8_project_%d_activity_%s_resource_%s" % (j, a, r))

    ## Constrain 9 activity sequence constrain
    for row1, row2 in project_activities.edges():
        m.addConstr(ST[row1] + project_activities.node[row1]['duration'], GRB.LESS_EQUAL,
                    ST[row2], name="constraint_9_project_%d_activity_%s_activity_%s" % (j, row1, row2))

    ## Constrain 10,11
    for row1 in project_activities.nodes():
        for row2 in project_activities.nodes():
            if row1 != row2 and len(list(
                    set(project_activities.node[row1]['rk_resources']).intersection(
                        project_activities.node[row2]['rk_resources']))) > 0:
                m.addConstr(ST[row1] + project_activities.node[row1]['duration'] - M * (
                    1 - y[row1, row2]), GRB.LESS_EQUAL, ST[row2],
                            name="constraint_10_project_%d_activity_%s_activity_%s" % (j, row1, row2))
                m.addConstr(
                    ST[row2] + project_activities.node[row2]['duration'] - M * (y[row1, row2]),
                    GRB.LESS_EQUAL, ST[row1],
                    name="constraint_11_project_%d_activity_%s_activity_%s" % (j, row1, row2))
                # m.addConstr(y[j,row1,row2]+y[j,row2,row1],GRB.LESS_EQUAL,1)

    ## Constrain 12
    for row in project_activities.nodes():
        m.addConstr(CT, GRB.GREATER_EQUAL, ST[row] + project_activities.node[row]['duration'],
                    name="constraint_12_project_%d_activity_%s" % (j, row))

    ## Constrain 13
    ## move to anealing objective function

    ## Constrain 14
    ## move to anealing objective function

    ## Constrain 15
    ## move to anealing objective function

    ## Constrain 16
    ## move to anealing objective function

    ## Constrain 17
    ## move to anealing objective function

    m.update()

    # Set optimization objective - minimize completion time
    expr = LinExpr()
    expr.add(CT)
    m.setObjective(expr, GRB.MINIMIZE)
    m.update()
    ##########################################
    m.params.presolve = 1
    m.update()
    # Solve
    # m.params.presolve=0

    m.optimize()
    # m.write(join(output_dir, "heuristic_%d.lp" % j))
    # m.write(join(output_dir, "heuristic_%d.sol" % j))
    # logging.info("project %d with optimalVal %r" % (j, m.objVal))
    print(m.status == GRB.OPTIMAL)
    for c in m.getConstrs():
        if c.ConstrName.startswith('constraint_8_project'):
            c.getAttr(GRB.Attr.SARHSLow)
            logging.info('%s shadow price (%f,%f)' % (c.ConstrName, c.SARHSLow, c.SARHSUp))
    return m.objVal
Пример #13
0
def generatesSample(
    num_days,
    num_shifts,
    num_nurses,
    numSam,
    bounds,
    constrList,
    partial_sol,
    x_mapping,
    y_mapping,
    gid,
):

    N = list(range(num_nurses))
    D = list(range(num_days))
    Ds = list(range(num_days + 1))
    S = list(range(num_shifts))
    Ss = list(range(num_shifts + 1))
    #    Sk=list(range(2))

    #    constrList=[[(0,),(1,)],[(0,),(2,)],[(0,),(1,2)],[(1,),(0,)],[(1,),(2,)],[(1,),(0,2)],[(2,),(0,)],[(2,),(1,)],[(2,),(0,1)],[(0,1),(2,)],[(0,2),(1,)],[(1,2),(0,)]]

    try:
        sys.stdout = open(os.devnull, "w")
        m = Model("nspSolver")
        sys.stdout = sys.__stdout__
        m.setParam(GRB.Param.OutputFlag, 0)
        ########### Decision Variables #############
        #        x = m.addVars(N,D,S,Sk, vtype=GRB.BINARY, name="x")
        o = m.addVars(N, D, S, vtype=GRB.BINARY, name="o")
        p = m.addVars(N, D, vtype=GRB.BINARY, name="p")
        q = m.addVars(N, S, vtype=GRB.BINARY, name="q")
        r = m.addVars(S, D, vtype=GRB.BINARY, name="r")

        tw = m.addVars(N, D, D, vtype=GRB.BINARY, name="tw")
        sw = m.addVars(N, Ds, D, vtype=GRB.BINARY, name="sw")
        tw1 = m.addVars(N, D, S, D, vtype=GRB.BINARY, name="tw1")
        sw1 = m.addVars(N, Ds, S, D, vtype=GRB.BINARY, name="sw1")

        tws = m.addVars(N, S, S, vtype=GRB.BINARY, name="tws")
        sws = m.addVars(N, Ss, S, vtype=GRB.BINARY, name="sws")
        tfs = m.addVars(N, S, S, vtype=GRB.BINARY, name="tfs")
        sfs = m.addVars(N, Ss, S, vtype=GRB.BINARY, name="sfs")

        tf = m.addVars(N, D, D, vtype=GRB.BINARY, name="tf")
        sf = m.addVars(N, Ds, D, vtype=GRB.BINARY, name="sf")
        tw1f = m.addVars(N, D, S, D, vtype=GRB.BINARY, name="tw1f")
        sw1f = m.addVars(N, Ds, S, D, vtype=GRB.BINARY, name="sw1f")

        ########### Required Constraints #############
        for n in N:
            for d in D:
                for s in S:
                    if not np.isnan(partial_sol[n, d, s]):
                        m.addConstr((o[n, d, s] == partial_sol[n, d, s]),
                                    "partial solution")

        m.addConstrs((o.sum(n, d, "*") == p[n, d] for n in N for d in D), "po")

        #        m.addConstrs((x.sum(n,d,s,'*')==o[n,d,s] for n in N for d in D for s in S),"xo")
        #        m.addConstrs((x[n,d,s,sk]==o[n,d,s] for n in N for d in D for s in S for sk in Sk if nurse_skill[n]==sk),"xo")
        #        m.addConstrs((x[n,d,s,sk]==0 for n in N for d in D for s in S for sk in Sk if nurse_skill[n]!=sk),"xo")
        m.addConstrs((q[n, s] <= o.sum(n, "*", s) for n in N for s in S), "qo")
        m.addConstrs((q[n, s] * o.sum(n, "*", s) == o.sum(n, "*", s) for n in N
                      for s in S), "qo")
        m.addConstrs((r[s, d] <= o.sum("*", d, s) for d in D for s in S), "ro")
        m.addConstrs((r[s, d] * o.sum("*", d, s) == o.sum("*", d, s) for d in D
                      for s in S), "ro")

        ########### Hard Constraints #############
        #        print(bounds)
        for i in range(len(bounds)):
            if bounds[i, 0] > 0:
                #                print(bounds[i,0])
                if constrList[i] == "0:1":
                    m.addConstrs((r.sum("*", d) >= bounds[i, 0] for d in D),
                                 "constr")

                elif constrList[i] == "0:2":
                    m.addConstrs((p.sum("*", d) >= bounds[i, 0] for d in D),
                                 "constr")

                elif constrList[i] == "0:1,2":
                    m.addConstrs((o.sum("*", d, "*") >= bounds[i, 0]
                                  for d in D), "constr")

                elif constrList[i] == "1:0":
                    m.addConstrs((r.sum(s, "*") >= bounds[i, 0] for s in S),
                                 "constr")

                elif constrList[i] == "1:2":
                    m.addConstrs((q.sum("*", s) >= bounds[i, 0] for s in S),
                                 "constr")

                elif constrList[i] == "1:0,2":
                    m.addConstrs((o.sum("*", "*", s) >= bounds[i, 0]
                                  for s in S), "constr")

                elif constrList[i] == "2:0":
                    m.addConstrs((p.sum(n, "*") >= bounds[i, 0] for n in N),
                                 "constr")

                elif constrList[i] == "2:1":
                    m.addConstrs((q.sum(n, "*") >= bounds[i, 0] for n in N),
                                 "constr")

                elif constrList[i] == "2:0,1":
                    m.addConstrs((o.sum(n, "*", "*") >= bounds[i, 0]
                                  for n in N), "constr")

                elif constrList[i] == "0,1:2":
                    m.addConstrs(
                        (o.sum("*", d, s) >= bounds[i, 0] for d in D
                         for s in S),
                        "constr",
                    )

                elif constrList[i] == "0,2:1":
                    m.addConstrs(
                        (o.sum(n, d, "*") >= bounds[i, 0] for d in D
                         for n in N),
                        "constr",
                    )

                elif constrList[i] == "1,2:0":
                    m.addConstrs(
                        (o.sum(n, "*", s) >= bounds[i, 0] for n in N
                         for s in S),
                        "constr",
                    )

            if bounds[i, 1] > 0:
                #                print(bounds[i,1])
                if constrList[i] == "0:1":
                    m.addConstrs((r.sum("*", d) <= bounds[i, 1] for d in D),
                                 "constr")

                elif constrList[i] == "0:2":
                    m.addConstrs((p.sum("*", d) <= bounds[i, 1] for d in D),
                                 "constr")

                elif constrList[i] == "0:1,2":
                    m.addConstrs((o.sum("*", d, "*") <= bounds[i, 1]
                                  for d in D), "constr")

                elif constrList[i] == "1:0":
                    m.addConstrs((r.sum(s, "*") <= bounds[i, 1] for s in S),
                                 "constr")

                elif constrList[i] == "1:2":
                    m.addConstrs((q.sum("*", s) <= bounds[i, 1] for s in S),
                                 "constr")

                elif constrList[i] == "1:0,2":
                    m.addConstrs((o.sum("*", "*", s) <= bounds[i, 1]
                                  for s in S), "constr")

                elif constrList[i] == "2:0":
                    m.addConstrs((p.sum(n, "*") <= bounds[i, 1] for n in N),
                                 "constr")

                elif constrList[i] == "2:1":
                    m.addConstrs((q.sum(n, "*") <= bounds[i, 1] for n in N),
                                 "constr")

                elif constrList[i] == "2:0,1":
                    m.addConstrs((o.sum(n, "*", "*") <= bounds[i, 1]
                                  for n in N), "constr")

                elif constrList[i] == "0,1:2":
                    m.addConstrs(
                        (o.sum("*", d, s) <= bounds[i, 1] for d in D
                         for s in S),
                        "constr",
                    )

                elif constrList[i] == "0,2:1":
                    m.addConstrs(
                        (o.sum(n, d, "*") <= bounds[i, 1] for d in D
                         for n in N),
                        "constr",
                    )

                elif constrList[i] == "1,2:0":
                    m.addConstrs(
                        (o.sum(n, "*", s) <= bounds[i, 1] for n in N
                         for s in S),
                        "constr",
                    )

            #        if mt==1:
            #            for i in range(len(nurse_preference)):
            #                m.addConstr((o[i,nurse_preference[i][0],nurse_preference[i][1]] == 0),"nursePref")

            if constrList[i] == "2:0" and bounds[i, 5] + bounds[i, 4] > 0:
                m.addConstrs((tw[n, 0, 0] == p[n, 0] for n in N),
                             "MaxConsWork")
                m.addConstrs(
                    (tw[n, d1 + 1, 0] <= p[n, d1 + 1] for n in N
                     for d1 in D if d1 < len(D) - 1),
                    "MaxConsWork",
                )
                m.addConstrs(
                    (tw[n, d1 + 1, 0] <= 1 - p[n, d1] for n in N
                     for d1 in D if d1 < len(D) - 1),
                    "MaxConsWork",
                )
                m.addConstrs(
                    (tw[n, d1 + 1, 0] >= p[n, d1 + 1] - p[n, d1] for n in N
                     for d1 in D if d1 < len(D) - 1),
                    "MaxConsWork",
                )

                m.addConstrs((tw[n, 0, d2] == 0 for n in N
                              for d2 in D if d2 > 0), "MaxConsWork")
                m.addConstrs(
                    (tw[n, d1, d2] <= tw[n, d1 - 1, d2 - 1] for n in N
                     for d1 in D for d2 in D if d1 > 0 if d2 > 0),
                    "MaxConsWork",
                )
                m.addConstrs(
                    (tw[n, d1, d2] <= p[n, d1] for n in N for d1 in D
                     for d2 in D if d1 > 0 if d2 > 0),
                    "MaxConsWork",
                )
                m.addConstrs(
                    (tw[n, d1, d2] >= p[n, d1] + tw[n, d1 - 1, d2 - 1] - 1
                     for n in N for d1 in D for d2 in D if d1 > 0 if d2 > 0),
                    "MaxConsWork",
                )
                if bounds[i, 5] > 0:
                    m.addConstr(
                        (quicksum(tw[n, d1, d2] for n in N for d1 in D
                                  for d2 in range(bounds[i, 5], len(D))) == 0),
                        "maxconswork",
                    )
                if bounds[i, 4] > 0:
                    m.addConstrs((sw[n, 0, d2] == 0 for n in N for d2 in D),
                                 "MinConsWork")
                    m.addConstrs(
                        (sw[n, d1, d2] <= tw[n, d1 - 1, d2] for n in N
                         for d1 in D for d2 in D if d1 > 0),
                        "MinConsWork",
                    )
                    m.addConstrs(
                        (sw[n, d1, d2] <= 1 - p[n, d1] for n in N for d1 in D
                         for d2 in D if d1 > 0),
                        "MinConsWork",
                    )
                    m.addConstrs(
                        (sw[n, d1, d2] >= tw[n, d1 - 1, d2] - p[n, d1]
                         for n in N for d1 in D for d2 in D if d1 > 0),
                        "MinConsWork",
                    )

                    m.addConstrs(
                        (sw[n, num_days, d2] == tw[n, num_days - 1, d2]
                         for n in N for d2 in D),
                        "MinConsWork",
                    )

                    m.addConstr(
                        (quicksum(sw[n, d1, d2] * (bounds[i, 4] - 1 - d2)
                                  for n in N for d1 in Ds
                                  for d2 in range(bounds[i, 4] - 1)) == 0),
                        "minconswork",
                    )

            if constrList[i] == [(2, ),
                                 (0, )] and bounds[i, 3] + bounds[i, 2] > 0:
                m.addConstrs((tf[n, 0, 0] == 1 - p[n, 0] for n in N),
                             "MaxConsFree")
                m.addConstrs(
                    (tf[n, d1 + 1, 0] <= p[n, d1] for n in N
                     for d1 in D if d1 < len(D) - 1),
                    "MaxConsFree",
                )
                m.addConstrs(
                    (tf[n, d1 + 1, 0] <= 1 - p[n, d1 + 1] for n in N
                     for d1 in D if d1 < len(D) - 1),
                    "MaxConsFree",
                )
                m.addConstrs(
                    (tf[n, d1 + 1, 0] >= p[n, d1] - p[n, d1 + 1] for n in N
                     for d1 in D if d1 < len(D) - 1),
                    "MaxConsFree",
                )

                m.addConstrs((tf[n, 0, d2] == 0 for n in N
                              for d2 in D if d2 > 0), "MaxConsFree")
                m.addConstrs(
                    (tf[n, d1, d2] <= tf[n, d1 - 1, d2 - 1] for n in N
                     for d1 in D for d2 in D if d1 > 0 if d2 > 0),
                    "MaxConsFree",
                )
                m.addConstrs(
                    (tf[n, d1, d2] <= 1 - p[n, d1] for n in N for d1 in D
                     for d2 in D if d1 > 0 if d2 > 0),
                    "MaxConsFree",
                )
                m.addConstrs(
                    (tf[n, d1, d2] >= tf[n, d1 - 1, d2 - 1] - p[n, d1]
                     for n in N for d1 in D for d2 in D if d1 > 0 if d2 > 0),
                    "MaxConsFree",
                )
                if bounds[i, 3] > 0:
                    m.addConstr(
                        (quicksum(tf[n, d1, d2] for n in N for d1 in D
                                  for d2 in range(bounds[i, 3], len(D))) == 0),
                        "maxconsfree",
                    )

                if bounds[i, 2] > 0:
                    m.addConstrs((sf[n, 0, d2] == 0 for n in N for d2 in D),
                                 "MinConsFree")
                    m.addConstrs(
                        (sf[n, d1, d2] <= tf[n, d1 - 1, d2] for n in N
                         for d1 in D for d2 in D if d1 > 0),
                        "MinConsFree",
                    )
                    m.addConstrs(
                        (sf[n, d1, d2] <= p[n, d1] for n in N for d1 in D
                         for d2 in D if d1 > 0),
                        "MinConsFree",
                    )
                    m.addConstrs(
                        (sf[n, d1, d2] >= tf[n, d1 - 1, d2] + p[n, d1] - 1
                         for n in N for d1 in D for d2 in D if d1 > 0),
                        "MinConsFree",
                    )

                    m.addConstrs(
                        (sf[n, num_days, d2] == tf[n, num_days - 1, d2]
                         for n in N for d2 in D),
                        "MinConsFree",
                    )

                    m.addConstr(
                        (quicksum(sf[n, d1, d2] * (bounds[i, 2] - 1 - d2)
                                  for n in N for d1 in Ds
                                  for d2 in range(bounds[i, 2] - 1)) == 0),
                        "minconsfree",
                    )

            if constrList[i] == [(2, ),
                                 (1, )] and bounds[i, 5] + bounds[i, 4] > 0:
                m.addConstrs((tws[n, 0, 0] == q[n, 0] for n in N),
                             "MaxConsWork")
                m.addConstrs(
                    (tws[n, s1 + 1, 0] <= q[n, s1 + 1] for n in N
                     for s1 in S if s1 < len(S) - 1),
                    "MaxConsWork",
                )
                m.addConstrs(
                    (tws[n, s1 + 1, 0] <= 1 - q[n, s1] for n in N
                     for s1 in S if s1 < len(S) - 1),
                    "MaxConsWork",
                )
                m.addConstrs(
                    (tws[n, s1 + 1, 0] >= q[n, s1 + 1] - q[n, s1] for n in N
                     for s1 in S if s1 < len(S) - 1),
                    "MaxConsWork",
                )

                m.addConstrs((tws[n, 0, s2] == 0 for n in N
                              for s2 in S if s2 > 0), "MaxConsWork")
                m.addConstrs(
                    (tws[n, s1, s2] <= tws[n, s1 - 1, s2 - 1] for n in N
                     for s1 in S for s2 in S if s1 > 0 if s2 > 0),
                    "MaxConsWork",
                )
                m.addConstrs(
                    (tws[n, s1, s2] <= q[n, s1] for n in N for s1 in S
                     for s2 in S if s1 > 0 if s2 > 0),
                    "MaxConsWork",
                )
                m.addConstrs(
                    (tws[n, s1, s2] >= q[n, s1] + tws[n, s1 - 1, s2 - 1] - 1
                     for n in N for s1 in S for s2 in S if s1 > 0 if s2 > 0),
                    "MaxConsWork",
                )

                if bounds[i, 5] > 0:
                    m.addConstr(
                        (quicksum(tws[n, s1, s2] for n in N for s1 in S
                                  for s2 in range(bounds[i, 5], len(S))) == 0),
                        "maxconswork",
                    )

                if bounds[i, 4] > 0:
                    m.addConstrs((sws[n, 0, s2] == 0 for n in N for s2 in S),
                                 "MinConsWork")
                    m.addConstrs(
                        (sws[n, s1, s2] <= tws[n, s1 - 1, s2] for n in N
                         for s1 in S for s2 in S if s1 > 0),
                        "MinConsWork",
                    )
                    m.addConstrs(
                        (sws[n, s1, s2] <= 1 - q[n, s1] for n in N for s1 in S
                         for s2 in S if s1 > 0),
                        "MinConsWork",
                    )
                    m.addConstrs(
                        (sws[n, s1, s2] >= tws[n, s1 - 1, s2] - q[n, s1]
                         for n in N for s1 in S for s2 in S if s1 > 0),
                        "MinConsWork",
                    )

                    m.addConstrs(
                        (sws[n, num_shifts, s2] == tws[n, num_shifts - 1, s2]
                         for n in N for s2 in S),
                        "MinConsWork",
                    )

                    m.addConstr(
                        (quicksum(sws[n, s1, s2] * (bounds[i, 4] - 1 - s2)
                                  for n in N for s1 in Ss
                                  for s2 in range(bounds[i, 4] - 1)) == 0),
                        "minconswork",
                    )

            if constrList[i] == [(2, ),
                                 (1, )] and bounds[i, 3] + bounds[i, 2] > 0:
                m.addConstrs((tfs[n, 0, 0] == 1 - q[n, 0] for n in N),
                             "MaxConsFree")
                m.addConstrs(
                    (tfs[n, s1 + 1, 0] <= q[n, s1] for n in N
                     for s1 in S if s1 < len(S) - 1),
                    "MaxConsFree",
                )
                m.addConstrs(
                    (tfs[n, s1 + 1, 0] <= 1 - q[n, s1 + 1] for n in N
                     for s1 in S if s1 < len(S) - 1),
                    "MaxConsFree",
                )
                m.addConstrs(
                    (tfs[n, s1 + 1, 0] >= q[n, s1] - q[n, s1 + 1] for n in N
                     for s1 in S if s1 < len(S) - 1),
                    "MaxConsFree",
                )

                m.addConstrs((tfs[n, 0, s2] == 0 for n in N
                              for s2 in S if s2 > 0), "MaxConsFree")
                m.addConstrs(
                    (tfs[n, s1, s2] <= tfs[n, s1 - 1, s2 - 1] for n in N
                     for s1 in S for s2 in S if s1 > 0 if s2 > 0),
                    "MaxConsFree",
                )
                m.addConstrs(
                    (tfs[n, s1, s2] <= 1 - q[n, s1] for n in N for s1 in S
                     for s2 in S if s1 > 0 if s2 > 0),
                    "MaxConsFree",
                )
                m.addConstrs(
                    (tfs[n, s1, s2] >= tfs[n, s1 - 1, s2 - 1] - q[n, s1]
                     for n in N for s1 in S for s2 in S if s1 > 0 if s2 > 0),
                    "MaxConsFree",
                )
                if bounds[i, 3] > 0:
                    m.addConstr(
                        (quicksum(tfs[n, s1, s2] for n in N for s1 in S
                                  for s2 in range(bounds[i, 3], len(S))) == 0),
                        "maxconsfree",
                    )

                if bounds[i, 2] > 0:
                    m.addConstrs((sfs[n, 0, s2] == 0 for n in N for s2 in S),
                                 "MinConsFree")
                    m.addConstrs(
                        (sfs[n, s1, s2] <= tfs[n, s1 - 1, s2] for n in N
                         for s1 in S for s2 in S if s1 > 0),
                        "MinConsFree",
                    )
                    m.addConstrs(
                        (sfs[n, s1, s2] <= q[n, s1] for n in N for s1 in S
                         for s2 in S if s1 > 0),
                        "MinConsFree",
                    )
                    m.addConstrs(
                        (sfs[n, s1, s2] >= tfs[n, s1 - 1, s2] + q[n, s1] - 1
                         for n in N for s1 in S for s2 in S if s1 > 0),
                        "MinConsFree",
                    )

                    m.addConstrs(
                        (sfs[n, num_shifts, s2] == tfs[n, num_shifts - 1, s2]
                         for n in N for s2 in S),
                        "MinConsWork",
                    )

                    m.addConstr(
                        (quicksum(sfs[n, s1, s2] * (bounds[i, 2] - 1 - s2)
                                  for n in N for s1 in Ss
                                  for s2 in range(bounds[i, 2] - 1)) == 0),
                        "minconsfree",
                    )

            if constrList[i] == [(1, 2),
                                 (0, )] and bounds[i, 5] + bounds[i, 4] > 0:
                m.addConstrs(
                    (tw1[n, 0, s, 0] == o[n, 0, s] for n in N for s in S),
                    "MaxConsSameShift",
                )
                m.addConstrs(
                    (tw1[n, d1 + 1, s, 0] <= o[n, d1 + 1, s] for s in S
                     for n in N for d1 in D if d1 < len(D) - 1),
                    "MaxConsSameShift",
                )
                m.addConstrs(
                    (tw1[n, d1 + 1, s, 0] <= 1 - o[n, d1, s] for s in S
                     for n in N for d1 in D if d1 < len(D) - 1),
                    "MaxConsSameShift",
                )
                m.addConstrs(
                    (tw1[n, d1 + 1, s, 0] >= o[n, d1 + 1, s] - o[n, d1, s]
                     for s in S for n in N for d1 in D if d1 < len(D) - 1),
                    "MaxConsSameShift",
                )

                m.addConstrs(
                    (tw1[n, 0, s, d2] == 0 for s in S for n in N
                     for d2 in D if d2 > 0),
                    "MaxConsSameShift",
                )
                m.addConstrs(
                    (tw1[n, d1, s, d2] <= tw1[n, d1 - 1, s, d2 - 1] for s in S
                     for n in N for d1 in D for d2 in D if d1 > 0 if d2 > 0),
                    "MaxConsSameShift",
                )
                m.addConstrs(
                    (tw1[n, d1, s, d2] <= o[n, d1, s] for s in S for n in N
                     for d1 in D for d2 in D if d1 > 0 if d2 > 0),
                    "MaxConsSameShift",
                )
                m.addConstrs(
                    (tw1[n, d1, s, d2] >=
                     o[n, d1, s] + tw1[n, d1 - 1, s, d2 - 1] - 1 for s in S
                     for n in N for d1 in D for d2 in D if d1 > 0 if d2 > 0),
                    "MaxConsSameShift",
                )
                if bounds[i, 5] > 0:
                    m.addConstr(
                        (quicksum(tw1[n, d1, s, d2] for s in S for n in N
                                  for d1 in D
                                  for d2 in range(bounds[i, 5], len(D))) == 0),
                        "maxconssameshift",
                    )

                if bounds[i, 4] > 0:
                    m.addConstrs(
                        (sw1[n, 0, s, d2] == 0 for s in S for n in N
                         for d2 in D),
                        "MinConsSameShift",
                    )
                    m.addConstrs(
                        (sw1[n, d1, s, d2] <= tw1[n, d1 - 1, s, d2] for s in S
                         for n in N for d1 in D for d2 in D if d1 > 0),
                        "MinConsSameShift",
                    )
                    m.addConstrs(
                        (sw1[n, d1, s, d2] <= 1 - o[n, d1, s] for s in S
                         for n in N for d1 in D for d2 in D if d1 > 0),
                        "MinConsSameShift",
                    )
                    m.addConstrs(
                        (sw1[n, d1, s, d2] >=
                         tw1[n, d1 - 1, s, d2] - o[n, d1, s] for s in S
                         for n in N for d1 in D for d2 in D if d1 > 0),
                        "MinConsSameShift",
                    )

                    m.addConstrs(
                        (sw1[n, num_days, s, d2] == tw1[n, num_days - 1, s, d2]
                         for n in N for s in S for d2 in D),
                        "MinConsWork",
                    )

                    m.addConstr(
                        (quicksum(sw1[n, d1, s, d2] * (bounds[i, 4] - 1 - d2)
                                  for s in S for n in N for d1 in Ds
                                  for d2 in range(bounds[i, 4] - 1)) == 0),
                        "minconssameshift",
                    )

            if constrList[i] == [(1, 2),
                                 (0, )] and bounds[i, 3] + bounds[i, 2] > 0:
                m.addConstrs(
                    (tw1f[n, 0, s, 0] == 1 - o[n, 0, s] for n in N for s in S),
                    "MaxConsFree",
                )
                m.addConstrs(
                    (tw1f[n, d1 + 1, s, 0] <= o[n, d1, s] for n in N for s in S
                     for d1 in D if d1 < len(D) - 1),
                    "MaxConsFree",
                )
                m.addConstrs(
                    (tw1f[n, d1 + 1, s, 0] <= 1 - o[n, d1 + 1, s] for n in N
                     for s in S for d1 in D if d1 < len(D) - 1),
                    "MaxConsFree",
                )
                m.addConstrs(
                    (tw1f[n, d1 + 1, s, 0] >= o[n, d1, s] - o[n, d1 + 1, s]
                     for n in N for s in S for d1 in D if d1 < len(D) - 1),
                    "MaxConsFree",
                )

                m.addConstrs(
                    (tw1f[n, 0, s, d2] == 0 for n in N for s in S
                     for d2 in D if d2 > 0),
                    "MaxConsFree",
                )
                m.addConstrs(
                    (tw1f[n, d1, s, d2] <= tw1f[n, d1 - 1, s, d2 - 1]
                     for n in N for s in S for d1 in D
                     for d2 in D if d1 > 0 if d2 > 0),
                    "MaxConsFree",
                )
                m.addConstrs(
                    (tw1f[n, d1, s, d2] <= 1 - o[n, d1, s] for n in N
                     for s in S for d1 in D for d2 in D if d1 > 0 if d2 > 0),
                    "MaxConsFree",
                )
                m.addConstrs(
                    (tw1f[n, d1, s, d2] >=
                     tw1f[n, d1 - 1, s, d2 - 1] - o[n, d1, s] for n in N
                     for s in S for d1 in D for d2 in D if d1 > 0 if d2 > 0),
                    "MaxConsFree",
                )
                if bounds[i, 3] > 0:
                    m.addConstr(
                        (quicksum(tw1f[n, d1, s, d2] for n in N for s in S
                                  for d1 in D
                                  for d2 in range(bounds[i, 3], len(D))) == 0),
                        "maxconsfree",
                    )

                if bounds[i, 2] > 0:
                    m.addConstrs(
                        (sw1f[n, 0, s, d2] == 0 for n in N for s in S
                         for d2 in D),
                        "MinConsw1free",
                    )
                    m.addConstrs(
                        (sw1f[n, d1, s, d2] <= tw1f[n, d1 - 1, s, d2]
                         for n in N for s in S for d1 in D
                         for d2 in D if d1 > 0),
                        "MinConsw1free",
                    )
                    m.addConstrs(
                        (sw1f[n, d1, s, d2] <= o[n, d1, s] for n in N
                         for s in S for d1 in D for d2 in D if d1 > 0),
                        "MinConsw1free",
                    )
                    m.addConstrs(
                        (sw1f[n, d1, s, d2] >=
                         tw1f[n, d1 - 1, s, d2] + o[n, d1, s] - 1 for n in N
                         for s in S for d1 in D for d2 in D if d1 > 0),
                        "MinConsw1free",
                    )

                    m.addConstrs(
                        (sw1f[n, num_days, s, d2]
                         == tw1f[n, num_days - 1, s, d2] for n in N for s in S
                         for d2 in D),
                        "MinConsWork",
                    )

                    m.addConstr(
                        (quicksum(sw1f[n, d1, s, d2] * (bounds[i, 2] - 1 - d2)
                                  for n in N for s in S for d1 in Ds
                                  for d2 in range(bounds[i, 2] - 1)) == 0),
                        "minconsw1free",
                    )

        m.setParam(GRB.Param.PoolSolutions, numSam)
        m.setParam(GRB.Param.PoolSearchMode, 2)
        m.optimize()
        nSolutions = m.SolCount
        # print("Number of solutions found: " + str(nSolutions))
        if m.status == GRB.Status.INFEASIBLE:
            m.computeIIS()
            # print("\nThe following constraint(s) cannot be satisfied:")
            for c in m.getConstrs():
                if c.IISConstr:
                    # print("%s" % c.constrName)
                    pass
        # if m.status == GRB.Status.OPTIMAL:
        #     m.write("m.sol")
        #        print(nSolutions)
        #        print(partial_sol)
        multi_predictions = []
        for i in range(nSolutions):
            provenance = ("countor", gid + "-" + str(uuid4()))
            m.setParam(GRB.Param.SolutionNumber, i)
            solution = m.getAttr("xn", o)
            #             print(m.getAttr("xn", p))
            tmp = np.zeros([num_nurses, num_days, num_shifts])
            for key in solution:
                tmp[key] = round(solution[key])
            #            tSample=np.swapaxes(np.swapaxes(tmp,0,1),1,2)
            tmp_sol = tmp.astype(int)

            #            print(partial_sol)
            for n in N:
                for d in D:
                    for s in S:
                        #                        print(x_mapping[n,d,s],y_mapping[n,d,s])
                        if np.isnan(partial_sol[n, d, s]):
                            #                            print("geer")
                            multi_predictions.append(
                                Prediction(
                                    Coordinate(
                                        y_mapping[n, d, s].item(),
                                        x_mapping[n, d, s].item(),
                                    ),
                                    tmp_sol[n, d, s].item(),
                                    1,
                                    provenance,
                                ))
        return multi_predictions

    except GurobiError as e:
        print("Error code " + str(e.errno) + ": " + str(e))

    except AttributeError:
        print("Encountered an attribute error")
Пример #14
0
def trajectory_model(s, T):
    model = Model("polytopic trajectory of PWA systems")
    x = {}
    u = {}
    theta = {}
    z = {}
    G = {}
    G_bound = 10
    for t in range(T):
        x[t] = np.empty((s.n, 1), dtype='object')  # n*1
        u[t] = np.empty((s.m, 1), dtype='object')  # m*1
        theta[t] = np.empty((s.m, s.n), dtype='object')  # n*m
        for row in range(s.n):
            x[t][row, 0] = model.addVar(lb=-G_bound, ub=G_bound)
        for row in range(s.m):
            u[t][row, 0] = model.addVar(lb=-G_bound, ub=G_bound)
        for row in range(s.m):
            for column in range(s.n):
                theta[t][row, column] = model.addVar(lb=-G_bound, ub=G_bound)
    for t in range(T + 1):
        for i in s.modes:
            z[t, i] = model.addVar(vtype=GRB.BINARY)
    x[T] = np.empty((s.n, 1), dtype='object')  # Final state in Mode i
    for row in range(s.n):
        x[T][row, 0] = model.addVar(lb=-G_bound, ub=G_bound)
    for t in range(T + 1):
        G[t] = np.empty((s.n, s.n), dtype='object')
        for row in range(s.n):
            for column in range(s.n):
                G[t][row, column] = model.addVar(lb=-G_bound, ub=G_bound)
    # Trajectory Constraints:
    bigM = G_bound * 2
    for t in range(T):
        for i in s.modes:
            for row in range(s.n):
                Ax = LinExpr()
                for k in range(s.n):
                    Ax.add(s.A[i][row, k] * x[t][k, 0])
                for k in range(s.m):
                    Ax.add(s.B[i][row, k] * u[t][k, 0])
                model.addConstr(x[t + 1][row, 0] <= Ax + s.c[i][row] + bigM -
                                bigM * z[t, i])
                model.addConstr(x[t + 1][row, 0] >= Ax + s.c[i][row] - bigM +
                                bigM * z[t, i])
    # Generator Dynamics Constraints:
    for t in range(T):
        for i in s.modes:
            for row in range(s.n):
                for column in range(s.n):
                    AG = LinExpr()
                    for k in range(s.n):
                        AG.add(s.A[i][row, k] * G[t][k, column])
                    for k in range(s.m):
                        AG.add(s.B[i][row, k] * theta[t][k, column])
                    model.addConstr(
                        G[t + 1][row, column] <= AG + bigM - bigM * z[t, i])
                    model.addConstr(
                        G[t + 1][row, column] >= AG - bigM + bigM * z[t, i])
    # Constraints of mode subsets
    for t in range(T):
        for i in s.modes:
            subset_MILP(model, G[t], s.Pi, s.H[i], s.h[i], x[t], z[t, i])
            subset_MILP(model, theta[t], s.Pi, s.F[i], s.f[i], u[t], z[t, i])
    # Constraints of modes:
    for t in range(T + 1):
        sum_z = LinExpr()
        for i in s.modes:
            sum_z.add(z[t, i])
        model.addConstr(sum_z == 1, name="sadra%d" % T)
    model.update()
    s.core_constraints[T] = model.getConstrs()
    s.core_Vars[T] = model.getVars()
    s.library[T] = (model, x, u, G, theta, z)
Пример #15
0
    m.addConstrs((X_coedta[cancha, equipoO, equipoE, deporte, bloque, dia]
                  == X_coedta[cancha, equipoE, equipoO, deporte, bloque, dia]
                  for cancha in C for deporte in D for bloque in T
                  for equipoE in E for equipoO in E if equipoE != equipoO
                  for dia in A), "C10")

    # m.addConstrs((quicksum(a_rpt[punto, producto, tiempo] for punto in R for producto in S) >= 1 for tiempo in T), "c9")

    # m.addConstrs((X_coedta[cancha, equipo, equipo, deporte, bloque, dia] == 0 for cancha in C for equipo in E for bloque in T for dia in A for deporte in D), "C10")
    print("R10 lista")
    # Optimizar
    m.optimize()

    print("Num Vars: ", len(m.getVars()))
    print("Num Restricciones: ", len(m.getConstrs()))

    status = m.status

    print('Status:', status)

    if status != GRB.Status.OPTIMAL:
        print('Optimization was stopped with status %d' % status)
        # exit(0)

    if status == GRB.Status.INF_OR_UNBD:
        print(
            'The model cannot be solved because it is infeasible or unbounded')

    if status == GRB.Status.INFEASIBLE:
        print("Model is INFEASIBLE")
Пример #16
0
from gurobipy import GRB, Model

m = Model()

m.addVar()

x = m.addVar(vtype=GRB.BINARY, name="x")
y = m.addVar(vtype=GRB.BINARY, name="y")
z = m.addVar(vtype=GRB.BINARY, name="z")

m.update()

m.setObjective(x + y + 2 * z, GRB.MAXIMIZE)

m.addConstr(x + 2 * y + 3 * z <= 6, name="c0")
m.addConstr(x + y >= 1, name="c1")

m.optimize()

m.printAttr("X")

for constr in m.getConstrs():
    print(constr, constr.getAttr("slack"))