Example #1
1
def diet(F,N,a,b,c,d):
    """diet -- model for the modern diet problem
    Parameters:
        F - set of foods
        N - set of nutrients
        a[i] - minimum intake of nutrient i
        b[i] - maximum intake of nutrient i
        c[j] - cost of food j
        d[j][i] - amount of nutrient i in food j
    Returns a model, ready to be solved.
    """
    model = Model("modern diet")

    # Create variables
    x,y,z = {},{},{}
    for j in F:
        x[j] = model.addVar(vtype="I", name="x(%s)" % j)

    for i in N:
        z[i] = model.addVar(lb=a[i], ub=b[i], vtype="C", name="z(%s)" % i)

    # Constraints:
    for i in N:
        model.addCons(quicksum(d[j][i]*x[j] for j in F) == z[i], name="Nutr(%s)" % i)

    model.setObjective(quicksum(c[j]*x[j]  for j in F), "minimize")

    model.data = x,y,z
    return model
Example #2
1
def test_model():
    # create solver instance
    s = Model()

    # add some variables
    x = s.addVar("x", vtype = 'C', obj = 1.0)
    y = s.addVar("y", vtype = 'C', obj = 2.0)

    assert x.getObj() == 1.0
    assert y.getObj() == 2.0

    s.setObjective(4.0 * y + 10.5, clear = False)
    assert x.getObj() == 1.0
    assert y.getObj() == 4.0
    assert s.getObjoffset() == 10.5

    # add some constraint
    c = s.addCons(x + 2 * y >= 1.0)
    assert c.isLinear()
    s.chgLhs(c, 5.0)
    s.chgRhs(c, 6.0)

    assert s.getLhs(c) == 5.0
    assert s.getRhs(c) == 6.0

    # solve problem
    s.optimize()

    solution = s.getBestSol()

    # print solution
    assert (s.getVal(x) == s.getSolVal(solution, x))
    assert (s.getVal(y) == s.getSolVal(solution, y))
    assert round(s.getVal(x)) == 5.0
    assert round(s.getVal(y)) == 0.0
    assert s.getSlack(c, solution) == 0.0
    assert s.getSlack(c, solution, 'lhs') == 0.0
    assert s.getSlack(c, solution, 'rhs') == 1.0
    assert s.getActivity(c, solution) == 5.0

    s.writeProblem('model')
    s.writeProblem('model.lp')

    s.freeProb()
    s = Model()
    x = s.addVar("x", vtype = 'C', obj = 1.0)
    y = s.addVar("y", vtype = 'C', obj = 2.0)
    c = s.addCons(x + 2 * y <= 1.0)
    s.setMaximize()

    s.delCons(c)

    s.optimize()

    assert s.getStatus() == 'unbounded'
Example #3
0
def mctransp(I,J,K,c,d,M):
    """mctransp -- model for solving the Multi-commodity Transportation Problem
    Parameters:
        - I: set of customers
        - J: set of facilities
        - K: set of commodities
        - c[i,j,k]: unit transportation cost on arc (i,j) for commodity k
        - d[i][k]: demand for commodity k at node i
        - M[j]: capacity
    Returns a model, ready to be solved.
    """

    model = Model("multi-commodity transportation")

    # Create variables
    x = {}
    for (i,j,k) in c:
        x[i,j,k] = model.addVar(vtype="C", name="x(%s,%s,%s)" % (i,j,k), obj=c[i,j,k])
# todo
    arcs = tuplelist([(i,j,k) for (i,j,k) in x])

    # Demand constraints
    for i in I:
        for k in K:
            model.addCons(sum(x[i,j,k] for (i,j,k) in arcs.select(i,"*",k)) == d[i,k], "Demand(%s,%s)" % (i,k))

    # Capacity constraints
    for j in J:
        model.addConstr(sum(x[i,j,k] for (i,j,k) in arcs.select("*",j,"*")) <= M[j], "Capacity(%s)" % j)

    model.data = x
    return model
Example #4
0
def tsp(V,c):
    """tsp -- model for solving the traveling salesman problem with callbacks
       - start with assignment model
       - add cuts until there are no sub-cycles
    Parameters:
        - V: set/list of nodes in the graph
        - c[i,j]: cost for traversing edge (i,j)
    Returns the optimum objective value and the list of edges used.
    """
    model = Model("TSP_lazy")
    conshdlr = TSPconshdlr()

    x = {}
    for i in V:
        for j in V:
            if j > i:
                x[i,j] = model.addVar(vtype = "B",name = "x(%s,%s)" % (i,j))

    for i in V:
        model.addCons(quicksum(x[j, i] for j in V if j < i) +
                      quicksum(x[i, j] for j in V if j > i) == 2, "Degree(%s)" % i)

    model.setObjective(quicksum(c[i, j] * x[i, j] for i in V for j in V if j > i), "minimize")

    model.data = x
    return model, conshdlr
Example #5
0
    def create_model():
        # create solver instance
        s = Model()

        # add some variables
        x = s.addVar("x", obj = -1.0, vtype = "I", lb=-10)
        y = s.addVar("y", obj = 1.0, vtype = "I", lb=-1000)
        z = s.addVar("z", obj = 1.0, vtype = "I", lb=-1000)

        # add some constraint
        s.addCons(314*x + 867*y + 860*z == 363)
        s.addCons(87*x + 875*y - 695*z == 423)

        # create conshdlr and include it to SCIP
        conshdlr = MyConshdlr(shouldtrans=True, shouldcopy=False)
        s.includeConshdlr(conshdlr, "PyCons", "custom constraint handler implemented in python",
                          sepapriority = 1, enfopriority = -1, chckpriority = 1, sepafreq = 10, propfreq = 50,
                          eagerfreq = 1, maxprerounds = -1, delaysepa = False, delayprop = False, needscons = True,
                          presoltiming = SCIP_PRESOLTIMING.FAST, proptiming = SCIP_PROPTIMING.BEFORELP)

        cons1 = s.createCons(conshdlr, "cons1name")
        ids.append(id(cons1))
        cons2 = s.createCons(conshdlr, "cons2name")
        ids.append(id(cons2))
        conshdlr.createData(cons1, 10, "cons1_anothername")
        conshdlr.createData(cons2, 12, "cons2_anothername")

        # add these constraints
        s.addPyCons(cons1)
        s.addPyCons(cons2)
        return s
Example #6
0
def test_event():
    # create solver instance
    s = Model()
    s.hideOutput()
    s.setPresolve(SCIP_PARAMSETTING.OFF)
    eventhdlr = MyEvent()
    s.includeEventhdlr(eventhdlr, "TestFirstLPevent", "python event handler to catch FIRSTLPEVENT")

    # add some variables
    x = s.addVar("x", obj=1.0)
    y = s.addVar("y", obj=2.0)

    # add some constraint
    s.addCons(x + 2*y >= 5)
    # solve problem
    s.optimize()

    # print solution
    assert round(s.getVal(x)) == 5.0
    assert round(s.getVal(y)) == 0.0

    del s

    assert 'eventinit' in calls
    assert 'eventexit' in calls
    assert 'eventexec' in calls
    assert len(calls) == 3
Example #7
0
def vrp(V, c, m, q, Q):
    """solve_vrp -- solve the vehicle routing problem.
       - start with assignment model (depot has a special status)
       - add cuts until all components of the graph are connected
    Parameters:
        - V: set/list of nodes in the graph
        - c[i,j]: cost for traversing edge (i,j)
        - m: number of vehicles available
        - q[i]: demand for customer i
        - Q: vehicle capacity
    Returns the optimum objective value and the list of edges used.
    """

    model = Model("vrp")
    vrp_conshdlr = VRPconshdlr()

    x = {}
    for i in V:
        for j in V:
            if j > i and i == V[0]:       # depot
                x[i,j] = model.addVar(ub=2, vtype="I", name="x(%s,%s)"%(i,j))
            elif j > i:
                x[i,j] = model.addVar(ub=1, vtype="I", name="x(%s,%s)"%(i,j))

    model.addCons(quicksum(x[V[0],j] for j in V[1:]) == 2*m, "DegreeDepot")
    for i in V[1:]:
        model.addCons(quicksum(x[j,i] for j in V if j < i) +
                        quicksum(x[i,j] for j in V if j > i) == 2, "Degree(%s)"%i)

    model.setObjective(quicksum(c[i,j]*x[i,j] for i in V for j in V if j>i), "minimize")
    model.data = x

    return model, vrp_conshdlr
Example #8
0
def scheduling_time_index(J,p,r,w):
    """
    scheduling_time_index: model for the one machine total weighted tardiness problem

    Model for the one machine total weighted tardiness problem
    using the time index formulation

    Parameters:
        - J: set of jobs
        - p[j]: processing time of job j
        - r[j]: earliest start time of job j
        - w[j]: weighted of job j; the objective is the sum of the weighted completion time

    Returns a model, ready to be solved.
    """
    model = Model("scheduling: time index")
    T = max(r.values()) + sum(p.values())
    X = {}   # X[j,t]=1 if job j starts processing at time t, 0 otherwise
    for j in J:
        for t in range(r[j], T-p[j]+2):
            X[j,t] = model.addVar(vtype="B", name="x(%s,%s)"%(j,t))

    for j in J:
        model.addCons(quicksum(X[j,t] for t in range(1,T+1) if (j,t) in X) == 1, "JobExecution(%s)"%(j))

    for t in range(1,T+1):
        ind = [(j,t2) for j in J for t2 in range(t-p[j]+1,t+1) if (j,t2) in X]
        if ind != []:
            model.addCons(quicksum(X[j,t2] for (j,t2) in ind) <= 1, "MachineUB(%s)"%t)

    model.setObjective(quicksum((w[j] * (t - 1 + p[j])) * X[j,t] for (j,t) in X), "minimize")

    model.data = X
    return model
def mils_echelon(T,K,P,f,g,c,d,h,a,M,UB,phi):
    """
    mils_echelon: echelon formulation for the multi-item, multi-stage lot-sizing problem

    Parameters:
        - T: number of periods
        - K: set of resources
        - P: set of items
        - f[t,p]: set-up costs (on period t, for product p)
        - g[t,p]: set-up times
        - c[t,p]: variable costs
        - d[t,p]: demand values
        - h[t,p]: holding costs
        - a[t,k,p]: amount of resource k for producing p in period t
        - M[t,k]: resource k upper bound on period t
        - UB[t,p]: upper bound of production time of product p in period t
        - phi[(i,j)]: units of i required to produce a unit of j (j parent of i)
    """
    rho = calc_rho(phi) # rho[(i,j)]: units of i required to produce a unit of j (j ancestor of i)

    model = Model("multi-stage lotsizing -- echelon formulation")

    y,x,E,H = {},{},{},{}
    Ts = range(1,T+1)
    for p in P:
        for t in Ts:
            y[t,p] = model.addVar(vtype="B", name="y(%s,%s)"%(t,p))
            x[t,p] = model.addVar(vtype="C", name="x(%s,%s)"%(t,p))
            H[t,p] = h[t,p] - sum([h[t,q]*phi[q,p] for (q,p2) in phi if p2 == p])
            E[t,p] = model.addVar(vtype="C", name="E(%s,%s)"%(t,p))        # echelon inventory
        E[0,p] = model.addVar(vtype="C", name="E(%s,%s)"%(0,p))    # echelon inventory

    for t in Ts:
        for p in P:
            # flow conservation constraints
            dsum = d[t,p] + sum([rho[p,q]*d[t,q] for (p2,q) in rho if p2 == p])
            model.addCons(E[t-1,p] + x[t,p] == E[t,p] + dsum, "FlowCons(%s,%s)"%(t,p))

            # capacity connection constraints
            model.addCons(x[t,p] <= UB[t,p]*y[t,p], "ConstrUB(%s,%s)"%(t,p))

        # time capacity constraints
        for k in K:
            model.addCons(quicksum(a[t,k,p]*x[t,p] + g[t,p]*y[t,p] for p in P) <= M[t,k],
                            "TimeUB(%s,%s)"%(t,k))


    # calculate echelon quantities
    for p in P:
        model.addCons(E[0,p] == 0, "EchelonInit(%s)"%(p))
        for t in Ts:
            model.addCons(E[t,p] >= quicksum(phi[p,q]*E[t,q] for (p2,q) in phi if p2 == p),
                            "EchelonLB(%s,%s)"%(t,p))

    model.setObjective(\
        quicksum(f[t,p]*y[t,p] + c[t,p]*x[t,p] + H[t,p]*E[t,p] for t in Ts for p in P), \
        "minimize")

    model.data = y,x,E
    return model
Example #10
0
def eld_another(U,p_min,p_max,d,brk):
    """eld -- economic load dispatching in electricity generation
    Parameters:
        - U: set of generators (units)
        - p_min[u]: minimum operating power for unit u
        - p_max[u]: maximum operating power for unit u
        - d: demand
        - brk[u][k]: (x,y) coordinates of breakpoint k, k=0,...,K for unit u
    Returns a model, ready to be solved.
    """
    model = Model("Economic load dispatching")

    # set objective based on piecewise linear approximation
    p,F,z = {},{},{}
    for u in U:
        abrk = [X for (X,Y) in brk[u]]
        bbrk = [Y for (X,Y) in brk[u]]
        p[u],F[u],z[u] = convex_comb_sos(model,abrk,bbrk)
        p[u].lb = p_min[u]
        p[u].ub = p_max[u]

    # demand satisfaction
    model.addCons(quicksum(p[u] for u in U) == d, "demand")

    # objective
    model.setObjective(quicksum(F[u] for u in U), "minimize")

    model.data = p
    return model
Example #11
0
def gpp(V,E):
    """gpp -- model for the graph partitioning problem
    Parameters:
        - V: set/list of nodes in the graph
        - E: set/list of edges in the graph
    Returns a model, ready to be solved.
    """
    model = Model("gpp")

    x = {}
    y = {}
    for i in V:
        x[i] = model.addVar(vtype="B", name="x(%s)"%i)
    for (i,j) in E:
        y[i,j] = model.addVar(vtype="B", name="y(%s,%s)"%(i,j))

    model.addCons(quicksum(x[i] for i in V) == len(V)/2, "Partition")

    for (i,j) in E:
        model.addCons(x[i] - x[j] <= y[i,j], "Edge(%s,%s)"%(i,j))
        model.addCons(x[j] - x[i] <= y[i,j], "Edge(%s,%s)"%(j,i))

    model.setObjective(quicksum(y[i,j] for (i,j) in E), "minimize")

    model.data = x
    return model
def test_circle():
    points =[
            (2.802686, 1.398947),
            (4.719673, 4.792101),
            (1.407758, 7.769566),
            (2.253320, 2.373641),
            (8.583144, 9.769102),
            (3.022725, 5.470335),
            (5.791380, 1.214782),
            (8.304504, 8.196392),
            (9.812677, 5.284600),
            (9.445761, 9.541600)]

    m = Model()
    a = m.addVar('a', lb=None)
    b = m.addVar('b', ub=None)
    r = m.addVar('r')

    # minimize radius
    m.setObjective(r, 'minimize')

    for i,p in enumerate(points):
        # NOTE: SCIP will not identify this as SOC constraints!
        m.addCons( sqrt((a - p[0])**2 + (b - p[1])**2) <= r, name = 'point_%d'%i)

    m.optimize()

    bestsol = m.getBestSol()
    assert abs(m.getSolVal(bestsol, r) - 5.2543) < 1.0e-3
    assert abs(m.getSolVal(bestsol, a) - 6.1242) < 1.0e-3
    assert abs(m.getSolVal(bestsol, b) - 5.4702) < 1.0e-3
def sils(T,f,c,d,h):
    """sils -- LP lotsizing for the single item lot sizing problem
    Parameters:
        - T: number of periods
        - P: set of products
        - f[t]: set-up costs (on period t)
        - c[t]: variable costs
        - d[t]: demand values
        - h[t]: holding costs
    Returns a model, ready to be solved.
    """
    model = Model("single item lotsizing")
    Ts = range(1,T+1)
    M = sum(d[t] for t in Ts)
    y,x,I = {},{},{}
    for t in Ts:
        y[t] = model.addVar(vtype="I", ub=1, name="y(%s)"%t)
        x[t] = model.addVar(vtype="C", ub=M, name="x(%s)"%t)
        I[t] = model.addVar(vtype="C", name="I(%s)"%t)
    I[0] = 0

    for t in Ts:
        model.addCons(x[t] <= M*y[t], "ConstrUB(%s)"%t)
        model.addCons(I[t-1] + x[t] == I[t] + d[t], "FlowCons(%s)"%t)

    model.setObjective(\
        quicksum(f[t]*y[t] + c[t]*x[t] + h[t]*I[t] for t in Ts),\
        "minimize")

    model.data = y,x,I
    return model
Example #14
0
def gcp(V,E,K):
    """gcp -- model for minimizing the number of colors in a graph
    Parameters:
        - V: set/list of nodes in the graph
        - E: set/list of edges in the graph
        - K: upper bound on the number of colors
    Returns a model, ready to be solved.
    """
    model = Model("gcp")
    x,y = {},{}
    for k in range(K):
        y[k] = model.addVar(vtype="B", name="y(%s)"%k)
        for i in V:
            x[i,k] = model.addVar(vtype="B", name="x(%s,%s)"%(i,k))

    for i in V:
        model.addCons(quicksum(x[i,k] for k in range(K)) == 1, "AssignColor(%s)"%i)

    for (i,j) in E:
        for k in range(K):
            model.addCons(x[i,k] + x[j,k] <= y[k], "NotSameColor(%s,%s,%s)"%(i,j,k))

    model.setObjective(quicksum(y[k] for k in range(K)), "minimize")

    model.data = x
    return model
Example #15
0
def mctransp(I,J,K,c,d,M):
    """mctransp -- model for solving the Multi-commodity Transportation Problem
    Parameters:
        - I: set of customers
        - J: set of facilities
        - K: set of commodities
        - c[i,j,k]: unit transportation cost on arc (i,j) for commodity k
        - d[i][k]: demand for commodity k at node i
        - M[j]: capacity
    Returns a model, ready to be solved.
    """

    model = Model("multi-commodity transportation")

    # Create variables
    x = {}

    for (i,j,k) in c:
        x[i,j,k] = model.addVar(vtype="C", name="x(%s,%s,%s)" % (i,j,k))

    # Demand constraints
    for i in I:
        for k in K:
            model.addCons(sum(x[i,j,k] for j in J if (i,j,k) in x) == d[i,k], "Demand(%s,%s)" % (i,k))

    # Capacity constraints
    for j in J:
        model.addCons(sum(x[i,j,k] for (i,j2,k) in x if j2 == j) <= M[j], "Capacity(%s)" % j)

    # Objective
    model.setObjective(quicksum(c[i,j,k]*x[i,j,k]  for (i,j,k) in x), "minimize")

    model.data = x

    return model
Example #16
0
def test_lpi():
    # create LP instance
    myLP = LP()

    myLP.addRow(entries = [(0,1),(1,2)] ,lhs = 5)
    lhs, rhs = myLP.getSides()
    assert lhs[0] == 5.0
    assert rhs[0] == myLP.infinity()

    assert(myLP.ncols() == 2)
    myLP.chgObj(0, 1.0)
    myLP.chgObj(1, 2.0)

    solval = myLP.solve()
    # create solver instance

    s = Model()
    # add some variables
    x = s.addVar("x", obj=1.0)
    y = s.addVar("y", obj=2.0)
    # add some constraint
    s.addCons(x + 2*y >= 5)
    # solve problem
    s.optimize()

    # check solution
    assert round(s.getVal(x)) == 5.0
    assert round(s.getVal(y)) == 0.0

    assert round(s.getObjVal() == solval)
Example #17
0
def transp(I,J,c,d,M):
    """transp -- model for solving the transportation problem
    Parameters:
        I - set of customers
        J - set of facilities
        c[i,j] - unit transportation cost on arc (i,j)
        d[i] - demand at node i
        M[j] - capacity
    Returns a model, ready to be solved.
    """

    model = Model("transportation")

    # Create variables
    x = {}

    for i in I:
        for j in J:
            x[i,j] = model.addVar(vtype="C", name="x(%s,%s)" % (i, j))

    # Demand constraints
    for i in I:
        model.addCons(quicksum(x[i,j] for j in J if (i,j) in x) == d[i], name="Demand(%s)" % i)

    # Capacity constraints
    for j in J:
        model.addCons(quicksum(x[i,j] for i in I if (i,j) in x) <= M[j], name="Capacity(%s)" % j)

    # Objective
    model.setObjective(quicksum(c[i,j]*x[i,j]  for (i,j) in x), "minimize")

    model.optimize()

    model.data = x
    return model
Example #18
0
def mtz_strong(n,c):
    """mtz_strong: Miller-Tucker-Zemlin's model for the (asymmetric) traveling salesman problem
    (potential formulation, adding stronger constraints)
    Parameters:
        n - number of nodes
        c[i,j] - cost for traversing arc (i,j)
    Returns a model, ready to be solved.
    """

    model = Model("atsp - mtz-strong")
    
    x,u = {},{}
    for i in range(1,n+1):
        u[i] = model.addVar(lb=0, ub=n-1, vtype="C", name="u(%s)"%i)
        for j in range(1,n+1):
            if i != j:
                x[i,j] = model.addVar(vtype="B", name="x(%s,%s)"%(i,j))

    for i in range(1,n+1):
        model.addCons(quicksum(x[i,j] for j in range(1,n+1) if j != i) == 1, "Out(%s)"%i)
        model.addCons(quicksum(x[j,i] for j in range(1,n+1) if j != i) == 1, "In(%s)"%i)

    for i in range(1,n+1):
        for j in range(2,n+1):
            if i != j:
                model.addCons(u[i] - u[j] + (n-1)*x[i,j] + (n-3)*x[j,i] <= n-2, "LiftedMTZ(%s,%s)"%(i,j))

    for i in range(2,n+1):
        model.addCons(-x[1,i] - u[i] + (n-3)*x[i,1] <= -2, name="LiftedLB(%s)"%i)
        model.addCons(-x[i,1] + u[i] + (n-3)*x[1,i] <= n-2, name="LiftedUB(%s)"%i)

    model.setObjective(quicksum(c[i,j]*x[i,j] for (i,j) in x), "minimize")
    
    model.data = x,u
    return model
Example #19
0
def weber(I,x,y,w):
    """weber: model for solving the single source weber problem using soco.
    Parameters:
        - I: set of customers
        - x[i]: x position of customer i
        - y[i]: y position of customer i
        - w[i]: weight of customer i
    Returns a model, ready to be solved.
    """

    model = Model("weber")

    X,Y,z,xaux,yaux = {},{},{},{},{}
    X = model.addVar(lb=-model.infinity(), vtype="C", name="X")
    Y = model.addVar(lb=-model.infinity(), vtype="C", name="Y")
    for i in I:
        z[i] = model.addVar(vtype="C", name="z(%s)"%(i))
        xaux[i] = model.addVar(lb=-model.infinity(), vtype="C", name="xaux(%s)"%(i))
        yaux[i] = model.addVar(lb=-model.infinity(), vtype="C", name="yaux(%s)"%(i))

    for i in I:
        model.addCons(xaux[i]*xaux[i] + yaux[i]*yaux[i] <= z[i]*z[i], "MinDist(%s)"%(i))
        model.addCons(xaux[i] == (x[i]-X), "xAux(%s)"%(i))
        model.addCons(yaux[i] == (y[i]-Y), "yAux(%s)"%(i))

    model.setObjective(quicksum(w[i]*z[i] for i in I), "minimize")

    model.data = X,Y,z
    return model
Example #20
0
def eoq_soco(I,F,h,d,w,W):
    """eoq_soco --  multi-item capacitated economic ordering quantity model using soco
    Parameters:
        - I: set of items
        - F[i]: ordering cost for item i
        - h[i]: holding cost for item i
        - d[i]: demand for item i
        - w[i]: unit weight for item i
        - W: capacity (limit on order quantity)
    Returns a model, ready to be solved.
    """
    model = Model("EOQ model using SOCO")

    T,c = {},{}
    for i in I:
        T[i] = model.addVar(vtype="C", name="T(%s)"%i)  # cycle time for item i
        c[i] = model.addVar(vtype="C", name="c(%s)"%i)  # total cost for item i

    for i in I:
        model.addCons(F[i] <= c[i]*T[i])

    model.addCons(quicksum(w[i]*d[i]*T[i] for i in I) <= W)

    model.setObjective(quicksum(c[i] + h[i]*d[i]*T[i]*0.5 for i in I), "minimize")

    model.data = T,c
    return model
Example #21
0
def gcp_fixed_k(V,E,K):
    """gcp_fixed_k -- model for minimizing number of bad edges in coloring a graph
    Parameters:
        - V: set/list of nodes in the graph
        - E: set/list of edges in the graph
        - K: number of colors to be used
    Returns a model, ready to be solved.
    """
    model = Model("gcp - fixed k")

    x,z = {},{}
    for i in V:
        for k in range(K):
            x[i,k] = model.addVar(vtype="B", name="x(%s,%s)"%(i,k))
    for (i,j) in E:
        z[i,j] = model.addVar(vtype="B", name="z(%s,%s)"%(i,j))

    for i in V:
        model.addCons(quicksum(x[i,k] for k in range(K)) == 1, "AssignColor(%s)" % i)

    for (i,j) in E:
        for k in range(K):
            model.addCons(x[i,k] + x[j,k] <= 1 + z[i,j], "BadEdge(%s,%s,%s)"%(i,j,k))

    model.setObjective(quicksum(z[i,j] for (i,j) in E), "minimize")

    model.data = x,z
    return model
def flp_nonlinear_sos(I,J,d,M,f,c,K):
    """flp_nonlinear_sos --  use model with SOS constraints
    Parameters:
        - I: set of customers
        - J: set of facilities
        - d[i]: demand for customer i
        - M[j]: capacity of facility j
        - f[j]: fixed cost for using a facility in point j
        - c[i,j]: unit cost of servicing demand point i from facility j
        - K: number of linear pieces for approximation of non-linear cost function
    Returns a model, ready to be solved.
    """
    a,b = {},{}
    for j in J:
        U = M[j]
        L = 0
        width = U/float(K)
        a[j] = [k*width for k in range(K+1)]
        b[j] = [f[j]*math.sqrt(value) for value in a[j]]

    model = Model("nonlinear flp -- use model with SOS constraints")
    
    x = {}
    for j in J:
        for i in I:
            x[i,j] = model.addVar(vtype="C", name="x(%s,%s)"%(i,j))  # i's demand satisfied from j
    
    # total volume transported from plant j, corresponding (linearized) cost, selection variable:
    X,F,z = {},{},{}
    for j in J:
        # add constraints for linking piecewise linear part:
        X[j],F[j],z[j] = convex_comb_sos(model,a[j],b[j])
        X[j].ub = M[j]
        # for i in I:
        #     model.addCons(
        #         x[i,j] <= \
        #         quicksum(min(d[i],a[j][k+1]) * (z[j][k] + z[j][k+1])\
        #                  for k in range(len(a[j])-1)),
        #         "Strong(%s,%s)"%(i,j))

    # constraints for customer's demand satisfaction
    for i in I:
        model.addCons(quicksum(x[i,j] for j in J) == d[i], "Demand(%s)"%i)

    for j in J:
        model.addCons(quicksum(x[i,j] for i in I) == X[j], "Capacity(%s)"%j)

    model.setObjective(quicksum(F[j] for j in J) +\
                       quicksum(c[i,j]*x[i,j] for j in J for i in I),\
                       "minimize")
    
    model.data = x,X,F
    return model
Example #23
0
def test_knapsack():
    # create solver instance
    s = Model("Knapsack")
    s.hideOutput()

    # setting the objective sense to maximise
    s.setMaximize()

    # item weights
    weights = [4, 2, 6, 3, 7, 5]
    # item costs
    costs = [7, 2, 5, 4, 3, 4]

    assert len(weights) == len(costs)

    # knapsack size
    knapsackSize = 15

    # adding the knapsack variables
    knapsackVars = []
    varNames = []
    varBaseName = "Item"
    for i in range(len(weights)):
        varNames.append(varBaseName + "_" + str(i))
        knapsackVars.append(s.addVar(varNames[i], vtype='I', obj=costs[i], ub=1.0))


    # adding a linear constraint for the knapsack constraint
    coeffs = {knapsackVars[i]: weights[i] for i in range(len(weights))}
    s.addCons(coeffs, lhs=None, rhs=knapsackSize)

    # solve problem
    s.optimize()

    s.printStatistics()

    # retrieving the best solution
    solution = s.getBestSol()

    # print solution
    varSolutions = []
    for i in range(len(weights)):
        solValue = round(s.getVal(knapsackVars[i], solution))
        varSolutions.append(solValue)
        if solValue > 0:
            print (varNames[i], "Times Selected:", solValue)
            print ("\tIncluded Weight:", weights[i]*solValue, "\tItem Cost:", costs[i]*solValue)

        s.releaseVar(knapsackVars[i])

    includedWeight = sum([weights[i]*varSolutions[i] for i in range(len(weights))])
    assert includedWeight > 0 and includedWeight <= knapsackSize
Example #24
0
def test_niceqcqp():
    s = Model()

    x = s.addVar("x")
    y = s.addVar("y")
    s.addCons(x*x + y*y <= 2)
    s.setObjective(x + y, sense='maximize')

    s.optimize()

    assert round(s.getVal(x)) == 1.0
    assert round(s.getVal(y)) == 1.0

    s.free()
def test_largequadratic():
    # inspired from performance issue on
    # http://stackoverflow.com/questions/38434300

    m = Model("dense_quadratic")
    dim = 200
    x = [m.addVar("x_%d" % i) for i in range(dim)]
    expr = quicksum((i+j+1)*x[i]*x[j]
                    for i in range(dim)
                    for j in range(dim))
    cons = expr <= 1.0
    #                              upper triangle,     diagonal
    assert len(cons.expr.terms) == dim * (dim-1) / 2 + dim
    m.addCons(cons)
Example #26
0
def kcenter(I,J,c,k):
    """kcenter -- minimize the maximum travel cost from customers to k facilities.
    Parameters:
        - I: set of customers
        - J: set of potential facilities
        - c[i,j]: cost of servicing customer i from facility j
        - k: number of facilities to be used
    Returns a model, ready to be solved.
    """

    model = Model("k-center")
    z = model.addVar(vtype="C", name="z")
    x,y = {},{}

    for j in J:
        y[j] = model.addVar(vtype="B", name="y(%s)"%j)
        for i in I:
            x[i,j] = model.addVar(vtype="B", name="x(%s,%s)"%(i,j))


    for i in I:
        model.addCons(quicksum(x[i,j] for j in J) == 1, "Assign(%s)"%i)

        for j in J:
            model.addCons(x[i,j] <= y[j], "Strong(%s,%s)"%(i,j))
            model.addCons(c[i,j]*x[i,j] <= z, "Max_x(%s,%s)"%(i,j))

    model.addCons(quicksum(y[j] for j in J) == k, "Facilities")

    model.setObjective(z, "minimize")
    model.data = x,y

    return model
def p_portfolio(I,sigma,r,alpha,beta):
    """p_portfolio -- modified markowitz model for portfolio optimization.
    Parameters:
        - I: set of items
        - sigma[i]: standard deviation of item i
        - r[i]: revenue of item i
        - alpha: acceptance threshold
        - beta: desired confidence level
    Returns a model, ready to be solved.
    """

    model = Model("p_portfolio")

    x = {}
    for i in I:
        x[i] = model.addVar(vtype="C", name="x(%s)"%i)  # quantity of i to buy
    rho = model.addVar(vtype="C", name="rho")
    rhoaux = model.addVar(vtype="C", name="rhoaux")

    model.addCons(rho == quicksum(r[i]*x[i] for i in I))
    model.addCons(quicksum(x[i] for i in I) == 1)

    model.addCons(rhoaux == (alpha - rho)*(1/phi_inv(beta))) #todo
    model.addCons(quicksum(sigma[i]**2 * x[i] * x[i] for i in I) <=  rhoaux * rhoaux)

    model.setObjective(rho, "maximize")

    model.data = x
    return model
Example #28
0
def test_niceqp():
    s = Model()

    x = s.addVar("x")
    y = s.addVar("y")
    s.addCons(x >= 2)
    s.addCons(x*x <= y)
    s.setObjective(y, sense='minimize')

    s.optimize()

    assert round(s.getVal(x)) == 2.0
    assert round(s.getVal(y)) == 4.0

    s.free()
Example #29
0
def maxflow(V,M,source,sink):
    """maxflow: maximize flow from source to sink, taking into account arc capacities M
    Parameters:
        - V: set of vertices
        - M[i,j]: dictionary or capacity for arcs (i,j)
        - source: flow origin
        - sink: flow target
    Returns a model, ready to be solved.
        """
    # create max-flow underlying model, on which to find cuts
    model = Model("maxflow")
    
    f = {} # flow variable
    for (i,j) in M:
        f[i,j] = model.addVar(lb=-M[i,j], ub=M[i,j], name="flow(%s,%s)"%(i,j))

    cons = {}
    for i in V:
        if i != source and i != sink:
            cons[i] = model.addCons(
                quicksum(f[i,j] for j in V if i<j and (i,j) in M) - \
                quicksum(f[j,i] for j in V if i>j and (j,i) in M) == 0,
                "FlowCons(%s)"%i)

    model.setObjective(quicksum(f[i,j] for (i,j) in M if i==source), "maximize")

    # model.write("tmp.lp")
    model.data = f,cons
    return model
Example #30
0
def staff(I,T,N,J,S,c,b):
    """
    staff: staff scheduling
    Parameters:
        - I: set of members in the staff
        - T: number of periods in a cycle
        - N: number of working periods required for staff's elements in a cycle
        - J: set of shifts in each period (shift 0 == rest)
        - S: subset of shifts that must be kept at least consecutive days
        - c[i,t,j]: cost of a shift j of staff's element i on period t
        - b[t,j]: number of staff elements required in period t, shift j
    Returns a model, ready to be solved.
    """
    Ts = range(1,T+1)
    model = Model("staff scheduling")

    x = {}
    for t in Ts:
        for j in J:
            for i in I:
                x[i,t,j] = model.addVar(vtype="B", name="x(%s,%s,%s)" % (i,t,j))


    model.setObjective(quicksum(c[i,t,j]*x[i,t,j] for i in I for t in Ts for j in J if j != 0),
                       "minimize")

    for t in Ts:
        for j in J:
            if j == 0:
                continue
            model.addCons(quicksum(x[i,t,j] for i in I) >= b[t,j], "Cover(%s,%s)" % (t,j))
    for i in I:
        model.addCons(quicksum(x[i,t,j] for t in Ts for j in J if j != 0) == N, "Work(%s)"%i)
        for t in Ts:
            model.addCons(quicksum(x[i,t,j] for j in J) == 1, "Assign(%s,%s)" % (i,t))
            for j in J:
                if j != 0:
                    model.addCons(x[i,t,j] + quicksum(x[i,t,k] for k in J if k != j and k != 0) <= 1,\
                                    "Require(%s,%s,%s)" % (i,t,j))
        for t in range(2,T):
            for j in S:
                model.addCons(x[i,t-1,j] + x[i,t+1,j] >= x[i,t,j], "SameShift(%s,%s,%s)" % (i,t,j))


    model.data = x
    return model
Example #31
0
def solve_it(input_data):
    # Modify this code to run your optimization algorithm

    # parse the input
    lines = input_data.split('\n')

    nodeCount = int(lines[0])

    points = []
    for i in range(1, nodeCount + 1):
        line = lines[i]
        parts = line.split()
        points.append(Point(float(parts[0]), float(parts[1])))

    cost_matrix = np.zeros((nodeCount, nodeCount), dtype="float32")
    for i in range(nodeCount):
        for j in range(i, nodeCount):
            cost_matrix[i, j] = length(points[i], points[j])
    cost_matrix = pd.DataFrame(cost_matrix)
    cost_matrix = cost_matrix + cost_matrix.transpose()

    model = Model("tsp")
    model.hideOutput()
    xs = cost_matrix.applymap(lambda x: model.addVar(vtype="B"))
    us = pd.Series(range(nodeCount)).map(lambda x: model.addVar(vtype="I"))

    for index, row in xs.iterrows():
        model.addCons(row.sum() == 1)
    for index, col in xs.iteritems():
        model.addCons(col.sum() == 1)

    # (xs + xs.transpose()).applymap(lambda const: model.addCons(const <=1))
    for i in range(nodeCount):
        for j in range(nodeCount):
            if i > j:
                model.addCons(xs[j][i] + xs[i][j] <= 1)
            if i == j:
                model.addCons(xs[i][j] == 0)
            if 0 < i and i != j:
                model.addCons(
                    us[i] - us[j] + nodeCount * xs[i][j] <= nodeCount - 1)

    objective = (xs * cost_matrix).sum().sum()
    model.setObjective(objective)
    model.setMinimize()

    model.setRealParam("limits/time", 30)
    model.optimize()
    print({
        "status": model.getStatus(),
        "obj": model.getObjVal(),
        "time": model.getTotalTime()
    })
    result = xs.applymap(model.getVal)
    route = np.argmax(result.values, axis=1)

    start = 0
    solution = []
    for i in range(nodeCount):
        start = route[start]
        solution.append(start)
    # build a trivial solution
    # visit the nodes in the order they appear in the file

    # # calculate the length of the tour
    obj = total_length_by_order(points, solution)

    # prepare the solution in the specified output format
    output_data = '%.2f' % obj + ' ' + str(0) + '\n'
    output_data += ' '.join(map(str, solution))

    return output_data
Example #32
0
def mcf(n, c):
    """mcf: multi-commodity flow formulation for the (asymmetric) traveling salesman problem
    Parameters:
        - n: number of nodes
        - c[i,j]: cost for traversing arc (i,j)
    Returns a model, ready to be solved.
    """
    model = Model("mcf")

    x, f = {}, {}
    for i in range(1, n + 1):
        for j in range(1, n + 1):
            if i != j:
                x[i, j] = model.addVar(vtype="B", name="x(%s,%s)" % (i, j))
            if i != j and j != 1:
                for k in range(2, n + 1):
                    if i != k:
                        f[i, j,
                          k] = model.addVar(ub=1,
                                            vtype="C",
                                            name="f(%s,%s,%s)" % (i, j, k))

    for i in range(1, n + 1):
        model.addCons(
            quicksum(x[i, j] for j in range(1, n + 1) if j != i) == 1,
            "Out(%s)" % i)
        model.addCons(
            quicksum(x[j, i] for j in range(1, n + 1) if j != i) == 1,
            "In(%s)" % i)

    for k in range(2, n + 1):
        model.addCons(
            quicksum(f[1, i, k] for i in range(2, n + 1)
                     if (1, i, k) in f) == 1, "FlowOut(%s)" % k)
        model.addCons(
            quicksum(f[i, k, k] for i in range(1, n + 1)
                     if (i, k, k) in f) == 1, "FlowIn(%s)" % k)

        for i in range(2, n + 1):
            if i != k:
                model.addCons(quicksum(f[j,i,k] for j in range(1,n+1) if (j,i,k) in f) == \
                                quicksum(f[i,j,k] for j in range(1,n+1) if (i,j,k) in f),
                                "FlowCons(%s,%s)"%(i,k))

    for (i, j, k) in f:
        model.addCons(f[i, j, k] <= x[i, j], "FlowUB(%s,%s,%s)" % (i, j, k))

    model.setObjective(quicksum(c[i, j] * x[i, j] for (i, j) in x), "minimize")

    model.data = x, f
    return model
Example #33
0
def mils_fl(T,P,f,g,c,d,h,M):
    """
    mils_fl: facility location formulation for the multi-item lot-sizing problem

    Requires more variables, but gives a better solution because LB is
    better than the standard formulation.  It can be used as a
    heuristic method that is sometimes better than relax-and-fix.

    Parameters:
        - T: number of periods
        - P: set of products
        - f[t,p]: set-up costs (on period t, for product p)
        - g[t,p]: set-up times
        - c[t,p]: variable costs
        - d[t,p]: demand values
        - h[t,p]: holding costs
        - M[t]:   resource upper bound on period t
    Returns a model, ready to be solved.
    """
    Ts = range(1,T+1)

    model = Model("multi-item lotsizing -- facility location formulation")

    y,X = {},{}
    for p in P:
        for t in Ts:
            y[t,p] = model.addVar(vtype="B", name="y(%s,%s)"%(t,p))
            for s in range(1,t+1):
                X[s,t,p] = model.addVar(name="X(%s,%s,%s)"%(s,t,p))


    for t in Ts:
        # capacity constraints
        model.addCons(quicksum(X[t,s,p] for s in range(t,T+1) for p in P) + \
                        quicksum(g[t,p]*y[t,p] for p in P) <= M[t],
                        "Capacity(%s)"%(t))

        for p in P:
            # demand satisfaction constraints
            model.addCons(quicksum(X[s,t,p] for s in range(1,t+1)) == d[t,p], "Demand(%s,%s)"%(t,p))

            # connection constraints
            for s in range(1,t+1):
                model.addCons(X[s,t,p] <= d[t,p] * y[s,p], "Connect(%s,%s,%s)"%(s,t,p))

    C = {} # variable costs plus holding costs
    for p in P:
        for s in Ts:
            sumC = 0
            for t in range(s,T+1):
                C[s,t,p] = (c[s,p] + sumC)
                sumC += h[t,p]

    model.setObjective(quicksum(f[t,p]*y[t,p] for t in Ts for p in P) + \
                       quicksum(C[s,t,p]*X[s,t,p] for t in Ts for p in P for s in range(1,t+1)),
                       "minimize")


    model.data = y,X
    model.write("tmp.lp")
    return model
Example #34
0
class MipModel:
    """Models the connected subgraph problem via mixed integer programming."""
    def __init__(self,
                 prob_input: Input,
                 hide_output: bool = True,
                 *,
                 binary_variables: bool = False) -> None:
        self.model = Model()
        if hide_output:
            self.model.hideOutput()
        self._prob_input = prob_input
        self._edge_vars = dict()
        self._node_vars = dict()
        self.__add_non_terminal_vars(binary_variables)
        self.__add_edge_vars(binary_variables)

    @property
    def graph_edges(self):
        return self._prob_input.edges

    @property
    def terminals(self):
        return self._prob_input.terminals

    @property
    def non_terminals(self):
        return self._prob_input.non_terminals

    @property
    def node_costs(self):
        return self._prob_input.costs

    @property
    def node_profits(self):
        return self._prob_input.profits

    @property
    def budget(self):
        return self._prob_input.budget

    @property
    def edge_vars(self):
        return self._edge_vars

    @property
    def non_terminal_vars(self):
        return self._node_vars

    @property
    def positive_non_terminal_vars(self):
        return {
            v: self.model.getVal(var)
            for v, var in self.non_terminal_vars.items()
            if self.model.getVal(var) > 0.
        }

    @property
    def positive_edge_vars(self):
        return {
            v: self.model.getVal(var)
            for v, var in self.edge_vars.items() if self.model.getVal(var) > 0.
        }

    def __add_edge_vars(self, binary: bool) -> None:
        """Creates variables for graph edges and adds them to the solver model."""
        for edge in self.graph_edges:
            name = f'x_{edge}'
            self.edge_vars[edge] = self.model.addVar(
                vtype='B' if binary else 'C', lb=0, ub=1, name=name)
        module_logger.debug(f'Added {len(self.graph_edges)} edge variables.')

    def __add_non_terminal_vars(self, binary: bool) -> None:
        """Creates variables for non-terminal nodes and adds them to the solver model."""
        for node in self.non_terminals:
            name = f'y_{node}'
            self.non_terminal_vars[node] = self.model.addVar(
                vtype='B' if binary else 'C', lb=0, ub=1, name=name)
        module_logger.debug(
            f'Added {len(self.non_terminal_vars)} node variables.')

    def add_cardinality_constraint(self) -> None:
        """Creates an equality constraint where the rhs corresponds to the sum over all
        edge variables and the lhs corresponds to the sum over all non-terminal node variables plus
        the number of terminals minus 1. In other words, x(E) = y(N) + |T| - 1.
        """
        rhs_vars = (self.non_terminal_vars.get(n) for n in self.non_terminals)
        self.model.addCons(quicksum(
            self.edge_vars.values()) == quicksum(rhs_vars) +
                           len(self.terminals) - 1,
                           name='card_cons')
        if logging.root.level >= logging.DEBUG:
            lhs_str = " + ".join(str(e) for e in self.edge_vars.values())
            rhs_str = " + ".join(
                str(i) for i in rhs_vars) + str(len(self.terminals) - 1)
            module_logger.debug(
                f'Added cardinality constraint: {lhs_str} == {rhs_str}')

    def add_budget_constraint(self) -> None:
        """Ensures that the weight taken over all selected nodes is less or equal than the budget.
        """
        lhs = [(self.node_costs[v], var)
               for v, var in self.non_terminal_vars.items()]
        rhs = self.budget - quicksum(self.node_costs[t]
                                     for t in self.terminals)
        self.model.addCons(quicksum(weight * var
                                    for weight, var in lhs) <= rhs,
                           name='weight_cons')
        if logging.root.level >= logging.DEBUG:
            lhs_str = " + ".join(str(weight) + str(var) for weight, var in lhs)
            module_logger.debug(f'Added budged constraint: {lhs_str} <= {rhs}')

    def max_profits(self) -> None:
        """Maximises the profit taken over all non-terminal nodes."""
        obj = [(self.node_profits[v], var)
               for v, var in self.non_terminal_vars.items()]
        self.model.setObjective(quicksum(profit * var for profit, var in obj),
                                "maximize")
        if logging.root.level >= logging.DEBUG:
            obj_str = " + ".join(str(profit) + str(var) for profit, var in obj)
            module_logger.debug(f'Added objective: {obj_str}')
Example #35
0
def test_model():
    # create solver instance
    s = Model()

    # add some variables
    x = s.addVar("x", vtype = 'C', obj = 1.0)
    y = s.addVar("y", vtype = 'C', obj = 2.0)

    assert x.getObj() == 1.0
    assert y.getObj() == 2.0

    s.setObjective(4.0 * y + 10.5, clear = False)
    assert x.getObj() == 1.0
    assert y.getObj() == 4.0
    assert s.getObjoffset() == 10.5

    # add some constraint
    c = s.addCons(x + 2 * y >= 1.0)
    assert c.isLinear()
    s.chgLhs(c, 5.0)
    s.chgRhs(c, 6.0)

    assert s.getLhs(c) == 5.0
    assert s.getRhs(c) == 6.0

    badsolution = s.createSol()
    s.setSolVal(badsolution, x, 2.0)
    s.setSolVal(badsolution, y, 2.0)
    assert s.getSlack(c, badsolution) == 0.0
    assert s.getSlack(c, badsolution, 'lhs') == 1.0
    assert s.getSlack(c, badsolution, 'rhs') == 0.0
    assert s.getActivity(c, badsolution) == 6.0
    s.freeSol(badsolution)

    # solve problem
    s.optimize()

    solution = s.getBestSol()

    # print solution
    assert (s.getVal(x) == s.getSolVal(solution, x))
    assert (s.getVal(y) == s.getSolVal(solution, y))
    assert round(s.getVal(x)) == 5.0
    assert round(s.getVal(y)) == 0.0
    assert s.getSlack(c, solution) == 0.0
    assert s.getSlack(c, solution, 'lhs') == 0.0
    assert s.getSlack(c, solution, 'rhs') == 1.0
    assert s.getActivity(c, solution) == 5.0

    s.freeProb()
    s = Model()
    x = s.addVar("x", vtype = 'C', obj = 1.0)
    y = s.addVar("y", vtype = 'C', obj = 2.0)
    c = s.addCons(x + 2 * y <= 1.0)
    s.setMaximize()

    s.delCons(c)

    s.optimize()

    assert s.getStatus() == 'unbounded'
Example #36
0
from pyscipopt import Model

model = Model("Animal quiz")

x = model.addVar(vtype="I", name="octopus")
y = model.addVar(vtype="I", name="turtel")
z = model.addVar(vtype="I", name="bird")

model.addCons(x + y + z == 32, name="Heads")
model.addCons(8 * x + 4 * y + 2 * z == 80, name="Legs")

model.setObjective(x + y, "minimize")

model.hideOutput()
model.optimize()

print("Optimal value:", model.getObjVal())
print((x.name, y.name, z.name), " = ",
      (model.getVal(x), model.getVal(y), model.getVal(z)))
Example #37
0
    def calc_damage(self):
        data = self.data

        # 各サブステ x とダメージ倍率 f(x) の関係式を2次関数で近似。パラメータa,b,cは要調整。
        # 係数: 	# f(x) = ax^2 + bx + c
        # scipを使う関係上、連続な関数を使用せざるを得ない。下記参照リンクの計算式の床関数もガン無視。なので多少誤差が出る(コンマ%くらい?)。
        # reference: http://allaganstudies.akhmorning.com/guide/damage/
        self.lmd_fdh = lambda x: 4.1667e-5 * x + 1

        self.lmd_fch = lambda x: (3.6732e-9 * x + 2.7271e-5) * x + 0.02 + 1

        self.lmd_fdt = lambda x: 3.9394e-05 * x + 1

        self.lmd_fss_gdc = lambda x: (2.13073e-9 * x + 3.81069e-5) * x + 1
        self.lmd_fss_dot_aa = lambda x: 3.9394e-05 * x + 1

        self.lmd_fss =  lambda x: self.rate_ss * self.lmd_fss_gdc(x) \
              + (self.rate_aa+self.rate_dot) * self.lmd_fss_dot_aa(x) \
              + (1-(self.rate_ss+self.rate_aa+self.rate_dot)) * 1

        self.lmd_ftn = lambda x: 3.0303e-5 * x + 1

        self.lmd_fpi = lambda x: 1  # 信仰値はダメージ倍率に影響なし

        self.expr_min = lambda x, y: (x + y) / 2 - abs(
            x - y) / 2  # min関数をscipが読める形に置き換える。
        # サブステの装備内での上限値を考慮するために必要。

        model = Model("calc_damage_multiplier")
        objvar = model.addVar("objvar", lb=1.0, ub=None, vtype="C")
        model.setObjective(objvar, "maximize")

        #### def variables for SCIP ####
        _is_chosen = {}
        # ex_m = {}
        ex_m_dh = {}
        ex_m_ch = {}
        ex_m_dt = {}
        ex_m_ss = {}
        ex_m_tn = {}
        ex_m_pi = {}
        # mg_m = {}
        mg_m_dh = {}
        mg_m_ch = {}
        mg_m_dt = {}
        mg_m_ss = {}
        mg_m_tn = {}
        mg_m_pi = {}
        # subst = {}
        dh = {}
        ch = {}
        dt = {}
        ss = {}
        tn = {}
        pi = {}

        for eq in data:
            # 各装備に対するエクス装着数
            ex_m_dh[eq] = model.addVar(name="ex_m_dh_" + eq, vtype="I", lb=0)
            ex_m_ch[eq] = model.addVar(name="ex_m_ch_" + eq, vtype="I", lb=0)
            ex_m_dt[eq] = model.addVar(name="ex_m_dt_" + eq, vtype="I", lb=0)
            ex_m_ss[eq] = model.addVar(name="ex_m_ss_" + eq, vtype="I", lb=0)
            ex_m_tn[eq] = model.addVar(name="ex_m_tn_" + eq, vtype="I", lb=0)
            ex_m_pi[eq] = model.addVar(name="ex_m_pi_" + eq, vtype="I", lb=0)
            # 制約条件:1装備当たりのエクス装着数が、装着可能な個数の上限を超えない
            model.addCons(
                ex_m_dh[eq] + ex_m_ch[eq] + ex_m_dt[eq] + ex_m_ss[eq] +
                ex_m_tn[eq] + ex_m_pi[eq] <= data[eq]["ex_m"])

            # 各装備に対するメガ装着数
            mg_m_dh[eq] = model.addVar(name="mg_m_dh_" + eq, vtype="I", lb=0)
            mg_m_ch[eq] = model.addVar(name="mg_m_ch_" + eq, vtype="I", lb=0)
            mg_m_dt[eq] = model.addVar(name="mg_m_dt_" + eq, vtype="I", lb=0)
            mg_m_ss[eq] = model.addVar(name="mg_m_ss_" + eq, vtype="I", lb=0)
            mg_m_tn[eq] = model.addVar(name="mg_m_tn_" + eq, vtype="I", lb=0)
            mg_m_pi[eq] = model.addVar(name="mg_m_pi_" + eq, vtype="I", lb=0)
            # 制約条件:1装備当たりのメガ装着数が、装着可能な個数の上限を超えない
            model.addCons(
                mg_m_dh[eq] + mg_m_ch[eq] + mg_m_dt[eq] + mg_m_ss[eq] +
                mg_m_tn[eq] + mg_m_pi[eq] <= data[eq]["mg_m"])

            ######## どちらの装備を選択したほうがよいかを変数にして解いてみる。
            _is_chosen[eq] = []
            if len(data[eq]["dh"]) == 1:
                _is_chosen[eq].append(
                    model.addVar(name=eq + "_0", vtype="B", lb=0, ub=1))
                model.addCons(_is_chosen[eq][0] <= 1)
            else:
                _is_chosen[eq].append(
                    model.addVar(name=eq + "_0", vtype="B", lb=0,
                                 ub=1))  # 要修正。3以上の時。
                _is_chosen[eq].append(
                    model.addVar(name=eq + "_1", vtype="B", lb=0, ub=1))
                model.addCons(_is_chosen[eq][0] + _is_chosen[eq][1] <= 1)
                # model.addCons(quicksum(_is_chosen[eq][i] for i in range(len(_is_chosen[eq]))) <= 1)
            ########

            # tmp_dh = 60*ex_m_dh[eq] + 20*mg_m_dh[eq] + data[eq]["dh"][0]
            # tmp_ch = 60*ex_m_ch[eq] + 20*mg_m_ch[eq] + data[eq]["ch"][0]
            # tmp_dt = 60*ex_m_dt[eq] + 20*mg_m_dt[eq] + data[eq]["dt"][0]
            # tmp_ss = 60*ex_m_ss[eq] + 20*mg_m_ss[eq] + data[eq]["ss"][0]

            ########
            tmp_dh = 60*ex_m_dh[eq] + 20*mg_m_dh[eq] \
              + quicksum( data[eq]["dh"][i][0]*_is_chosen[eq][i] for i in range(len(_is_chosen[eq])) )
            tmp_ch = 60*ex_m_ch[eq] + 20*mg_m_ch[eq] \
              + quicksum( data[eq]["ch"][i][0]*_is_chosen[eq][i] for i in range(len(_is_chosen[eq])) )
            tmp_dt = 60*ex_m_dt[eq] + 20*mg_m_dt[eq] \
              + quicksum( data[eq]["dt"][i][0]*_is_chosen[eq][i] for i in range(len(_is_chosen[eq])) )
            tmp_ss = 60*ex_m_ss[eq] + 20*mg_m_ss[eq] \
              + quicksum( data[eq]["ss"][i][0]*_is_chosen[eq][i] for i in range(len(_is_chosen[eq])) )
            tmp_tn = 60*ex_m_tn[eq] + 20*mg_m_tn[eq] \
              + quicksum( data[eq]["tn"][i][0]*_is_chosen[eq][i] for i in range(len(_is_chosen[eq])) )
            tmp_pi = 60*ex_m_pi[eq] + 20*mg_m_pi[eq] \
              + quicksum( data[eq]["pi"][i][0]*_is_chosen[eq][i] for i in range(len(_is_chosen[eq])) )

            # マテリアにより上昇するサブステが、サブステ上限値を超えないようにする
            dh[eq] = self.expr_min(tmp_dh, data[eq]["dh"][0][1])
            ch[eq] = self.expr_min(tmp_ch, data[eq]["ch"][0][1])
            dt[eq] = self.expr_min(tmp_dt, data[eq]["dt"][0][1])
            ss[eq] = self.expr_min(tmp_ss, data[eq]["ss"][0][1])
            tn[eq] = self.expr_min(tmp_tn, data[eq]["tn"][0][1])
            pi[eq] = self.expr_min(tmp_pi, data[eq]["pi"][0][1])

        dh_sum = quicksum(dh[eq] for eq in data)
        ch_sum = quicksum(ch[eq] for eq in data)
        dt_sum = quicksum(dt[eq] for eq in data)
        ss_sum = quicksum(ss[eq] for eq in data)
        tn_sum = quicksum(tn[eq] for eq in data)
        pi_sum = quicksum(pi[eq] for eq in data)

        #### damage efficiency in each substatuses ####
        fdh = self.lmd_fdh(dh_sum)
        fch = self.lmd_fch(ch_sum)
        fdt = self.lmd_fdt(dt_sum)
        fss = self.lmd_fss(ss_sum)
        ftn = self.lmd_ftn(tn_sum)
        fpi = self.lmd_fpi(pi_sum)
        model.addCons(objvar <= fdh * fch * fdt * fss * ftn *
                      fpi)  # 制約条件(目的関数):ダメージ効率を最大化する

        #### SS調整 ####
        model.addCons(ss_sum >= self.ss_lower)  # 制約条件: SSが少なくとも X 以上

        ## 信仰調整 ##
        model.addCons(pi_sum >= self.pi_lower)  # 制約条件: 信仰が少なくとも X 以上

        #### optimize ####
        model.optimize()
        sol = model.getBestSol()

        #### show result ####
        ## 注意:	addVar()で vtype="I" や "B" として宣言した変数(整数変数、バイナリ変数)は、
        ##			解を取得するために getVal() を呼ぶと、値が float 型で返ってくるので気を付けること。
        num_eq = {}
        result = {}
        for eq in data:
            ########
            print(_is_chosen[eq])
            num_eq[eq] = [round(model.getVal(v))
                          for v in _is_chosen[eq]].index(1)
            ########
            result[eq] = {}
            result[eq]["dh"] = (
                min(
                    60 * round(model.getVal(ex_m_dh[eq])) +
                    20 * round(model.getVal(mg_m_dh[eq])) +
                    data[eq]["dh"][num_eq[eq]][0],
                    data[eq]["dh"][num_eq[eq]][1]),
                data[eq]["dh"][num_eq[eq]][1],
            )
            result[eq]["ch"] = (
                min(
                    60 * round(model.getVal(ex_m_ch[eq])) +
                    20 * round(model.getVal(mg_m_ch[eq])) +
                    data[eq]["ch"][num_eq[eq]][0],
                    data[eq]["ch"][num_eq[eq]][1]),
                data[eq]["ch"][num_eq[eq]][1],
            )
            result[eq]["dt"] = (
                min(
                    60 * round(model.getVal(ex_m_dt[eq])) +
                    20 * round(model.getVal(mg_m_dt[eq])) +
                    data[eq]["dt"][num_eq[eq]][0],
                    data[eq]["dt"][num_eq[eq]][1]),
                data[eq]["dt"][num_eq[eq]][1],
            )
            result[eq]["ss"] = (
                min(
                    60 * round(model.getVal(ex_m_ss[eq])) +
                    20 * round(model.getVal(mg_m_ss[eq])) +
                    data[eq]["ss"][num_eq[eq]][0],
                    data[eq]["ss"][num_eq[eq]][1]),
                data[eq]["ss"][num_eq[eq]][1],
            )
            result[eq]["tn"] = (
                min(
                    60 * round(model.getVal(ex_m_tn[eq])) +
                    20 * round(model.getVal(mg_m_tn[eq])) +
                    data[eq]["tn"][num_eq[eq]][0],
                    data[eq]["tn"][num_eq[eq]][1]),
                data[eq]["tn"][num_eq[eq]][1],
            )
            result[eq]["pi"] = (
                min(
                    60 * round(model.getVal(ex_m_pi[eq])) +
                    20 * round(model.getVal(mg_m_pi[eq])) +
                    data[eq]["pi"][num_eq[eq]][0],
                    data[eq]["pi"][num_eq[eq]][1]),
                data[eq]["pi"][num_eq[eq]][1],
            )

        # 装備品のみのサブステ
        equip_dh = sum([data[eq]["dh"][num_eq[eq]][0] for eq in data])
        equip_ch = sum([data[eq]["ch"][num_eq[eq]][0] for eq in data])
        equip_dt = sum([data[eq]["dt"][num_eq[eq]][0] for eq in data])
        equip_ss = sum([data[eq]["ss"][num_eq[eq]][0] for eq in data])
        equip_tn = sum([data[eq]["tn"][num_eq[eq]][0] for eq in data])
        equip_pi = sum([data[eq]["pi"][num_eq[eq]][0] for eq in data])
        subst_init = equip_dh + equip_ch + equip_dt + equip_ss + equip_tn + equip_pi

        # マテリアのみのサブステ
        subst_materia_dh = sum([result[eq]["dh"][0]
                                for eq in result]) - equip_dh
        subst_materia_ch = sum([result[eq]["ch"][0]
                                for eq in result]) - equip_ch
        subst_materia_dt = sum([result[eq]["dt"][0]
                                for eq in result]) - equip_dt
        subst_materia_ss = sum([result[eq]["ss"][0]
                                for eq in result]) - equip_ss
        subst_materia_tn = sum([result[eq]["tn"][0]
                                for eq in result]) - equip_tn
        subst_materia_pi = sum([result[eq]["pi"][0]
                                for eq in result]) - equip_pi
        subst_materia = subst_materia_dh + subst_materia_ch + subst_materia_dt + subst_materia_ss + subst_materia_tn + subst_materia_pi

        fdh_sol = self.lmd_fdh(equip_dh + subst_materia_dh)
        fch_sol = self.lmd_fch(equip_ch + subst_materia_ch)
        fdt_sol = self.lmd_fdt(equip_dt + subst_materia_dt)
        fss_sol = self.lmd_fss(equip_ss + subst_materia_ss)
        fss_dot_aa_sol = self.lmd_fss_dot_aa(equip_ss + subst_materia_ss)
        fss_gdc_sol = self.lmd_fss_gdc(equip_ss + subst_materia_ss)
        ftn_sol = self.lmd_ftn(equip_tn + subst_materia_tn)
        fpi_sol = self.lmd_fpi(equip_pi + subst_materia_pi)

        print(sol)
        print("Optimal value:", model.getObjVal())
        print("")
        print("")
        print("            エクス              |メガ              | サブステ")
        print(
            "            dh ch dt ss tn pi|dh ch dt ss tn pi|     dh           ch           dt           ss           tn           pi"
        )
        for eq in data:
            ex_m_dh_num = round(model.getVal(ex_m_dh[eq]))
            ex_m_ch_num = round(model.getVal(ex_m_ch[eq]))
            ex_m_dt_num = round(model.getVal(ex_m_dt[eq]))
            ex_m_ss_num = round(model.getVal(ex_m_ss[eq]))
            ex_m_tn_num = round(model.getVal(ex_m_tn[eq]))
            ex_m_pi_num = round(model.getVal(ex_m_pi[eq]))

            mg_m_dh_num = round(model.getVal(mg_m_dh[eq]))
            mg_m_ch_num = round(model.getVal(mg_m_ch[eq]))
            mg_m_dt_num = round(model.getVal(mg_m_dt[eq]))
            mg_m_ss_num = round(model.getVal(mg_m_ss[eq]))
            mg_m_tn_num = round(model.getVal(mg_m_tn[eq]))
            mg_m_pi_num = round(model.getVal(mg_m_pi[eq]))

            tmp_form = lambda x: str(x) if x > 0 else "-"

            string = "{0:10s}: {1}  {2}  {3}  {4}  {5}  {6} |{7}  {8}  {9}  {10}  {11}  {12} |{13:4d}  +{14:3d}   {15:4d}  +{16:3d}   {17:4d}  +{18:3d}   {19:4d}  +{20:3d}   {21:4d}  +{22:3d}   {23:4d}  +{24:3d}"
            print(
                string.format(
                    eq,
                    tmp_form(ex_m_dh_num),
                    tmp_form(ex_m_ch_num),
                    tmp_form(ex_m_dt_num),
                    tmp_form(ex_m_ss_num),
                    tmp_form(ex_m_tn_num),
                    tmp_form(ex_m_pi_num),
                    tmp_form(mg_m_dh_num),
                    tmp_form(mg_m_ch_num),
                    tmp_form(mg_m_dt_num),
                    tmp_form(mg_m_ss_num),
                    tmp_form(mg_m_tn_num),
                    tmp_form(mg_m_pi_num),
                    data[eq]["dh"][num_eq[eq]][0],
                    round(result[eq]["dh"][0]) - data[eq]["dh"][num_eq[eq]][0],
                    data[eq]["ch"][num_eq[eq]][0],
                    round(result[eq]["ch"][0]) - data[eq]["ch"][num_eq[eq]][0],
                    data[eq]["dt"][num_eq[eq]][0],
                    round(result[eq]["dt"][0]) - data[eq]["dt"][num_eq[eq]][0],
                    data[eq]["ss"][num_eq[eq]][0],
                    round(result[eq]["ss"][0]) - data[eq]["ss"][num_eq[eq]][0],
                    data[eq]["tn"][num_eq[eq]][0],
                    round(result[eq]["tn"][0]) - data[eq]["tn"][num_eq[eq]][0],
                    data[eq]["pi"][num_eq[eq]][0],
                    round(result[eq]["pi"][0]) - data[eq]["pi"][num_eq[eq]][0],
                ))

        print("")
        print(num_eq)
        print("")
        print("サブステ 装備	: {0:4.0f}".format(subst_init))
        print("サブステ マテリア	: {0:4.0f}".format(subst_materia))
        print("サブステ 総数	: {0:4.0f}".format(subst_init + subst_materia))
        print("")
        print("                       Equip  Materia")
        print("dh(ダイレクトヒット)	: {0:4.0f} ({1:4.0f} +  {2:4.0f})".format(
            equip_dh + subst_materia_dh, equip_dh, subst_materia_dh))
        print("ch(クリティカルヒット)	: {0:4.0f} ({1:4.0f} +  {2:4.0f})".format(
            equip_ch + subst_materia_ch, equip_ch, subst_materia_ch))
        print("dt(意思力)	: {0:4.0f} ({1:4.0f} +  {2:4.0f})".format(
            equip_dt + subst_materia_dt, equip_dt, subst_materia_dt))
        print("ss(スキルスピード)	: {0:4.0f} ({1:4.0f} +  {2:4.0f})".format(
            equip_ss + subst_materia_ss, equip_ss, subst_materia_ss))
        print("tn(不屈)	: {0:4.0f} ({1:4.0f} +  {2:4.0f})".format(
            equip_tn + subst_materia_tn, equip_tn, subst_materia_tn))
        print("pi(信仰)	: {0:4.0f} ({1:4.0f} +  {2:4.0f})".format(
            equip_pi + subst_materia_pi, equip_pi, subst_materia_pi))
        print("")
        self.show_eff(fdh_sol, fch_sol, fdt_sol, fss_sol, fss_gdc_sol,
                      fss_dot_aa_sol, ftn_sol, fpi_sol)

        # memo
        # 解に対する変数の値が知りたい場合
        # print(sol[dh])
        # print(model.getSolVal(sol, dh))
        # print(model.getVal(dh))

        # 解に対する式の値が知りたい場合
        # print(model.getSolVal(sol, fdh))
        # print(model.getVal(fdh))

        print("******** 厳密解 ********")
        rtn = self.calc_exact_dmg_multiplier(equip_dh + subst_materia_dh,
                                             equip_ch + subst_materia_ch,
                                             equip_dt + subst_materia_dt,
                                             equip_ss + subst_materia_ss,
                                             equip_tn + subst_materia_tn,
                                             equip_pi + subst_materia_pi)
        self.show_eff(*rtn)
Example #38
0
def updateCopyNum(B,
                  F,
                  S,
                  CRefer,
                  cells,
                  alpha=0.1,
                  root=0,
                  vType='C',
                  Cap=False):
    tumors = B.shape[0]
    cellsTotal = cells + CRefer.shape[0]
    copyNum = B.shape[1]
    m = Model('phylo')

    C = {}
    for i in range(cells):
        for j in range(copyNum):
            C[i, j] = m.addVar(vtype=vType, name='C(%s,%s)' % (i, j))

    bDelta = {}
    for i in range(tumors):
        for j in range(copyNum):
            bDelta[i, j] = m.addVar(vtype='C', name='bDelta(%s,%s)' % (i, j))

    for p in range(tumors):
        for s in range(copyNum):
            expr = B[p, s]
            for k in range(cells):
                expr += -(F[p, k] * C[k, s])
            m.addCons(bDelta[p, s] - (expr) >= 0, name='resu(%s,%s)' % (p, s))
            m.addCons(bDelta[p, s] + (expr) >= 0, name='resl(%s,%s)' % (p, s))
    for k in range(cells):
        for s in range(copyNum):
            m.addCons(C[k, s] >= 0, name='pos(%s,%s)' % (k, s))

    if (Cap == True):
        for k in range(cells):
            for s in range(copyNum):
                m.addCons(C[k, s] <= 10, name='cap(%s,%s)' % (k, s))

    wDelta = {}
    for i in range(cellsTotal):
        for j in range(cellsTotal):
            for k in range(copyNum):
                wDelta[i, j, k] = m.addVar(vtype='C',
                                           name='wDelta(%s,%s,%s)' % (i, j, k))

    for u in range(cellsTotal):
        for v in range(cellsTotal):
            for i in range(copyNum):
                if (u < cells):
                    Cui = C[u, i]
                else:
                    Cui = CRefer[u - cells, i]
                if (v < cells):
                    Cvi = C[v, i]
                else:
                    Cvi = CRefer[v - cells, i]
                m.addCons(wDelta[u, v, i] - Cui + Cvi >= 0,
                          name='delu(%s,%s,%s)' % (u, v, i))
                m.addCons(wDelta[u, v, i] - Cvi + Cui >= 0,
                          name='dell(%s,%s,%s)' % (u, v, i))

    objExpr = quicksum(bDelta[i, j] for i in range(tumors)
                       for j in range(copyNum))
    for u in range(cellsTotal):
        for v in range(cellsTotal):
            objExpr += alpha * quicksum(wDelta[u, v, i]
                                        for i in range(copyNum)) * S[u, v]

    m.setObjective(objExpr, 'minimize')
    m.optimize()

    #print('Total Obj:', m.getObjVal())
    # 2 is OPTIMAL

    Cresult = np.zeros([cells, copyNum], dtype=np.float)
    for k in range(cells):
        for s in range(copyNum):
            Cresult[k, s] = m.getVal(C[k, s])

    objVal = m.getObjVal()
    return [Cresult, objVal]
Example #39
0
def optimize_schedule(prefs,
                      LP_input,
                      grades,
                      teacher,
                      GAP,
                      requirements=None,
                      prox=None,
                      save_location=None):
    """
	Runs the optimizer in SCIP

	Parameters
	----------
	prefs 	- a Pandas DataFrame containing the student preferences

	LP_Input- a Pandas DataFrame coming from a clean_data function, that serves
			  as the main input to the LP, it must have columns:
				Course Name
				Double Period
				Max
				Min
				Required Grades
				Number of Instances
				Room Type

	grades 	- a Pandas DataFrame that has all the students and their grade

	prox 	- a Padnas DataFrame that serves as the proximity matrix for courses

	teacher_info - a Padnas DataFrame that list all courses and the teacher
				   that will be teaching it

	Gap 	- the number from the GUI slider we will use to determine 
			  what MIPGap to run the solver with

	Requirements - List of requirement objects that were solicited from the user
				   these are then iterated over, parsed, and coded


	NOTE: most of the commented out stuff is from a previous iteration
	where the data was being pulled from various .csv files, I have included
	it as a helper if we need to go back and de-bug and see how it once worked
	when the data was coming from somewhere else

	NOTE 2: The commented out variables, constraints, and other optimization
	code is for Gurobi, the non-commented is for SCIP
	"""
    # prefs.to_csv("OptTestFiles/prefs.csv")
    # LP_input.to_csv("OptTestFiles/LP_input.csv")
    # teacher.to_csv("OptTestFiles/teacher.csv")

    start_time = timeit.default_timer()

    # --------------------------------------------------------
    # 						Read Data
    # --------------------------------------------------------
    # prefs = pd.read_csv("Resources/FlatChoicesBinary.csv")
    # courses = pd.read_csv("Resources/FlatCourseSize.csv")
    #prox = pd.read_csv("Resources/Proximity.csv")
    prox = pd.read_csv("../Resources/Proximity.csv")
    #prox.to_csv("OptTestFiles/prox.csv")
    #teacher = pd.read_csv("../Resources/Teacher_Info.csv", header=None)
    # course_rooms = pd.read_csv("Resources/CourseRoomReqs.csv")
    grades = pd.read_csv("../Resources/grades.csv", header=None)
    #grades.to_csv("OptTestFiles/grades.csv")

    # clean it up
    prefs.rename(columns={"Unnamed: 0": "Student"}, inplace=True)
    # courses.rename(columns={"0":"Class"}, inplace=True)
    # courses.drop("Unnamed: 0", axis=1, inplace=True)

    # NEW DATA
    #df = pd.read_csv("Resources/LP_Input.csv")
    df = LP_input

    # --------------------------------------------------------
    #					Pull out sets
    # --------------------------------------------------------
    # Extract sets
    S = prefs["Student"].tolist(
    )  # list of all students (once we get ID make dictionary)

    # Cd = {} # Course dictionary
    # for i in courses.index:
    #     Cd[i] = courses["Class"].iloc[i]
    Cd = {}
    for i in df.index:
        Cd[i] = df["Course Name"].iloc[i]

    for i in Cd:
        print(i, Cd[i])

    C = range(len(Cd))

    # Gather "Other Indicies"
    other_indicies = []
    for j in Cd:
        if "Other" in Cd[j]:
            other_indicies.append(j)

    T = [1, 2, 3, 4, 7, 8]  # Periods

    ## Instructors and corerspondence
    I = list(set(teacher[0]))
    DW_courses = list(set(teacher[1]))

    # Grades for each student
    Grades = grades[1]

    # Extract Preferences
    P = prefs.drop("Student", axis=1).as_matrix()

    # Double periods
    # Db = courses["Double"].fillna(0).astype(int)
    Db = df["Double Period"].fillna(0).astype(int)
    Db = Db.values

    # Course Sizes (min and max)
    # MIN = courses["Min"]
    # MAX = courses["Max"]
    MIN = df["Min"]
    MIN = MIN.values
    MAX = df["Max"]
    MAX = MAX.values

    # To check feasibility:
    # MIN = [3]*len(C)
    # MAX = [40]*len(C)

    # Proximity Matrix
    D = prox.drop("0", axis=1).as_matrix()

    # Create Proximity dictionary {subject:proximity vector}
    prox_dict = {}
    Subjects = list(prox.columns)[1:]
    for subj in list(prox.columns)[1:]:
        prox_dict[subj] = prox[subj]

    # Required Courses
    # grade_requirements = {}
    # for grade in [5,6,7,8,9,10,11,12]:
    # 	grade_requirements[grade] = df.index[df['Required Grades'] == grade].tolist()

    # # remove empties
    # for g in grade_requirements.keys():
    # 	if grade_requirements[g] == []:
    # 		del grade_requirements[g]

    # --------------------------------------------------------
    #                  Multi-Instance Course list
    # --------------------------------------------------------
    # Look through input to determine which courses are multi-input
    # Create a list of these courses (only the first half of the double
    # if it is a double course)
    multi = df["Number of Instances"].fillna(0).astype(int)
    # print("\n\n\nMulti is:\n\n")
    # print(multi)
    # print("\n\n\nMulti of a single index\n\n")
    # print("Multi is of type", type(multi))
    # print("At a single index", multi[2])
    # print("At a single index with get", multi.get(2))
    # print("type when trying to convert", type(multi[0]))
    multi = multi.values
    # print("\n\n\nMulti (values) is:\n\n")
    # print(multi)
    # print("\n\n\nMulti of a single index\n\n")
    # print("Multi is of type", type(multi))
    # print("At a single index", multi[2])
    # #print("At a single index with get", multi.get(2))
    # print("type when trying to convert", type(multi[0]))
    multi_nested_list = []
    j = 0
    while j < len(Cd):
        # if it is part of multi-instance cluster
        if multi[j] == 2:
            #print("testing multi[j] ==2 with j=", j, "multi[j]=",multi[j])
            #if int(multi.get(j)) == 2:
            # if it is a double period
            if Db[j] == 1:
                new = [j, j + 2]
                j += 4  # pass over cluster
            else:
                # not a double period
                new = [j, j + 1]
                j += 2
            multi_nested_list.append(new)
        # if not a multi-instance
        elif multi[j] == 3:
            # these can't be double periods so just drop in all 3
            multi_nested_list.append([j, j + 1, j + 2])
            j += 3
        else:
            j += 1

    # ignore OTHER in multi-instance (these have 6 next to them)

    # --------------------------------------------------------
    #					Map Teachers to Courses
    # --------------------------------------------------------
    # Need matrix with instructors as rows, all courses as columns, and 1 if teaching that course
    I_C_dict = {}
    for i in I:
        I_C_dict[i] = []
        for index in range(teacher.shape[0]):
            if teacher.iloc[index][0] == i:
                l = I_C_dict[i]
                l.append(teacher.iloc[index][1])
                I_C_dict[i] = l

    # Teacher_Course_Matrix
    courses_list = list(Cd.values())
    Teacher_Course_Matrix = np.zeros(len(courses_list))
    for i in I:
        t = np.zeros(len(courses_list))
        for j in Cd:
            if Cd[j] in I_C_dict[i]:
                # print(i, "is teaching:", (40-len(i)-12)*".", Cd[j])
                t[j] = 1
        Teacher_Course_Matrix = np.vstack(
            [Teacher_Course_Matrix, np.matrix(t)])

    Ta = np.array(Teacher_Course_Matrix[1:]
                  )  # matrix tying teachers to courses they teach

    # --------------------------------------------------------
    #					Set up Room Data
    # --------------------------------------------------------
    # Set of rooms
    R = [
        "U1", "Steve", "U2", "U3", "U4/5", "U6", "U7", "L2", "L3", "Library",
        "Art", "L4", "L6", "Sci A", "Sci B", "Sci C", "Music Room", "Gym",
        "Gym2"
    ]

    # Department Courses
    Science_Rooms = ["Sci A", "Sci B", "Sci C"]
    Art_Rooms = ["Art"]
    Gym_Rooms = ["Gym", "Gym2"]
    Music_Rooms = ["Music Room"]
    Free_Rooms = list(
        set(R) - set(Science_Rooms + Art_Rooms + Gym_Rooms + Music_Rooms))

    # Science_Courses = course_rooms["Science"]
    # Art_Courses = course_rooms["Art"]
    # Gym_Courses = course_rooms["Gym"]
    # Music_Courses = course_rooms["Music"]
    # Free_Courses = course_rooms["Free"]
    #Resource_Courses = course_rooms["Resource"]

    # Get courses for each room type (Art, Science, Gym, Music, Resource)
    Art_Courses = df.index[df['Room Type'] == "Art"].tolist()
    Science_Courses = df.index[df['Room Type'] == "Science"].tolist()
    Gym_Courses = df.index[df['Room Type'] == "Gym"].tolist()
    Music_Courses = df.index[df['Room Type'] == "Music"].tolist()
    Resource_Courses = df.index[df['Room Type'] == "Resource"].tolist()

    room_constrained_subjects = ["Science", "Art", "Music", "Gym"]
    constrained_rooms = {
        "Science": Science_Rooms,
        "Art": Art_Rooms,
        "Music": Music_Rooms,
        "Gym": Gym_Rooms
    }
    constrained_courses = {
        "Science": Science_Courses,
        "Art": Art_Courses,
        "Music": Music_Courses,
        "Gym": Gym_Courses
    }

    #------------------------------------------------------------
    #------------------------------------------------------------

    #------------------------------------------------------------
    #------------------------------------------------------------
    #					Start Model Setup
    #------------------------------------------------------------
    #------------------------------------------------------------
    # Create Model instance
    m = Model("Schedule")

    # Trackers--to verify what SCIP/GB says
    num_vars = 0
    num_cons = 0

    #------------------------------------------------------------
    #						Create Variables
    #------------------------------------------------------------
    print("Adding variables")
    # Add Student Variables (X)
    X = {}
    for i in S:
        for j in range(len(C)):
            name = "Student " + str(i) + " in course " + str(j)
            # X[i,j] = m.addVar(vtype=GRB.BINARY, name=name)
            X[i, j] = m.addVar(vtype="B", name=name)
            num_vars += 1
    print("\tStudent/Course variable added")

    # Add Course Variable
    Course = {}  # Variable dictionary
    for j in range(len(C)):
        for t in T:
            name = "Course " + str(j) + " in period " + str(t)
            # Course[j,t] = m.addVar(vtype=GRB.BINARY, name=name)
            Course[j, t] = m.addVar(vtype="B", name=name)
            num_vars += 1
    print("\tCourse/Period variable added")

    # Create the u variable
    U = {}
    for i in S:
        for j in range(len(C)):
            for t in T:
                name = "min " + str(i) + ", " + str(j) + ", " + str(t)
                # U[i,j,t] = m.addVar(vtype=GRB.BINARY, name=name)
                U[i, j, t] = m.addVar(vtype="B", name=name)
                num_vars += 1
    print("\tU(Student/Course/Period) variable added")

    # Define r  room variable (over course j in room r durring period t)
    Rv = {}
    for j in range(len(C)):
        if "Other" not in Cd[j] and "Empty" not in Cd[j]:
            for s in R:
                for t in T:
                    name = "Course " + str(j) + " in room " + str(s) + \
                      " durring period " + str(t)
                    # Rv[j,s,t] = m.addVar(vtype=GRB.BINARY, name=name)
                    Rv[j, s, t] = m.addVar(vtype="B", name=name)
                    num_vars += 1
    print("\tRoom/Period Variables added")

    #------------------------------------------------------------
    #------------------------------------------------------------
    #						Add Constraints
    #------------------------------------------------------------
    #------------------------------------------------------------
    print("Adding constraints")

    # Force student in one course per period
    for i in S:
        for t in T:
            # m.addConstr(quicksum(U[i,j,t] for j in C) == 1) # one course per period
            m.addCons(quicksum(U[i, j, t]
                               for j in C) == 1)  # one course per period
            num_cons += 1
    print("\tOne course per period")

    # "AND" Constraint--no more than one course per period for a student
    for i in S:
        for j in C:
            # m.addConstr(X[i,j] == quicksum(U[i,j,t] for t in T))
            m.addCons(X[i, j] == quicksum(U[i, j, t] for t in T))
            num_cons += 1
            for t in T:
                # m.addConstr(Course[j,t] >= U[i,j,t])
                m.addCons(Course[j, t] >= U[i, j, t])
                num_cons += 1
    print("\tU set-up constraints (`and`) added")

    # must have preffed the course (minus the requirements)
    # 8th graders must be in Researchers (j=88)
    # 9th Graders in 1 of African Studies (8), or Latrin American Studies (61)
    # 6th Graders in People and Lit (78,80), or Inquiry and Tools (52,54)
    for i in S:
        for j in Cd:
            if Grades[i] == 8 and j == 88:
                pass
            elif Grades[i] == 9 and (j in [8, 9, 61, 62]):
                pass
            elif Grades[i] == 6 and (j in [78, 79, 80, 81, 52, 53, 54, 55]):
                # so many as these are alternates and doubles
                pass
            else:
                # m.addConstr(X[i,j] <= P[i][j])
                m.addCons(X[i, j] <= P[i][j])
                num_cons += 1
    print("\tStudents in courses they prefer")

    # g = 0
    # for i in S:
    # 	if Grades[i] == 9:
    # 		if P[i][8] == 1:
    # 			g += 1

    # Add capacity and minimum constraint
    print("Are we having the same problem with MAX?:", MAX[0])
    for j in range(len(C)):
        # m.addConstr(quicksum(X[i,j] for i in S) <= MAX[j])
        m.addCons(quicksum(X[i, j] for i in S) <= MAX[j])
        #m.addConstr(quicksum(X[i,j] for i in S) <= 100)
        #m.addConstr(quicksum(X[i,j] for i in S) >= MIN[j])
        m.addCons(quicksum(X[i, j] for i in S) >= MIN[j])
        num_cons += 2
    print("\tCourse capacity")

    #------------------------------------------------------------
    #					Proximity Constraints
    #------------------------------------------------------------

    # Setup proximity min and max dicts (temp untill we generate more granular data)
    min_sub_dict = {}
    max_sub_dict = {}
    for subject in Subjects:
        min_sub_dict[subject] = np.ones(len(S)) * 0
        max_sub_dict[subject] = np.ones(len(S)) * 3
        # it works when max is 6 --> I think the constraints are written correctly?
        # infeasible when 5, very suspicious

    # # proximity by subject
    #for subject in Subjects:
    # print("min_sub_dict:", min_sub_dict)
    # print("max_sub_dict:", max_sub_dict)
    # print("Prox_dict", prox_dict.keys())
    # print("Prox_dict['Other']", prox_dict["Other"])
    # print("Prox_dict['K']", prox_dict["K"])
    # print(prox_dict["Other"][0])
    # print("\n\nRun over all j for Other")
    # print("Cd is", Cd )
    # for j in Cd:
    # 	print("j:", j)
    # 	if j == 89:
    # 		print("j is 89 so should get a 1?")
    # 	print(prox_dict["Other"][j])

    # for subject in ["K", "F", "D", "M", "IIC", "VI", "C", "IV", "IIA", "E", "I",
    # 			"H", "V", "VII", "Other", "G", "J", "IIB", "L", "IB"]: # test with limited set of subjects, trying to find issue
    # 	print("subject:", subject)
    # 	for i in S:
    # 		#print("i:", i)
    # 		if min_sub_dict[subject][i] > 0:
    # 			# m.addConstr(quicksum(prox_dict[subject][j]*X[i,j] for j in range(len(C))) >= min_sub_dict[subject][i])\
    # 			print("We have hit the interior")
    # 			m.addCons(quicksum(prox_dict[subject][j]*X[i,j] for j in range(len(C))) >= min_sub_dict[subject][i])
    # 		# do we always need a max?
    # 		# m.addConstr(quicksum(prox_dict[subject][j]*X[i,j] for j in range(len(C))) <= max_sub_dict[subject][i])
    # 		m.addCons(quicksum(prox_dict[subject][j]*X[i,j] for j in range(len(C))) <= max_sub_dict[subject][i])
    # print("\tProximity constraint added")

    print(
        "\n\nProximity constraints NOT ADDED as I don't think the files match\n\n"
    )

    #------------------------------------------------------------
    #						Teacher Constraitns
    #------------------------------------------------------------

    # Teacher teaching at most one course per period
    print("\n\nTa is:", Ta)
    print("\n\nTa Shape:", Ta.shape)
    print("\n\nCd is:", Cd)
    print("I is:", I)
    print("teacher is:", teacher)

    for j in Cd:
        print(Cd[j])

    for k in range(len(I)):
        for t in T:
            print("k:", k, "t:", t)
            # m.addConstr(quicksum(Course[j,t]*Ta[k][j] for j in C) <= 1)
            m.addCons(quicksum(Course[j, t] * Ta[k][j] for j in C) <= 1)
            num_cons += 1
    print("\tTeacher teaches as most once per period")

    #------------------------------------------------------------
    #					Course Constraints
    #------------------------------------------------------------
    # Course Taught only once Constraint
    for j in range(len(C)):
        # m.addConstr(quicksum(Course[j,t] for t in T) == 1)
        m.addCons(quicksum(Course[j, t] for t in T) == 1)
        num_cons += 1
    print("\tCourse taught only once")

    # Double period--consecutive constraints
    for j in range(len(C)):
        if Db[j] == 1:  # if double period
            for t in T:
                if t != 4 and t != 8:
                    # m.addConstr(Course[j,t] == Course[j+1, t+1]) # change to == from >=
                    m.addCons(Course[j,
                                     t] == Course[j + 1, t +
                                                  1])  # change to == from >=
                    num_cons += 1
    print("\tDouble periods must be consecutive")

    # # Double Period--not 4th or 8th
    for j in range(len(C)):
        if Db[j] == 1:
            # m.addConstr(Course[j,4] == 0)
            m.addCons(Course[j, 4] == 0)
            # m.addConstr(Course[j,8] == 0)
            m.addCons(Course[j, 8] == 0)
            num_cons += 2
    print("\tDouble periods not in 4th or 8th")

    # # Double Period--Student in both
    for i in S:
        for j in range(len(C)):
            if Db[j] == 1:
                # m.addConstr(X[i,j+1] == X[i,j]) # this was >= but == is better?
                m.addCons(X[i, j + 1] == X[i,
                                           j])  # this was >= but == is better?
                num_cons += 1
    print("\tStudents in both parts of double")

    # Multi-Instance courses (students only in one instance--at most)
    for i in S:
        for course_set in multi_nested_list:
            # in at most one course of the list
            # m.addConstr(quicksum(X[i,j] for j in course_set) <= 1)
            m.addCons(quicksum(X[i, j] for j in course_set) <= 1)
    print("\t Students in at most of instance of multi-instance Course ")

    #------------------------------------------------------------
    #					Required Courses
    #------------------------------------------------------------
    # 8th graders must be in Researchers (j=88)
    # 9th Graders in 1 of African Studies (8), or Latrin American Studies (61)
    # 6th Graders in People and Lit (78,80), or Inquiry and Tools (52,54)

    # MUST RE-IMPLEMENT THIS BASED ON THE REAUIREMENT SOLICIATIONS
    # for i in S:
    # 	if Grades[i] == 8:
    # 		m.addConstr(X[i,88] == 1)
    # 	if Grades[i] == 9:
    # 		m.addConstr(X[i,8] + X[i,61] == 1)
    # 	if Grades[i] == 6:
    # 		m.addConstr(X[i,78] + X[i,80] + X[i,52] + X[i,54] == 1)
    # print "\tGrade level course requirements"

    print("\n\n\n FIGURE OUT HOW TO CODE IN THE REQUIREMENTS \n\n\n\n")

    # for i in S:
    # 	# For each grade that has some requirement
    # 	for grade in grade_requirements.keys():
    # 		# Determine if this student a restricted grade
    # 		if Grades[i] == grade:
    # 			for i in range(len(grade_requirements[grade])):
    # 				j = grade_requirements[grade][i] # pull course index
    # 				# Determine if multi-instance
    # 				if multi[j] != 0:
    # 					# If also double
    # 					if Db[j] == 1:
    ## INCOMPLETE:
    # I am thinking about how to handle this with 6th grades who have OR conditions

    #------------------------------------------------------------
    #					Room Constraints
    #------------------------------------------------------------
    # If course taught, gets one room
    for j in range(len(C)):
        if "Other" not in Cd[j] and "Empty" not in Cd[j]:
            for t in T:
                # m.addConstr(quicksum(Rv[j,s,t] for s in R) == Course[j,t])
                m.addCons(quicksum(Rv[j, s, t] for s in R) == Course[j, t])
    print("\tCourses get one room")

    # make set of course indicies without Other and Empty
    c_mini = []
    for j in Cd:
        if "Other" not in Cd[j] and "Empty" not in Cd[j]:
            c_mini.append(j)

    # Room gets at most one course per period
    for s in R:
        for t in T:
            # m.addConstr(quicksum(Rv[j,s,t] for j in c_mini) <= 1)
            m.addCons(quicksum(Rv[j, s, t] for j in c_mini) <= 1)
    print("\tRooms get at most one course per period")

    # Double periods in the same room
    for j in Cd:
        if Db[j] == 1:
            for t in T:
                if t != 4 and t != 8:
                    for s in R:
                        # m.addConstr(Rv[j,s,t] == Rv[j+1, s, t+1])
                        m.addCons(Rv[j, s, t] == Rv[j + 1, s, t + 1])
                        num_cons += 1
    print("\tDouble Periods in same room")

    # force subject constrained courses into appropriate rooms
    # for subject in room_constrained_subjects:
    # 	sub_courses = constrained_courses[subject] # coruses in this subject
    # 	sub_rooms = constrained_rooms[subject] # appropriate rooms
    # 	for j in Cd:
    # 		if "Other" not in Cd[j] and "Empty" not in Cd[j]:
    # 			if sub_courses[j] == 1: # if course is in subject
    # 				for t in T:
    # 					m.addConstr(quicksum(Rv[j,s,t] for s in sub_rooms) == Course[j,t])
    # print "\tCourses with subject specific room needs accomodated"

    for subject in room_constrained_subjects:
        sub_courses = constrained_courses[subject]  # coruses in this subject
        sub_rooms = constrained_rooms[subject]  # appropriate rooms
        for j in sub_courses:
            for t in T:
                # m.addConstr(quicksum(Rv[j,s,t] for s in sub_rooms) == Course[j,t])
                m.addCons(
                    quicksum(Rv[j, s, t] for s in sub_rooms) == Course[j, t])
    print("\tCourses with subject specific room needs accomodated")

    #-------------------------------------------------------------
    #						Period Constraints
    #-------------------------------------------------------------
    # Force "Other" courses in specific periods
    for i in range(len(T)):
        # m.addConstr(Course[other_indicies[i], T[i]] == 1)
        m.addCons(Course[other_indicies[i], T[i]] == 1)
    print("\t`Other` courses in each period")

    # Required Courses in periods 1-4
    # Must be in begning of day
    # for j in [88, 8, 9, 61, 62, 78, 79, 80, 81, 52, 53, 54, 55]:
    # #for j in [88, 8, 9, 61, 62]:
    # 	# m.addConstr(quicksum(Course[j, t] for t in [1,2,3,4]) == 1)
    # 	m.addCons(quicksum(Course[j, t] for t in [1,2,3,4]) == 1)
    # print "\tRequired courses in periods 1 -> 4"

    # # Concurrance  (People and lit (78,80)) and (Inquire and tools (52, 54))
    # for t in T:
    # 	#m.addConstr(Course[78,t] == Course[80,t]) # ISSUE! <-----------------------------
    # 	m.addConstr(Course[52,t] == Course[54,t])
    # print "Concurrance of Multi-instance courses"

    print("TODO: MAKE SURE THE REAUIRED DOUBLE PERIOD COURSES IN MORNING?")

    print("All constraints added")

    #-------------------------------------------------------------
    #-------------------------------------------------------------
    #						Set Objective
    #-------------------------------------------------------------
    #-------------------------------------------------------------

    # Null objective
    # m.setObjective(X[1,1]*0, GRB.MAXIMIZE) # just find a feasible solution

    # Set Gap
    # m.Params.MIPGap=.3 # 30% <-- I know this is appropriate as have run quite a bit
    # m.Params.MIPGap=1
    m.setRealParam('limits/gap', GAP)
    print("GAP set")

    # Preference objective
    #m.setObjective(quicksum(X[i,j]*P[i][j] for i in S for j in C), GRB.MAXIMIZE)

    # Minimize other objective
    # m.setObjective(-1*quicksum(X[i,j] for i in S for j in other_indicies), GRB.MAXIMIZE)

    # Minimize other, and Maximize Prefs
    m.setObjective(
        -1 * quicksum(X[i, j] for i in S
                      for j in other_indicies) + quicksum(X[i, j] * P[i][j]
                                                          for i in S
                                                          for j in C),
        "maximize")

    print("Objective Set")

    # print(str(num_vars), "Variables")
    # print(str(num_cons), "Constraints")

    elapsed = timeit.default_timer() - start_time
    print("Model setup in " + str(round(elapsed, 3)) + " seconds")
    #-------------------------------------------------------------
    #							Solve
    #-------------------------------------------------------------
    # Solve model
    print("-" * 30 + "Optimization Starting" + "-" * 30)
    m.optimize()  # NOTE: solver info printed to terminal

    # What am I going to do with the solution?
    # Maybe make a solution object, that saves the variable values, along
    # with the courses, teacher names, etc. this can easily be pickled,
    # and parsed to get the schedules?

    # Save all variable values
    XV = {}
    CourseV = {}
    for i in S:
        for j in range(len(C)):
            # get student variable
            XV[i, j] = get_value(X[i, j])
            for t in T:
                CourseV[j, t] = get_value(Course[j, t])
    # get rooms
    RoomV = {}
    # for j in range(len(C)):
    for j in c_mini:
        for s in R:
            for t in T:
                RoomV[j, s, t] = get_value(Rv[j, s, t])
                #RoomV[j,s,t] = Rv[j,s,t].X

    UV = {}
    for i in S:
        for j in Cd:
            for t in T:
                UV[i, j, t] = get_value(U[i, j, t])

    # Create Solution object to faving
    solution = Solution(Cd, R, Ta, S, XV, CourseV, RoomV, UV)

    # Save the solution
    file = save_location + ".pkl"
    with open(file, "rb") as output:
        pickle.dump(solution, output, pickle.HIGHEST_PROTOCOL)

    # Return to solution object as well
    return solution
Example #40
0
from pyscipopt import Model
import time
tic = time.time()

# create model object
model = Model('exercise1')

# create variables
x = model.addVar('x', ub=3)
y = model.addVar('y', lb=0)

# objective function definition
model.setObjective(-4 * x - 2 * y, sense='minimize')

# create constrains
model.addCons(x + y <= 8)
model.addCons(8 * x + 3 * y >= -24)
model.addCons(-6 * x + 8 * y <= 48)
model.addCons(3 * x + 5 * y <= 15)

# launch optimization
model.optimize()

# get results
sol = model.getBestSol()

# display results
print('\nBest solution:')
print('x=', sol[x])
print('y=', sol[y])
Example #41
0
def updateTree(B, Ctotal, cells=None, alpha=0.1, root=0):
    tumors = B.shape[0]
    cellsTotal = Ctotal.shape[0]
    copyNum = Ctotal.shape[1]

    if (cells == None):
        cells = cellsTotal

    m = Model('phylo')

    g, S = {}, {}
    for i in range(cellsTotal):
        for j in range(cellsTotal):
            S[i, j] = m.addVar(vtype='B', name='S(%s,%s)' % (i, j))
            for k in range(cellsTotal):
                g[i, j, k] = m.addVar(vtype='B',
                                      name='g(%s,%s,%s)' % (i, j, k))

    for t in range(cellsTotal):
        for u in range(cellsTotal):
            if u != t and u != root:
                expr = 0
                for v in range(cellsTotal):
                    expr += (g[u, v, t] - g[v, u, t])
                m.addCons(expr == 0, name='conserv(%s,%s)' % (u, t))

    for t in range(cellsTotal):
        if t != root:
            m.addCons(quicksum(g[i, t, t] for i in range(cellsTotal)) == 1,
                      name='sink(%s)' % (t, ))
        m.addCons(quicksum(g[t, i, t] for i in range(cellsTotal)) == 0,
                  name='leaf(%s)' % (t, ))

    m.addCons(quicksum(g[i, root, j] for i in range(cellsTotal)
                       for j in range(cellsTotal)) == 0,
              name='root')
    for t in range(cellsTotal):
        if t != root:
            m.addCons(quicksum(g[root, i, t] for i in range(cellsTotal)) == 1,
                      name='source(%s)' % (t, ))

    for t in range(cellsTotal):
        for u in range(cellsTotal):
            for v in range(cellsTotal):
                m.addCons(S[u, v] - g[u, v, t] >= 0,
                          name='present(%s,%s,%s)' % (u, v, t))

    wDelta = getDistanceMatrix(Ctotal)

    objExpr = quicksum(S[i, j] for i in range(cellsTotal)
                       for j in range(cellsTotal))
    for u in range(cellsTotal):
        for v in range(cellsTotal):
            objExpr += wDelta[u, v] * S[u, v]

    m.setObjective(alpha * objExpr, "minimize")
    m.optimize()

    #print('Total Obj:', m.getObjVal())

    Sresult = np.zeros([cellsTotal, cellsTotal], dtype=np.int8)
    for u in range(cellsTotal):
        for v in range(cellsTotal):
            Sresult[u, v] = m.getVal(S[u, v])

    objVal = m.getObjVal()
    return [Sresult, objVal]
Example #42
0
def test_string():
    PI = 3.141592653589793238462643
    NWIRES = 11
    DIAMETERS = [0.207, 0.225, 0.244, 0.263, 0.283, 0.307, 0.331, 0.362, 0.394, 0.4375, 0.500]
    PRELOAD = 300.0
    MAXWORKLOAD = 1000.0
    MAXDEFLECT = 6.0
    DEFLECTPRELOAD = 1.25
    MAXFREELEN = 14.0
    MAXCOILDIAM = 3.0
    MAXSHEARSTRESS = 189000.0
    SHEARMOD = 11500000.0

    m = Model()
    coil = m.addVar('coildiam')
    wire = m.addVar('wirediam')
    defl = m.addVar('deflection', lb=DEFLECTPRELOAD / (MAXWORKLOAD - PRELOAD), ub=MAXDEFLECT / PRELOAD)
    ncoils = m.addVar('ncoils', vtype='I')
    const1 = m.addVar('const1')
    const2 = m.addVar('const2')
    volume = m.addVar('volume')

    y = [m.addVar('wire%d' % i, vtype='B') for i in range(NWIRES)]

    obj = 1.0 * volume
    m.setObjective(obj, 'minimize')

    m.addCons(PI/2*(ncoils + 2)*coil*wire**2 - volume == 0, name='voldef')

    m.addCons(coil / wire - const1 == 0, name='defconst1')

    m.addCons((4.0*const1 - 1.0) / (4.0*const1 - 4.0) + 0.615 / const1 - const2 == 0, name='defconst2')

    m.addCons(8.0*MAXWORKLOAD/PI*const1*const2 - MAXSHEARSTRESS*wire**2 <= 0.0, name='shear')

    m.addCons(8.0/SHEARMOD*ncoils*const1**3 / wire - defl == 0.0, name="defdefl")

    m.addCons(MAXWORKLOAD*defl + 1.05*ncoils*wire + 2.1*wire <= MAXFREELEN, name='freel')

    m.addCons(coil + wire <= MAXCOILDIAM, name='coilwidth')

    m.addCons(quicksum(c*v for (c,v) in zip(DIAMETERS, y)) - wire == 0, name='defwire')

    m.addCons(quicksum(y) == 1, name='selectwire')

    m.optimize()

    assert abs(m.getPrimalbound() - 1.6924910128) < 1.0e-6
Example #43
0
def test_gastrans():
    GASTEMP = 281.15
    RUGOSITY = 0.05
    DENSITY = 0.616
    COMPRESSIBILITY = 0.8
    nodes = [
            #   name          supplylo   supplyup pressurelo pressureup   cost
            ("Anderlues",          0.0,       1.2,       0.0,      66.2,   0.0  ),  #  0
            ("Antwerpen",         None,    -4.034,      30.0,      80.0,   0.0  ),  #  1
            ("Arlon",             None,    -0.222,       0.0,      66.2,   0.0  ),  #  2
            ("Berneau",            0.0,       0.0,       0.0,      66.2,   0.0  ),  #  3
            ("Blaregnies",        None,   -15.616,      50.0,      66.2,   0.0  ),  #  4
            ("Brugge",            None,    -3.918,      30.0,      80.0,   0.0  ),  #  5
            ("Dudzele",            0.0,       8.4,       0.0,      77.0,   2.28 ),  #  6
            ("Gent",              None,    -5.256,      30.0,      80.0,   0.0  ),  #  7
            ("Liege",             None,    -6.385,      30.0,      66.2,   0.0  ),  #  8
            ("Loenhout",           0.0,       4.8,       0.0,      77.0,   2.28 ),  #  9
            ("Mons",              None,    -6.848,       0.0,      66.2,   0.0  ),  # 10
            ("Namur",             None,    -2.120,       0.0,      66.2,   0.0  ),  # 11
            ("Petange",           None,    -1.919,      25.0,      66.2,   0.0  ),  # 12
            ("Peronnes",           0.0,      0.96,       0.0,      66.2,   1.68 ),  # 13
            ("Sinsin",             0.0,       0.0,       0.0,      63.0,   0.0  ),  # 14
            ("Voeren",          20.344,    22.012,      50.0,      66.2,   1.68 ),  # 15
            ("Wanze",              0.0,       0.0,       0.0,      66.2,   0.0  ),  # 16
            ("Warnand",            0.0,       0.0,       0.0,      66.2,   0.0  ),  # 17
            ("Zeebrugge",         8.87,    11.594,       0.0,      77.0,   2.28 ),  # 18
            ("Zomergem",           0.0,       0.0,       0.0,      80.0,   0.0  )   # 19
            ]
    arcs = [
            # node1  node2  diameter length active */
            (   18,     6,    890.0,   4.0, False ),
            (   18,     6,    890.0,   4.0, False ),
            (    6,     5,    890.0,   6.0, False ),
            (    6,     5,    890.0,   6.0, False ),
            (    5,    19,    890.0,  26.0, False ),
            (    9,     1,    590.1,  43.0, False ),
            (    1,     7,    590.1,  29.0, False ),
            (    7,    19,    590.1,  19.0, False ),
            (   19,    13,    890.0,  55.0, False ),
            (   15,     3,    890.0,   5.0,  True ),
            (   15,     3,    395.0,   5.0,  True ),
            (    3,     8,    890.0,  20.0, False ),
            (    3,     8,    395.0,  20.0, False ),
            (    8,    17,    890.0,  25.0, False ),
            (    8,    17,    395.0,  25.0, False ),
            (   17,    11,    890.0,  42.0, False ),
            (   11,     0,    890.0,  40.0, False ),
            (    0,    13,    890.0,   5.0, False ),
            (   13,    10,    890.0,  10.0, False ),
            (   10,     4,    890.0,  25.0, False ),
            (   17,    16,    395.5,  10.5, False ),
            (   16,    14,    315.5,  26.0,  True ),
            (   14,     2,    315.5,  98.0, False ),
            (    2,    12,    315.5,   6.0, False )
            ]

    scip = Model()

    # create flow variables
    flow = {}
    for arc in arcs:
        flow[arc] = scip.addVar("flow_%s_%s"%(nodes[arc[0]][0],nodes[arc[1]][0]), # names of nodes in arc
                lb = 0.0 if arc[4] else None) # no lower bound if not active

    # pressure difference variables
    pressurediff = {}
    for arc in arcs:
        pressurediff[arc] = scip.addVar("pressurediff_%s_%s"%(nodes[arc[0]][0],nodes[arc[1]][0]), # names of nodes in arc
                lb = None)

    # supply variables
    supply = {}
    for node in nodes:
        supply[node] = scip.addVar("supply_%s"%(node[0]), lb = node[1], ub = node[2], obj = node[5])

    # square pressure variables
    pressure = {}
    for node in nodes:
        pressure[node] = scip.addVar("pressure_%s"%(node[0]), lb = node[3]**2, ub = node[4]**2)


    # node balance constrains, for each node i: outflows - inflows = supply
    for nid, node in enumerate(nodes):
        # find arcs that go or end at this node
        flowbalance = 0
        for arc in arcs:
            if arc[0] == nid: # arc is outgoing
                flowbalance += flow[arc]
            elif arc[1] == nid: # arc is incoming
                flowbalance -= flow[arc]
            else:
                continue

        scip.addCons(flowbalance == supply[node], name="flowbalance%s"%node[0])

    # pressure difference constraints: pressurediff[node1 to node2] = pressure[node1] - pressure[node2]
    for arc in arcs:
        scip.addCons(pressurediff[arc] == pressure[nodes[arc[0]]] - pressure[nodes[arc[1]]], "pressurediffcons_%s_%s"%(nodes[arc[0]][0],nodes[arc[1]][0]))

    # pressure loss constraints:
    # active arc: flow[arc]^2 + coef * pressurediff[arc] <= 0.0
    # regular pipes: flow[arc] * abs(flow[arc]) - coef * pressurediff[arc] == 0.0
    # coef = 96.074830e-15*diameter(i)^5/(lambda*compressibility*temperatur*length(i)*density)
    # lambda = (2*log10(3.7*diameter(i)/rugosity))^(-2)
    from math import log10
    for arc in arcs:
        coef = 96.074830e-15 * arc[2]**5 * (2.0*log10(3.7*arc[2]/RUGOSITY))**2 / COMPRESSIBILITY / GASTEMP / arc[3] / DENSITY
        if arc[4]: # active
            scip.addCons(flow[arc]**2 + coef * pressurediff[arc] <= 0.0, "pressureloss_%s_%s"%(nodes[arc[0]][0],nodes[arc[1]][0]))
        else:
            scip.addCons(flow[arc]*abs(flow[arc]) - coef * pressurediff[arc] == 0.0, "pressureloss_%s_%s"%(nodes[arc[0]][0],nodes[arc[1]][0]))

    scip.setRealParam('limits/time', 5)
    scip.optimize()

    if scip.getStatus() == 'timelimit':
        pytest.skip()

    assert abs(scip.getPrimalbound() - 89.08584) < 1.0e-9
Example #44
0
    def pricerredcost(self):

        # Retreiving the dual solutions
        dualSolutions = []
        for i, c in enumerate(self.data['cons']):
            dualSolutions.append(self.model.getDualsolLinear(c))

        # Building a MIP to solve the subproblem
        subMIP = Model("CuttingStock-Sub")

        # Turning off presolve
        subMIP.setPresolve(SCIP_PARAMSETTING.OFF)

        # Setting the verbosity level to 0
        subMIP.hideOutput()

        cutWidthVars = []
        varNames = []
        varBaseName = "CutWidth"

        # Variables for the subMIP
        for i in range(len(dualSolutions)):
            varNames.append(varBaseName + "_" + str(i))
            cutWidthVars.append(
                subMIP.addVar(varNames[i],
                              vtype="I",
                              obj=-1.0 * dualSolutions[i]))

        # Adding the knapsack constraint
        knapsackCons = subMIP.addCons(
            quicksum(w * v for (w, v) in zip(
                self.data['widths'], cutWidthVars)) <= self.data['rollLength'])

        # Solving the subMIP to generate the most negative reduced cost pattern
        subMIP.optimize()

        objval = 1 + subMIP.getObjVal()

        # Adding the column to the master problem
        if objval < -1e-08:
            currentNumVar = len(self.data['var'])

            # Creating new var; must set pricedVar to True
            newVar = self.model.addVar("NewPattern_" + str(currentNumVar),
                                       vtype="C",
                                       obj=1.0,
                                       pricedVar=True)

            # Adding the new variable to the constraints of the master problem
            newPattern = []
            for i, c in enumerate(self.data['cons']):
                coeff = round(subMIP.getVal(cutWidthVars[i]))
                self.model.addConsCoeff(c, newVar, coeff)

                newPattern.append(coeff)

            # Storing the new variable in the pricer data.
            self.data['patterns'].append(newPattern)
            self.data['var'].append(newVar)

        return {'result': SCIP_RESULT.SUCCESS}
Example #45
0
def tsp_solver(c, customers, vehicle_tours):
    def addcut(cut_edges):
        G = networkx.Graph()
        G.add_edges_from(cut_edges)
        Components = list(networkx.connected_components(G))
        if len(Components) == 1:
            return False
        model.freeTransform()
        for S in Components:
            model.addCons(
                quicksum(x[i, j] for i in S for j in S) <= len(S) - 1)

        return True

    # Add the depot on each vehicle
    vehicle_tours = {k: vehicle_tours[k] + [0] for k in vehicle_tours.keys()}
    final_obj = 0
    final_tours = []
    for key, value in vehicle_tours.items():
        v_customers = value
        model = Model("vrp_tsp")

        x = {}

        for i in v_customers:
            for j in v_customers:
                # vehicle moves from customer i to customer j
                x[i, j] = model.addVar(vtype="B", name="x(%s,%s)" % (i, j))

        for i in v_customers:
            # Constraint: every customer can only be visited once
            # (or, every node must be connected and connect to another node)
            model.addCons(quicksum(x[i, j] for j in v_customers) == 1)
            model.addCons(quicksum(x[j, i] for j in v_customers) == 1)

            for j in v_customers:
                if i == j:
                    # Constraint: a node cannot conect to itself
                    model.addCons(x[i, j] == 0)

        # Objective function: minimize total distance of the tour
        model.setObjective(
            quicksum(x[i, j] * c[(i, j)] for i in v_customers
                     for j in v_customers), "minimize")

        EPS = 1.e-6
        isMIP = False
        while True:
            model.optimize()
            edges = []
            for (i, j) in x:
                if model.getVal(x[i, j]) > EPS:
                    edges.append((i, j))

            if addcut(edges) == False:
                if isMIP:  # integer variables, components connected: solution found
                    break
                model.freeTransform()
                for (
                        i, j
                ) in x:  # all components connected, switch to integer model
                    model.chgVarType(x[i, j], "B")
                    isMIP = True

        # model.optimize()
        best_sol = model.getBestSol()
        sub_tour = []

        # Build the graph path
        # Retrieve the last node of the graph, i.e., the last one connecting to the depot
        last_node = [n for n in edges if n[1] == 0][0][0]
        G = networkx.Graph()
        G.add_edges_from(edges)
        path = list(networkx.all_simple_paths(G, source=0, target=last_node))
        path.sort(reverse=True, key=lambda u: len(u))

        if len(path) > 0:
            path = path[0][1:]
        else:
            path = path[1:]

        obj = model.getSolObjVal(best_sol)
        final_obj += obj
        final_tours.append([customers[i] for i in path])

    return final_obj, final_tours
Example #46
0
    for b in range(1, M + 1):
        for c in range(1, G + 1):
            name = "T1_fmg_" + str(a) + ',' + str(b) + ',' + str(c)
            T1_fmg[a, b, c] = m.addVar(name, vtype='I', lb=-0.1, ub=1.1)

# 定义临时变量,降级到l级的牛奶的总量
D_fml2g = {}
for a in range(1, F + 1):
    for b in range(1, M + 1):
        for d in range(1, L + 1):
            for e in range(1, G + 1):
                name = "D_fml2g_" + str(a) + ',' + str(b) + ',' + str(
                    d) + ',' + str(e)
                D_fml2g[a, b, d, e] = m.addVar(name, vtype='I', lb=0)
                m.addCons(D_fml2g[a, b, d,
                                  e] == quicksum(D_fml1l2g[a, b, c, d, e]
                                                 for c in range(1, L + 1)))

# 临时变量,从l级降级到其他级别的牛奶总量
D_fml1g = {}
for a in range(1, F + 1):
    for b in range(1, M + 1):
        for d in range(1, L + 1):
            for e in range(1, G + 1):
                name = "D_fml1g_" + str(a) + ',' + str(b) + ',' + str(
                    d) + ',' + str(e)
                D_fml1g[a, b, d, e] = m.addVar(name, vtype='I', lb=0)
                m.addCons(D_fml1g[a, b, d,
                                  e] == quicksum(D_fml1l2g[a, b, d, c, e]
                                                 for c in range(1, L + 1)))
Example #47
0
def vehicle_assignment_solver(K,
                              a,
                              b,
                              c,
                              customer_count,
                              predefined_vehicle_index=None,
                              predefined_vehicle_nodes=None):
    v_range = range(0, K)
    c_range = range(1, customer_count)
    samples = []

    a_ord = sorted(a.items(), key=lambda k: k[1])
    a_ord.reverse()
    samples.append(a_ord[0])
    del a_ord[0]

    while True:
        a_ord = sorted(a_ord,
                       key=lambda el: dist_between_nodes(el, samples, c),
                       reverse=True)
        samples.append(a_ord[0])
        del a_ord[0]

        if len(samples) == K:
            break

    w = {}
    for i in v_range:
        w[i] = samples[i][0]

    # Resolve MIP problem to find the best possible vehicle-customers combinations
    model = Model("vrp_vehicles")
    #model.hideOutput()

    if customer_count >= 200:
        model.setRealParam("limits/gap", 0.005)

    y = {}
    for v in v_range:
        for i in c_range:
            # customer i is visited by vehicle v
            y[i, v] = model.addVar(vtype="B", name="y(%s,%s)" % (i, v))
    for v in v_range:
        # Constraint: the demand of customers assigned to vehicle V cannot exceed its capacity
        model.addCons(quicksum(a[i] * y[i, v] for i in c_range) <= b)

        # Constraint: for this model, we enforce every vehicle to visit a customer
        # model.addCons(quicksum(y[i, v] for i in c_range) >= 1)

        # Constraint: we enforce the customers on 'w' to be visited by the defined vehicle
        #model.addCons(y[w[v], v] == 1)

        #if predefined_vehicle_nodes and v == predefined_vehicle_index:
        #    for p in predefined_vehicle_nodes:
        #        model.addCons(y[p, predefined_vehicle_index] == 1)

    for i in c_range:
        # if i > 0:
        # Constraint: each customer has to be visited by exactly one vehicle
        model.addCons(quicksum(y[i, v] for v in v_range) == 1)

    model.setObjective(
        quicksum(
            quicksum(
                cost_of_new_customer_in_vehicle(c, i, w[v]) * y[i, v]
                for i in c_range) for v in v_range), "maximize")

    model.optimize()
    # best_sol = model.getBestSol()
    vehicle_tours = {}
    for v in v_range:
        vehicle_tours[v] = []
        for i in c_range:
            # val = model.getSolVal(best_sol, y[i, v])
            val = model.getVal(y[i, v])
            if val > 0.5:
                vehicle_tours[v].append(i)

    obj = model.getObjVal()

    return obj, vehicle_tours
Example #48
0
    (5, 2): 8,
    (5, 3): 4,
}

model = Model("transportation")

# Create variables
x = {}

for i in I:
    for j in J:
        x[i, j] = model.addVar(vtype="C", name="x(%s,%s)" % (i, j))

# Demand constraints
for i in I:
    model.addCons(sum(x[i, j] for j in J if (i, j) in x) == d[i],
                  name="Demand(%s)" % i)

# Capacity constraints
for j in J:
    model.addCons(sum(x[i, j] for i in I if (i, j) in x) <= M[j],
                  name="Capacity(%s)" % j)

# Objective
model.setObjective(quicksum(c[i, j] * x[i, j] for (i, j) in x), "minimize")

model.optimize()

print("Optimal value:", model.getObjVal())

EPS = 1.e-6
Example #49
0
	P_In_S[t] = model.addVar(vtype="C", name="x(%s)"%j)
	P_RO[t] = model.addVar(vtype="C", name="x(%s)"%j, lb=0, ub=2500)
	st[t] = model.addVar(vtype="C", name="x(%s)"%j, ub = 1)
	Fp[t] = model.addVar(vtype="C", name="x(%s)"%j, lb=0, ub = 4)
	Yopt[t] = model.addVar(vtype="C", name="x(%s)"%j, lb=.6, ub=1)
	P_Sys[t]= model.addVar(vtype="C", name="x(%s)"%j)
	Vf[t] = model.addVar(vtype="C", name="x(%s)"%j)
	hdot[t]= model.addVar(vtype="C", name="x(%s)"%j)
	h[t] = model.addVar(vtype="C", name="x(%s)"%j, lb=0, ub=hmax)
	Theta_VFD[t] = model.addVar(vtype="C", name="x(%s)"%j, lb=0, ub=Theta_Max)
	Vr[t] = model.addVar(vtype="C", name="x(%s)"%j, lb=0, ub=2)

# Create Constraints

for t in time:
	model.addCons(quickSum())

for j in Blends:
    x[j] = model.addVar(vtype="C", name="x(%s)"%j)

# Create constraints
c = {}
for i in Grapes:
    c[i] = model.addCons(quicksum(Use[i,j]*x[j] for j in Blends) <= Inventory[i], name="Use(%s)"%i)

# Objective
model.setObjective(quicksum(Profit[j]*x[j] for j in Blends), "maximize")

model.optimize()

if model.getStatus() == "optimal":
    def create_model(self):
        model = Model()
        x, b = {}, {}
        _A = [(i, t) for i in self.tasks for t in self.periods]
        for (i, t) in _A:
            x[i, t] = model.addVar(vtype="B", name="x(%s,%s)" %
                                   (i, t))  # create decision variables
            b[i, t] = model.addVar(vtype="B", name="b(%s,%s)" %
                                   (i, t))  # create decision variables

        # create constraints
        for t in self.periods:
            model.addCons(
                quicksum(self.p[i, t] * (1 - x[i, t])
                         for i in self.tasks) - self.d[t] >= 0)  # 1
            model.addCons(quicksum(x[i, t]
                                   for i in self.tasks) <= self.LT[t])  # 6
            model.addCons(
                quicksum((self.MV[i] + self.MH[i] + self.ML[i]) * x[i, t]
                         for i in self.tasks) <= self.AM[t])  # 11
            model.addCons(
                quicksum(self.V[i] * x[i, t]
                         for i in self.tasks) <= self.AV[t])  # 12
            model.addCons(
                quicksum(self.H[i] * x[i, t]
                         for i in self.tasks) <= self.AH[t])  # 13

        for i in self.tasks:
            model.addCons(quicksum(b[i, t] for t in self.periods) == 1)  # 2
            model.addCons(
                quicksum(x[i, t] for t in self.periods) == self.LP[i])  # 5
            model.addCons(
                quicksum(b[i, t]
                         for t in self.periods[:self.L[i] - self.LP[i] +
                                               2]) == 1)  # 9
            for t in self.periods:
                model.addCons(x[i, t] >= b[i, t])  # 3

            for t in self.periods[1:]:
                model.addCons(x[i, t] - x[i, t - 1] <= b[i, t])  # 3, t >= 2
                model.addCons(
                    x[i, t] + x[i, t - 1] + b[i, t] <= 1 + self.LP[i])  # 4

            for j in self.tasks:
                if j != i:
                    model.addCons(x[i, t] + x[j, t] <= 1)  # 8
                    for t in self.periods:
                        model.addCons(
                            quicksum(b[i, k] for k in self.periods) - b[j, t]
                            >= 0)  # 7

            for t in self.U:
                model.addCons(x[i, t] == 0)  # 10

        # create costs
        C_M, C_T = {}, {}
        for i in self.tasks:
            for t in self.periods:
                C_M[i,t] = self.C_MV[t] * self.MV[i] + self.C_MH[t] * self.MH[i] + \
                    self.C_ML[t] * self.ML[i]
                C_T[i,t] = (self.C_FV * self.V[i] + self.C_FH * self.H[i])/self.LP[i] + \
                    self.C_SV[i,t] * self.V[i] + self.C_SH[i,t] * self.H[i]

        # create ojective function
        model.setObjective(quicksum((C_M[i,t] + self.C_EQ[i,t] + self.C_I[i,t] + \
            C_T[i,t]) * x[i,t] for t in self.periods for i in self.tasks), "minimize")
        model.hideOutput()  # silent mode
        model.optimize()
        if model.getStatus() != 'optimal':
            print('Model is not feasible!')
        else:
            c_total = model.getObjVal()
            print("Total cost is: ", c_total)
            for (i, t) in _A:
                if model.getVal(x[i, t]) == 1.0:
                    print(x[i, t], " = 1")
                if model.getVal(b[i, t]) == 1.0:
                    print(b[i, t], " = 1")
        return
Example #51
0
        print("* Sense: %s" % m.getObjectiveSense())
    for v in m.getVars():
        if v.name != "n":
            print("%s: %d" % (v, round(m.getVal(v))))
    print("\n")


# AND #
model = Model()
model.hideOutput()
x = model.addVar("x", "B")
y = model.addVar("y", "B")
z = model.addVar("z", "B")
r = model.addVar("r", "B")
model.addConsAnd([x, y, z], r)
model.addCons(x == 1)
model.setObjective(r, sense="minimize")
model.optimize()
printFunc("AND", model)

# OR #
model = Model()
model.hideOutput()
x = model.addVar("x", "B")
y = model.addVar("y", "B")
z = model.addVar("z", "B")
r = model.addVar("r", "B")
model.addConsOr([x, y, z], r)
model.addCons(x == 0)
model.setObjective(r, sense="maximize")
model.optimize()
Example #52
0
subject to 2x +   y +   z <= 60
           x  +  2y +   z <= 60
                        z <= 30
           x,y,z >= 0

Copyright (c) by Joao Pedro PEDROSO and Mikio KUBO, 2015
"""
from pyscipopt import Model

model = Model("Simple linear optimization")

x1 = model.addVar(vtype="C", name="x1")
x2 = model.addVar(vtype="C", name="x2")
x3 = model.addVar(vtype="C", name="x3")

model.addCons(2 * x1 + x2 + x3 <= 60)
model.addCons(x1 + 2 * x2 + x3 <= 60)
model.addCons(x3 <= 30)

model.setObjective(15 * x1 + 18 * x2 + 30 * x3, "maximize")

model.optimize()

if model.getStatus() == "optimal":
    print("Optimal value:", model.getObjVal())
    print("Solution:")
    print("  x1 = ", model.getVal(x1))
    print("  x2 = ", model.getVal(x2))
    print("  x3 = ", model.getVal(x3))
else:
    print("Problem could not be solved to optimality")
def lewis_caroll_zebra(positions, carac):
    """
    Parameters:
        - n: Integer, number of queen and size of the grid
    Returns a model, ready to be solved.
    """

    m = Model()

    # create a binary variable for every field and value
    x = {}
    for i in range(5):
        for j in range(5):
            for k in range(5):
                name = str(i)+','+str(j)+','+str(k)
                x[i, j, k] = m.addVar(name, vtype='B')

    # only one value per carac in every field
    for i in range(5):
        for j in range(5):
            m.addCons(quicksum(x[i, j, k] for k in range(5)) == 1)

    # only "one coffee" constraint
    for j in range(5):
        for k in range(5):
            m.addCons(quicksum(x[i, j, k] for i in range(5)) == 1)

    m.addCons(x[0, 1, 0] == 1) # Le norvégien habite la première maison,
    m.addCons(x[1, 0, 0] == 1) # La maison à coté de celle du norvégien est bleue,
    m.addCons(x[2, 2, 0] == 1) # L’habitant de la troisième maison boit du lait,

    for i in range(5):
        m.addCons(x[i, 1, 1] == x[i, 0, 1]) # L’anglais habite la maison rouge,
        m.addCons(x[i, 2, 2] == x[i, 0, 3]) # L’habitant de la maison verte boit du café
        m.addCons(x[i, 0, 2] == x[i, 3, 0]) # L’habitant de la maison jaune fume des Kools,
        m.addCons(x[i, 1, 2] == x[i, 4, 1]) # L’espagnol a un chien,
        m.addCons(x[i, 1, 4] == x[i, 2, 3]) # L'ukrainien boit du thé
        m.addCons(x[i, 1, 3] == x[i, 3, 1]) # Le japonais fume des cravens
        m.addCons(x[i, 3, 2] == x[i, 4, 3]) # Le fumeur de old golds a un escargot
        m.addCons(x[i, 3, 3] == x[i, 2, 1]) # Le fumeur de gitanes boit du vin,

    m.addCons(x[0, 0, 4] == 0)
    for i in range(4):
        m.addCons(x[i, 0, 3] == x[i+1, 0, 4]) # La maison blanche se trouve juste après la verte,
    
    m.addCons(x[0, 3, 4]==x[1, 4, 2])
    m.addCons(x[0, 3, 0]==x[1, 4, 4])
    for i in range(1, 4):
        m.addCons(x[i, 3, 4] <= x[i+1, 4, 2] + x[i-1, 4, 2]) # Un voisin du fumeur de Chesterfields a un renard,
        m.addCons(x[i, 3, 0] <= x[i+1, 4, 4] + x[i-1, 4, 4]) # Un voisin du fumeur de Kools a un cheval.
    
    m.addCons(x[4, 3, 4]==x[3, 4, 2])
    m.addCons(x[4, 3, 0]==x[3, 4, 4])

    return m, x
Example #54
0
def test_model():
    # create solver instance
    s = Model()

    # test parameter methods
    pric = s.getParam('lp/pricing')
    s.setParam('lp/pricing', 'q')
    assert 'q' == s.getParam('lp/pricing')
    s.setParam('lp/pricing', pric)
    s.setParam('visual/vbcfilename', 'vbcfile')
    assert 'vbcfile' == s.getParam('visual/vbcfilename')

    assert 'lp/pricing' in s.getParams()
    s.setParams({'visual/vbcfilename': '-'})
    assert '-' == s.getParam('visual/vbcfilename')

    # add some variables
    x = s.addVar("x", vtype = 'C', obj = 1.0)
    y = s.addVar("y", vtype = 'C', obj = 2.0)

    assert x.getObj() == 1.0
    assert y.getObj() == 2.0

    s.setObjective(4.0 * y + 10.5, clear = False)
    assert x.getObj() == 1.0
    assert y.getObj() == 4.0
    assert s.getObjoffset() == 10.5

    # add some constraint
    c = s.addCons(x + 2 * y >= 1.0)
    assert c.isLinear()
    s.chgLhs(c, 5.0)
    s.chgRhs(c, 6.0)

    assert s.getLhs(c) == 5.0
    assert s.getRhs(c) == 6.0

    # solve problem
    s.optimize()

    solution = s.getBestSol()

    # print solution
    assert (s.getVal(x) == s.getSolVal(solution, x))
    assert (s.getVal(y) == s.getSolVal(solution, y))
    assert round(s.getVal(x)) == 5.0
    assert round(s.getVal(y)) == 0.0
    assert s.getSlack(c, solution) == 0.0
    assert s.getSlack(c, solution, 'lhs') == 0.0
    assert s.getSlack(c, solution, 'rhs') == 1.0
    assert s.getActivity(c, solution) == 5.0

    # check expression evaluations
    expr = x*x + 2*x*y + y*y
    expr2 = x + 1
    assert s.getVal(expr) == s.getSolVal(solution, expr)
    assert s.getVal(expr2) == s.getSolVal(solution, expr2)
    assert round(s.getVal(expr)) == 25.0
    assert round(s.getVal(expr2)) == 6.0

    s.writeProblem('model')
    s.writeProblem('model.lp')

    s.freeProb()
    s = Model()
    x = s.addVar("x", vtype = 'C', obj = 1.0)
    y = s.addVar("y", vtype = 'C', obj = 2.0)
    c = s.addCons(x + 2 * y <= 1.0)
    s.setMaximize()

    s.delCons(c)

    s.optimize()

    assert s.getStatus() == 'unbounded'
Example #55
0
def scf(n, c):
    """scf: single-commodity flow formulation for the (asymmetric) traveling salesman problem
    Parameters:
        - n: number of nodes
        - c[i,j]: cost for traversing arc (i,j)
    Returns a model, ready to be solved.
    """
    model = Model("atsp - scf")

    x, f = {}, {}
    for i in range(1, n + 1):
        for j in range(1, n + 1):
            if i != j:
                x[i, j] = model.addVar(vtype="B", name="x(%s,%s)" % (i, j))
                if i == 1:
                    f[i, j] = model.addVar(lb=0,
                                           ub=n - 1,
                                           vtype="C",
                                           name="f(%s,%s)" % (i, j))
                else:
                    f[i, j] = model.addVar(lb=0,
                                           ub=n - 2,
                                           vtype="C",
                                           name="f(%s,%s)" % (i, j))

    for i in range(1, n + 1):
        model.addCons(
            quicksum(x[i, j] for j in range(1, n + 1) if j != i) == 1,
            "Out(%s)" % i)
        model.addCons(
            quicksum(x[j, i] for j in range(1, n + 1) if j != i) == 1,
            "In(%s)" % i)

    model.addCons(
        quicksum(f[1, j] for j in range(2, n + 1)) == n - 1, "FlowOut")

    for i in range(2, n + 1):
        model.addCons(quicksum(f[j,i] for j in range(1,n+1) if j != i) - \
                        quicksum(f[i,j] for j in range(1,n+1) if j != i) == 1, "FlowCons(%s)"%i)

    for j in range(2, n + 1):
        model.addCons(f[1, j] <= (n - 1) * x[1, j], "FlowUB(%s,%s)" % (1, j))
        for i in range(2, n + 1):
            if i != j:
                model.addCons(f[i, j] <= (n - 2) * x[i, j],
                              "FlowUB(%s,%s)" % (i, j))

    model.setObjective(quicksum(c[i, j] * x[i, j] for (i, j) in x), "minimize")

    model.data = x, f
    return model
Example #56
0
def mintreeMFP(n, e, d):
    """
    mintreeMFP: min Cost Tree based on Flow Conservation 
    Parameters:
        - n: number of nodes
        - e[i,j]['cap','cost']: edges of graph, 'cap': capacity of edge, 'cost': cost for traversing edge (i,j)
        - d[i,j]: demande(data) from node i to j
    Returns a model, ready to be solved.
    """
    print("\n========min Cost Tree based on Flow Conservation======")

    model = Model("mintreeMFP")
    x, f, z = {}, {}, {}  # flow variable
    """
    In our model, f[i,j] is the sum of flow on edge, if f[i,j]>0 then z[i,j]=1 else z[i,j]=0, such that get minTree
    In order to express the logical constraint, define a Big M, and z is Binary, 
    z[i,j]>=f[i,j]/M (gurantee f/M <1) and z[i,j]<=f[i,j]*M (gurantee f[i,j]*M >1)
    """
    M = 100000000
    for (i, j) in e.keys():
        f[i, j] = model.addVar(ub=1000000,
                               lb=0,
                               vtype="C",
                               name="f[%s,%s]" % (i, j))
        z[i, j] = model.addVar(ub=1, lb=0, vtype="B", name="z[%s,%s]" % (i, j))
        for (s, t) in d.keys():
            x[i, j, s, t] = model.addVar(ub=1000000,
                                         lb=0,
                                         vtype="C",
                                         name="x[%s,%s,%s,%s]" % (i, j, s, t))
    # node flow conservation
    for (s, t) in d.keys():
        for j in n.keys():
            # for destination node
            if j == t:
                model.addCons(
                    quicksum(x[i, j, s, t]
                             for i in n.keys() if (i, j) in e.keys()) -
                    quicksum(x[j, i, s, t]
                             for i in n.keys() if (j, i) in e.keys()) == d[s,
                                                                           t],
                    "DesNode(%s)" % j)
            # for source node
            elif j == s:
                model.addCons(
                    quicksum(x[i, j, s, t]
                             for i in n.keys() if (i, j) in e.keys()) -
                    quicksum(x[j, i, s, t] for i in n.keys()
                             if (j, i) in e.keys()) == -d[s, t],
                    "SourceNode(%s)" % j)
            else:
                model.addCons(
                    quicksum(x[i, j, s, t]
                             for i in n.keys() if (i, j) in e.keys()) -
                    quicksum(x[j, i, s, t]
                             for i in n.keys() if (j, i) in e.keys()) == 0,
                    "SourceNode(%s)" % j)
    # constrains for edge capacity, take into consideration of tree optimization, using variable f
    for (i, j) in e.keys():
        f[i, j] = quicksum(x[i, j, s, t] for (s, t) in d.keys())
        model.addCons(f[i, j] <= e[i, j]['cap'], 'edge(%s,%s)' % (i, j))
        # logical constraint
        model.addCons(M * z[i, j] >= f[i, j])
        model.addCons(z[i, j] <= f[i, j] * M)

    model.data = x, f

    #model.setObjective(quicksum(f[i,j]*e[i,j]['cost'] for (i,j) in e.keys()), "minimize")
    model.setObjective(quicksum(z[i, j] for (i, j) in e.keys()), "minimize")
    return model
Example #57
0
]

weights = [
    7, 86, 5, 76, 7, 56, 76, 76, 7, 67, 6, 76, 75, 6, 567, 56, 578, 58, 6, 465
]

x = {}
n = len(values)
capacity = 500

model = Model('knapsack')

# define variables as binaries
for i in range(n):
    x[i] = model.addVar(name=f'x_{i}', vtype='B')

# add constraint so that the sum of weights is less than or equal to capacity
model.addCons(quicksum(x[i] * weights[i] for i in range(n)) <= capacity)

# set the objective to the negative of sum of values to maximize value
model.setObjective(quicksum(-x[i] * values[i] for i in range(n)))

# optimize
model.optimize()

sol = model.getBestSol()

# print results
for i in range(n):
    print(sol[x[i]])
Example #58
0
def scip_solver_2(customers, customer_count, vehicle_count, vehicle_capacity):
    model = Model("vrp")

    c_range = range(0, customer_count)
    cd_range = range(1, customer_count)

    x, d, w, v = {}, {}, {}, {}
    for i in c_range:
        for j in c_range:
            d[i, j] = length(customers[i], customers[j])
            w[i, j] = customers[i].demand + customers[j].demand
            if j > i and i == 0:  # depot
                x[i, j] = model.addVar(ub=2,
                                       vtype="I",
                                       name="x(%s,%s)" % (i, j))
            elif j > i:
                x[i, j] = model.addVar(ub=1,
                                       vtype="I",
                                       name="x(%s,%s)" % (i, j))

    model.addCons(
        quicksum(x[0, j] for j in cd_range) <= 2 * vehicle_count,
        "DegreeDepot")

    for i in cd_range:
        model.addCons(
            quicksum(x[j, i] for j in c_range if j < i) +
            quicksum(x[i, j] for j in c_range if j > i) == 2, "Degree(%s)" % i)

    model.setObjective(
        quicksum(d[i, j] * x[i, j] for i in c_range for j in c_range if j > i),
        "minimize")

    mip_gaps = [0.0]
    runs = 0

    start = datetime.now()
    for gap in mip_gaps:
        model.freeTransform()
        model.setRealParam("limits/gap", gap)
        model.setRealParam("limits/time", 60 * 20)  # Time limit in seconds
        edges, final_edges, runs = optimize(customer_count, customers, model,
                                            vehicle_capacity, vehicle_count, x)

    run_time = datetime.now() - start

    print(edges)
    print(final_edges)
    output = [[]] * vehicle_count
    for i in range(vehicle_count):
        output[i] = []
        current_item = None
        if len(final_edges) > 0:

            for e in final_edges:
                if e[0] == 0:
                    current_item = e
                    break
            if current_item:
                a = current_item[0]
                current_node = current_item[1]
                output[i].append(customers[current_node])
                final_edges.remove(current_item)
                searching_connections = True
                while searching_connections and len(final_edges) > 0:
                    for edge in final_edges:
                        found_connection = False
                        a_edge = edge[0]
                        b_edge = edge[1]

                        if b_edge == current_node and a_edge == 0:
                            final_edges.remove(edge)
                            break

                        if a_edge == current_node:
                            output[i].append(customers[b_edge])
                            current_node = b_edge
                            found_connection = True
                        elif b_edge == current_node:
                            output[i].append(customers[a_edge])
                            current_node = a_edge
                            found_connection = True

                        if found_connection:
                            final_edges.remove(edge)
                            break

                    if not found_connection:
                        searching_connections = False

    print(output)

    sol = model.getBestSol()
    obj = model.getSolObjVal(sol)

    print("RUN TIME: %s" % str(run_time))
    print("NUMBER OF OPTIMIZATION RUNS: %s" % runs)

    return obj, output
Example #59
0
#!/usr/bin/env python

from pyscipopt import Model

model = Model("test")
x = model.addVar()
y = model.addVar()
z = model.addVar()

model.addCons(x + y + z == 32)

# Set objective function
model.setObjective(x + y, "minimize")

# model.hideOutput()
model.writeLP('./Lp.lp')
Example #60
0
def test_cuttingstock():
    # create solver instance
    s = Model("CuttingStock")

    s.setPresolve(0)

    # creating a pricer
    pricer = CutPricer()
    s.includePricer(pricer, "CuttingStockPricer",
                    "Pricer to identify new cutting stock patterns")

    # item widths
    widths = [14, 31, 36, 45]
    # width demand
    demand = [211, 395, 610, 97]
    # roll length
    rollLength = 100
    assert len(widths) == len(demand)

    # adding the initial variables
    cutPatternVars = []
    varNames = []
    varBaseName = "Pattern"
    patterns = []

    initialCoeffs = []
    for i in range(len(widths)):
        varNames.append(varBaseName + "_" + str(i))
        cutPatternVars.append(s.addVar(varNames[i], obj=1.0))

    # adding a linear constraint for the knapsack constraint
    demandCons = []
    for i in range(len(widths)):
        numWidthsPerRoll = float(int(rollLength / widths[i]))
        demandCons.append(
            s.addCons(numWidthsPerRoll * cutPatternVars[i] >= demand[i],
                      separate=False,
                      modifiable=True))
        newPattern = [0] * len(widths)
        newPattern[i] = numWidthsPerRoll
        patterns.append(newPattern)

    # Setting the pricer_data for use in the init and redcost functions
    pricer.data = {}
    pricer.data['var'] = cutPatternVars
    pricer.data['cons'] = demandCons
    pricer.data['widths'] = widths
    pricer.data['demand'] = demand
    pricer.data['rollLength'] = rollLength
    pricer.data['patterns'] = patterns

    # solve problem
    s.optimize()

    # print original data
    printWidths = '\t'.join(str(e) for e in widths)
    print('\nInput Data')
    print('==========')
    print('Roll Length:', rollLength)
    print('Widths:\t', printWidths)
    print('Demand:\t', '\t'.join(str(e) for e in demand))

    # print solution
    widthOutput = [0] * len(widths)
    print('\nResult')
    print('======')
    print('\t\tSol Value', '\tWidths\t', printWidths)
    for i in range(len(pricer.data['var'])):
        rollUsage = 0
        solValue = round(s.getVal(pricer.data['var'][i]))
        if solValue > 0:
            outline = 'Pattern_' + str(i) + ':\t' + str(
                solValue) + '\t\tCuts:\t'
            for j in range(len(widths)):
                rollUsage += pricer.data['patterns'][i][j] * widths[j]
                widthOutput[j] += pricer.data['patterns'][i][j] * solValue
                outline += str(pricer.data['patterns'][i][j]) + '\t'
            outline += 'Usage:' + str(rollUsage)
            print(outline)

    print('\t\t\tTotal Output:', '\t'.join(str(e) for e in widthOutput))