Ejemplo n.º 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
Ejemplo n.º 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'
Ejemplo n.º 3
0
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
Ejemplo n.º 4
0
def prodmix(I,K,a,p,epsilon,LB):
    """prodmix:  robust production planning using soco
    Parameters:
        I - set of materials
        K - set of components
        a[i][k] -  coef. matrix
        p[i] - price of material i
        LB[k] - amount needed for k
    Returns a model, ready to be solved.
    """

    model = Model("robust product mix")

    x,rhs = {},{}
    for i in I:
        x[i] = model.addVar(vtype="C", name="x(%s)"%i)
    for k in K:
        rhs[k] = model.addVar(vtype="C", name="rhs(%s)"%k)

    model.addCons(quicksum(x[i] for i in I) == 1)
    for k in K:
        model.addCons(rhs[k] == -LB[k]+ quicksum(a[i,k]*x[i] for i in I) )
        model.addCons(quicksum(epsilon*epsilon*x[i]*x[i] for i in I) <= rhs[k]*rhs[k])

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

    model.data = x,rhs
    return model
Ejemplo n.º 5
0
def markowitz(I,sigma,r,alpha):
    """markowitz -- simple 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
    Returns a model, ready to be solved.
    """
    model = Model("markowitz")

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

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

    # set nonlinear objective: SCIP only allow for linear objectives hence the following
    obj = model.addVar(vtype="C", name="objective", lb = None, ub = None)  # auxiliary variable to represent objective
    model.addCons(quicksum(sigma[i]**2 * x[i] * x[i] for i in I) <= obj)
    model.setObjective(obj, "minimize")

    model.data = x
    return model
Ejemplo n.º 6
0
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
Ejemplo n.º 7
0
def _init():
    model = Model()
    model.hideOutput()
    x = model.addVar("x","B")
    y = model.addVar("y","B")
    z = model.addVar("z","B")
    return model, x, y, z
Ejemplo n.º 8
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
Ejemplo n.º 9
0
def kmedian(I,J,c,k):
    """kmedian -- minimize total cost of servicing customers from 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-median")
    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(quicksum(y[j] for j in J) == k, "Facilities")

    model.setObjective(quicksum(c[i,j]*x[i,j] for i in I for j in J), "minimize")
    model.data = x,y

    return model
Ejemplo n.º 10
0
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
Ejemplo n.º 11
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
Ejemplo n.º 12
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
Ejemplo n.º 13
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
Ejemplo n.º 14
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
Ejemplo n.º 15
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
Ejemplo n.º 16
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
Ejemplo n.º 17
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
Ejemplo n.º 18
0
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
Ejemplo n.º 19
0
def mils_standard(T,K,P,f,g,c,d,h,a,M,UB,phi):
    """
    mils_standard: standard 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)
    """
    model = Model("multi-stage lotsizing -- standard formulation")

    y,x,I = {},{},{}
    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))
            I[t,p] = model.addVar(vtype="C",name="I(%s,%s)"%(t,p))
        I[0,p] = model.addVar(name="I(%s,%s)"%(0,p))

    for t in Ts:
        for p in P:
            # flow conservation constraints
            model.addCons(I[t-1,p] + x[t,p] == \
                            quicksum(phi[p,q]*x[t,q] for (p2,q) in phi if p2 == p) \
                            + I[t,p] + d[t,p],
                            "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))

    # initial inventory quantities
    for p in P:
        model.addCons(I[0,p] == 0, "InventInit(%s)"%(p))

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

    model.data = y,x,I
    return model
Ejemplo n.º 20
0
def test_quicksum_model():
    m = Model("quicksum")
    x = m.addVar("x")
    y = m.addVar("y")
    z = m.addVar("z")
    c = 2.3

    q = quicksum([x,y,z,c]) == 0.0
    s =      sum([x,y,z,c]) == 0.0

    assert(q.expr.terms == s.expr.terms)
Ejemplo n.º 21
0
def setModel(vtype="B", name=None, imax=2):
    """initialize model and its variables.
    imax (int): number of operators"""
    if name is None:
        name = "model"
    m = Model(name)
    m.hideOutput()
    i = 0
    r = m.addVar("r", vtype)
    while i < imax:
        m.addVar("v%s" % i, vtype)
        i += 1
    return m
Ejemplo n.º 22
0
def staff_mo(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 shit 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 with no objective function.
    """

    Ts = range(1,T+1)
    model = Model("staff scheduling -- multiobjective version")

    x,y = {},{}
    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))
            y[t,j] = model.addVar(vtype="C", name="y(%s,%s)" % (t,j))

    C = model.addVar(vtype="C", name="cost")
    U = model.addVar(vtype="C", name="uncovered")

    model.addCons(C >= quicksum(c[i,t,j]*x[i,t,j] for i in I for t in Ts for j in J if j != 0), "Cost")
    model.addCons(U >= quicksum(y[t,j] for t in Ts for j in J if j != 0), "Uncovered")

    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] - y[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,y,C,U
    return model
Ejemplo n.º 23
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
Ejemplo n.º 24
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
Ejemplo n.º 25
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
Ejemplo n.º 26
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)
Ejemplo n.º 27
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
Ejemplo n.º 28
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
Ejemplo n.º 29
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
Ejemplo n.º 30
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
Ejemplo n.º 31
0
def create_sudoku():
    scip = Model("Sudoku")

    x = {} # values of squares
    for row in range(9):
        for col in range(9):
            # some variables are fix
            if init[row*9 + col] != 0:
                x[row,col] = scip.addVar(vtype = "I", lb = init[row*9 + col], ub = init[row*9 + col], name = "x(%s,%s)" % (row,col))
            else:
                x[row,col] = scip.addVar(vtype = "I", lb = 1, ub = 9, name = "x(%s,%s)" % (row,col))
            var = x[row,col]
            #print("built var ", var.name, " with bounds: (%d,%d)"%(var.getLbLocal(), var.getUbLocal()))

    conshdlr = ALLDIFFconshdlr()

    # hoping to get called when all vars have integer values
    scip.includeConshdlr(conshdlr, "ALLDIFF", "All different constraint", propfreq = 1, enfopriority = -10, chckpriority = -10)

    # row constraints; also we specify the domain of all variables here
    # TODO/QUESTION: in principle domain is of course associated to the var and not the constraint. it should be "var.data"
    # But ideally that information would be handle by SCIP itself... the reason we can't is because domain holes is not implemented, right?
    domains = {}
    for row in range(9):
        vars = []
        for col in range(9):
            var = x[row,col]
            vars.append(var)
            vals = set(range(int(round(var.getLbLocal())), int(round(var.getUbLocal())) + 1))
            domains[var.ptr()] = vals
        # this is kind of ugly, isn't it?
        cons = scip.createCons(conshdlr, "row_%d" % row)
        #print("in test: received a constraint with id ", id(cons)) ### DELETE
        cons.data = SimpleNamespace() # so that data behaves like an instance of a class (ie, cons.data.whatever is allowed)
        cons.data.vars = vars
        cons.data.domains = domains
        scip.addPyCons(cons)

    # col constraints
    for col in range(9):
        vars = []
        for row in range(9):
            var = x[row,col]
            vars.append(var)
        cons = scip.createCons(conshdlr, "col_%d"%col)
        cons.data = SimpleNamespace()
        cons.data.vars = vars
        cons.data.domains = domains
        scip.addPyCons(cons)

    # square constraints
    for idx1 in range(3):
        for idx2 in range(3):
            vars = []
            for row in range(3):
                for col in range(3):
                    var = x[3*idx1 + row, 3*idx2 + col]
                    vars.append(var)
            cons = scip.createCons(conshdlr, "square_%d-%d"%(idx1, idx2))
            cons.data = SimpleNamespace()
            cons.data.vars = vars
            cons.data.domains = domains
            scip.addPyCons(cons)


    #scip.setObjective()

    return scip, x
Ejemplo n.º 32
0
    (4, 1): 8,
    (4, 2): 5,
    (4, 3): 3,
    (5, 1): 10,
    (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(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()
Ejemplo n.º 33
0
from pyscipopt import Model

model = Model("Example")  # model name is optional
x = model.addVar("x")
y = model.addVar("y", vtype="INTEGER")
model.setObjective(x + y)
model.addCons(2 * x - y * y >= 0)
model.optimize()
Ejemplo n.º 34
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
Ejemplo n.º 35
0
def scipfamily9generalmini(ll,fixer,one):
    biggig=[]
    l = [x for x in constraints()]
    p = [x for x in allsets()]
    weight=[1.0,1.0,-1.0]
    oweight=[1.0,-1.0]
    for i in range(len(l)):
        new=l[i] + weight
    c = [6,6,6,6,6,5,6,7,9]  
    cone = [0,100,41,39,40,27,89,91,111]  
    if fixer == 1:
        two1 = filtersets.zerone(ll)
    else:  
        two1 = ll
    two = []
    for i in range(len(two1)):
        if i != one:
           two.insert(0,two1[i])
    sets=two
    indexkeeps = filtersets.powerset(9)
    allones=[1.0]*len(p)
    flag=1
    count=0
    index=[]
    fixf = Model()
    fixf.hideOutput()
    fixf.setMinimize()
   
    FranklVarsf = []
    FvarNamesf = []
    FvarBaseNamef = "Setfix"
    # add frankl variables
    for i in range(len(p)):
        FvarNamesf.append(FvarBaseNamef + "_" + str(i))
        FranklVarsf.append(fixf.addVar(FvarNamesf[i], vtype='B', obj=1.0, ub=1.0))
    # add union-closed constraints
    for i in range(len(l)):
        new=l[i] + weight
        coeffs = {FranklVarsf[l[i][j]-1]: new[j+3] for j in range(0,len(weight))}
        fixf.addCons(coeffs, lhs=None, rhs=1.0, name ="uc(%s)" %i)
    # add fixed family
    for i in range(len(sets)):
          coeffs = {FranklVarsf[p.index(sets[i])]: 1.0}
          fixf.addCons(coeffs, lhs = 1.0, rhs = 1.0)
             # if i >=6 and i <=7:
               #  coeffs = {FranklVars[p.index(sets[i])]: 1.0}
                # sbin.addCons(coeffs, lhs = 1.0, rhs = 1.0)

      # add the empty set
   
    #fixf.writeProblem('original.lp')
    fixf.optimize()
    fixedfam=[0.0]*len(p)
    if fixf.getStatus()=="optimal":
             for j in range(len(p)):
                 fixedfam[j]=round(fixf.getVal(FranklVarsf[j]))
                  
            

    else:
        print 'We have a bug in the generation of the fixed family'  
    lf = [x for x in constraintsf(fixedfam)]
   
    onemore = []
    for i in range(len(fixedfam)):
        if fixedfam[i] > 0.5:
           onemore.insert(0,indexkeeps.index(p[i]))
    print onemore
    #print [x for x in p if fixedfam[p.index(x)] > 0.0]
    #return 0
    fixf.free()  
    while flag==1:
          # continous model for c_is
          slin = Model()
          slin.hideOutput()
          # binary model for fixed c_i
          sbin = Model()
          sbin.setMinimize()
          #sbin.setIntParam("limits/solutions", 1)
          sbin.hideOutput()
          #sbin.setMaximize()
          # continous variables c_is
          WeightVars = []
          WvarNames = []
          WvarBaseName = "Weight"
          # binary variables for sets in frankl family
          FranklVars = []
          FvarNames = []
          FvarBaseName = "x"
   
          # add c_i variables
          for i in range(len(c)):
              if i <=7:
                 WvarNames.append(WvarBaseName + "_"+ str(i))
                 WeightVars.append(slin.addVar(WvarNames[i], vtype='I', obj=1.0, lb=0.0))
              else:
                 WvarNames.append(WvarBaseName + "_" + str(i))
                 WeightVars.append(slin.addVar(WvarNames[i], vtype='I', obj=1.0, lb=0.0))
          # add constraints sum equals one
          coeffs = [1]*len(c)
          #coeffs1 = [1]
          objec = {WeightVars[i]: coeffs[i] for i in range(len(c))}
          slin.setObjective(objec,"minimize")
          coeffss = {WeightVars[i]: 1.0 for i in range(len(c))}
          #coeffss1 = {WeightVars[i]: 1.0 for i in range(5,6)}
          slin.addCons(coeffss, lhs=1.0, rhs=None,name= 'sum_one')
          #slin.addCons(coeffss1,lhs=0.0, rhs=0.0,name= 'fix_one')
          
          if count >= 1:
             print count
            # print 'this is it!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1'
             #print makeccoff(index[0])
            # print index[0]
             # print 'this is it!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1'
            # print index
             for i in range(len(index)):
                 size=sum(index[i])
                 print size
                 print 'hereererere'
                 keeperset=[]
                 for j in range(len(index[i])):
                     if index[i][j] >= 0.5:
                        keeperset.insert(0,j)
                 print count 
                 print [indexkeeps.index(p[x]) for x in keeperset]
                 cr=[x for x in makeccoff(index[i])]
                 coeffs = {WeightVars[j]: (2*cr[j]-size) for j in range(len(cr))}
                 slin.addCons(coeffs, lhs=0.0, rhs=None,name= 'nogoodcut')

          
          # optimize linear program with c_is
          # slin.hideOutput()
          slin.optimize()
         
          # get best solution
          # csol=slin.getBestSol 
          
          if slin.getStatus()=="optimal":  # if we find optimal print c
             for i in range(len(c)):
                 c[i]=slin.getVal(WeightVars[i])
             #print c
          else:
              flag=0                       # otherwise we found a proof!
              print 'Found Infeasibility'
              slin.writeProblem('check.lp')
              
              for i in range(len(c)):
                  c[i]=slin.getVal(WeightVars[i])
              print c
              return 0
              
          slin.free()
          # add frankl variables
          for i in range(len(p)):
              FvarNames.append(FvarBaseName + "_" + str(i))
              FranklVars.append(sbin.addVar(FvarNames[i], vtype='B', obj=1.0, ub=1.0))
  
          # add union-closed constraints
          for i in range(len(l)):
              new=l[i] + weight
              coeffs = {FranklVars[l[i][j]-1]: new[j+3] for j in range(0,len(weight))}
              sbin.addCons(coeffs, lhs=None, rhs=1.0, name ="uc(%s)" %i)
          coeffs = {FranklVars[i]: allones[i] for i in range(len(p))}
          #sbin.addCons(coeffs, lhs=1, rhs=None, name= 'mini')
          # add fixed family constraints
         
          for i in range(len(lf)):
              new=lf[i] + oweight
              coeffs = {FranklVars[lf[i][j]-1]: new[j+2] for j in range(0,len(oweight))}
              sbin.addCons(coeffs, lhs=None, rhs=0.0, name= "fs(%s)" %i)
         
          #weits=makeweightint(c)
          #num=weits[0]
          
         
          num=[x for x in makeweightint(c)]
          obj=[x for x in makeobj(c)]
          # print num
          # add feasibility constraint
          coeffs = {FranklVars[i]: num[i] for i in range(len(p))}
          obj = {FranklVars[i]: obj[i] for i in range(len(p))}
          sbin.setObjective(obj,"maximize")
          sbin.addCons(coeffs, lhs = None, rhs = -1)
          sbin.setMaximize()
          sbin.writeProblem('checkIP.lp')
          spx = cplex.Cplex()
          spx.read('checkIP.lp')
          #spx.parameters.mip.limits.solutions.set(1)
          spx.set_log_stream(None)
          spx.set_error_stream(None)
          spx.set_warning_stream(None)
          spx.set_results_stream(None)
          spx.solve()
          
         
          # optimize binary program
          # sbin.setMaximize()
          
          # sbin.optimize()
          row=[None]*len(p)
          
         
          if spx.solution.get_status() == 101 or spx.solution.get_status() == 102:
             for j in range(len(p)):
                 row[j]=round(spx.solution.get_values(j))
                 

             index.insert(0,row)
          else:
             print 'We found the suckers!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!'  # we found a proof!
             print c
             print [Fraction(x).limit_denominator() for x in c]
             sbin.writeProblem('checkIP.lp')
             kepme= [Fraction(x).limit_denominator().numerator for x in c]
             print kepme
             print 'werrrerrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr'
             biggig.insert(0,one)
             flag = 0
          count=count+1
          sbin.free()
    print biggig             
Ejemplo n.º 36
0
from pyscipopt import Model

model = Model("Simple linear optimization")

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

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

model.optimize()

if model.getStatus() == "optimal":
    print("Optimal value:", model.getObjVal())
    print("Solution:")
    print("  x = ", model.getVal(x))
    print("  y = ", model.getVal(y))
    print("  z = ", model.getVal(z))
else:
    print("Problem could not be solved to optimality")
Ejemplo n.º 37
0
        c2[(i, j)] = 2

for j in range(n):
    I[j] = d[(0, j)] * (random.random() + 0.8)

M = list(range(m + 1))
N = I.keys()
w = {}
x = {}
y = {}

model = Model('Allocation')

for i in M:
    for j in N:
        w[i, j] = model.addVar(vtype='C', lb=0.0, name='w(%s,%s)' % (i, j))

for i in M[1:]:
    for j in N:
        x[i, j] = model.addVar(vtype='B', name='x(%s,%s)' % (i, j))

for i in M:
    for j in N:
        y[i, j] = model.addVar(vtype='C', lb=0.0, name='y(%s,%s)' % (i, j))

# Capacity constraints
model.addCons(sum(x[i, j] for i in M[1:] for j in N) <= L, name='Capacity')

# Weights constraints
for j in N:
    model.addCons(sum(w[i, j] for i in M) <= 1,
Ejemplo n.º 38
0
def flp(I,J,d,M,f,c,cp,cU):
    """flp -- model for the capacitated facility location problem
    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
    Returns a model, ready to be solved.
    """
   
        
    model = Model("flp")

    x,y,y2 = {},{},{}
    for j in range(len(J)):
        y[j] = model.addVar(vtype="B", name="y(%s)"%j)
        for i in range(I):
            x[i,j] = model.addVar(vtype="C", name="x(%s,%s)"%(i,j))
            y2[i,j] = model.addVar(vtype="B", name="y2(%s,%s)"%(i,j))
    
    #### restrictions: ####
    
        #demand has to be completely served by the facilities
    for i in range(I):
        model.addCons(quicksum(x[i,j]*y2[i,j]\
                               for j in range(len(J))) == d[i]) 
        
        #demand served by a facility is not allowed to exceed 
        #the capacity of it
        
    for j in range(len(M)):
        model.addCons(quicksum(x[i,j]*y2[i,j]\
                               for i in range(I)) <= M[j]*y[j])
        
        
        #delivery to customer is not allowed to exceed customers demand

    for (i,j) in x:
        model.addCons(x[i,j]*y2[i,j] <= d[i]*y[j])
       
        
    for i in range(I):
        #i = 0
        for j in J:
            #j = 0
            model.addCons(y2[i,j] <= y[j])
      
        
        

        ####objective function: variable cost for open station #####
        ####                       plus cost for deliveries  ######      
    model.setObjective(
#        quicksum(f[j]*y[j] for j in J) +
        quicksum(c[i+3,j]*x[i,j]*cU for i in range(I) for j in J) + 
        quicksum(y[j]*((instance['deport%d' %(j)]['due_time']-\
                 instance['deport%d' %(j)]['ready_time'])*cp)\
            for j in range(len(J))),"minimize")
            
        #for the possibility to get access to the values of each 
        #defined variable
            
    model.data = x,y,y2

    return model
Ejemplo n.º 39
0
alpha = 0.1
theta = 0.2
p = 1
n = 500

D = {}
SV = {0: [120, 30], 1: [40, 10], 2: [40, 10], 3: [40, 10]}
for i in range(m + 1):
    D[i] = np.clip(np.random.normal(SV[i][0], SV[i][1], n), 1, None)

model = Model('Allocation')

w = {}
for i in range(m + 1):
    w[i] = model.addVar(vtype='C',
                        lb=0.0,
                        ub=1.0,
                        name='DC%i_reserve_ratio' % i)

x = {}
for i in range(m + 1):
    for j in range(n):
        x[(i, j)] = model.addVar(vtype='C', lb=0.0, name='DC%i_stockout' % i)

for j in range(n):
    model.addCons( x[(0,j)] >= (1-alpha) * (1-theta) * quicksum(x[(i,j)]\
                  for i in range(1,m+1)) - w[0] * I[0] + D[0][j], name='RDC_out')

for i in range(1, m + 1):
    for j in range(n):
        model.addCons(x[(i, j)] >= D[i][j] - w[i] * I[0] - I[i],
                      name='FDC%i_out' % i)
Ejemplo n.º 40
0
class KS_MIP(MIPModel):
    """
    KS: the knapsack instance

    fss: first_stage_solution
    scenario: the sampled scenario to be modeled.
    model the MIP

    """
    def __init__(self, ks, fss, sampled_weights):
        MIPModel.__init__(self)
        self.value = ks.get_values()
        self.penalty = ks.get_penalty()
        self.weight = sampled_weights
        self.capacity = ks.get_C()
        assert (len(fss) == len(self.value))
        self.x_star = fss

        self.model = Model("knap_sasck")
        self.solution = None
        self.slack = None
        self.opt_obj = None

    def solve(self):
        self.best_sol_list = []
        # Create variables
        y = {}
        # auxiliary variables
        # ax = {}
        for i in range(len(self.value)):
            y[i] = self.model.addVar(vtype="B", name="y(%s)" % i)
            # ax[i] = self.model.addVar(vtype="B", name="ax(%s)" % i)
        slack = self.model.addVar(vtype="C", name="slack")
        # Add constraints
        self.model.addCons(
            quicksum(self.weight[j] * (self.x_star[j] - y[j])
                     for j in range(len(self.weight))) <= self.capacity,
            name="capacity constraint")
        for j in range(len(self.value)):
            self.model.addCons(y[j] <= self.x_star[j])
        # impose ax[i] = max (y-x,0) api does not support min, max function
        self.model.setObjective(
            quicksum(-1 * self.value[j] * y[j] + y[j] * (-1 * self.penalty)
                     for j in range(len(self.value))), "maximize")
        self.model.data = y, slack
        self.model.hideOutput()  # silent the output
        self.model.optimize()
        status = self.model.getStatus()
        if status == "unbounded" or status == "infeasible":
            return status

        y, slack = self.model.data
        Y = np.zeros(len(self.weight))
        for i in range(len(self.weight)):
            Y[i] = self.model.getVal(y[i])
        self.solution, self.slack, self.opt_obj = Y, self.model.getVal(
            slack), self.model.getObjVal()

        return status

    def query_solution(self):
        return self.solution

    def query_slack(self):
        return self.slack

    def query_opt_obj(self):
        return self.opt_obj

    def query_best_sol(self):
        return self.best_sol_list
Ejemplo n.º 41
0
        Item(4, 36, 50), Item(5, 36, 35), Item(6, 48, 30),
        Item(7, 42, 15), Item(8, 42, 40), Item(9, 36, 30),
        Item(10, 24, 35), Item(11, 30, 45), Item(12, 30, 10),
        Item(13, 42, 20), Item(14, 36, 30), Item(15, 36, 25)
    ]

    bins = [
        Bin(1, 100), Bin(2, 100), Bin(3, 100), Bin(4, 100), Bin(5, 100)
    ]

    model = Model()
    x = dict()

    for _item in items:
        for _bin in bins:
            x[_item.index, _bin.index] = model.addVar(vtype="B")

    for _item in items:
        model.addCons(
            quicksum(x[_item.index, _bin.index] for _bin in bins) <= 1)

    for _bin in bins:
        model.addCons(
            quicksum(
                _item.weight * x[_item.index, _bin.index] for _item in items
            ) <= _bin.capacity)

    model.setObjective(
        quicksum(
            _item.value * x[_item.index, _bin.index]
            for _item in items for _bin in bins
Ejemplo n.º 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
Ejemplo n.º 43
0
def model():
    m = Model()
    x = m.addVar("x")
    y = m.addVar("y")
    z = m.addVar("z")
    return m, x, y, z
Ejemplo n.º 44
0
from pyscipopt import Model

m = Model("svm")

x = m.addVar(vtype='B', name='x')
y = m.addVar(vtype='C', name='y')

m.addCons(3 * x + 2 * y >= 4)

m.optimize()
Ejemplo n.º 45
0
def optimize():
    global n, m, facility, customer
    model = Model("Facility")
    model.hideOutput()
    model.setRealParam('limits/time', 3600)
    # define decision variable
    x = []  #bool flag is facility i is serving customer j
    x = [[0 for x in range(m)] for y in range(n)]
    o = [0 for x in range(n)]
    #x[i][j] jth customer is assigned to ith warehouse
    for i in range(n):
        for j in range(m):
            x[i][j] = model.addVar(
                vtype="B", name="%s,%s" %
                (i, j))  # whether facility i is serving customer j
    # each warehouse whether its open or not.
    for i in range(n):
        o[i] = model.addVar(vtype="B", name="o(%s)" % (i))
    # define constraints
    # Each customer is exactly assigned to 1 facility
    for i in range(m):
        model.addCons(quicksum(x[j][i] for j in range(n)) == 1)
    #Each facility is serving to its demand
    for i in range(n):
        model.addCons(
            quicksum(x[i][j] * customer[j].demand
                     for j in range(m)) <= facility[i].capacity)
    # If facility is closed, no customer is assigned to it
    for i in range(n):
        for j in range(m):
            model.addCons(x[i][j] <= o[i])

    # if a facility is open , it should have at-least 1 customer.
    model.addCons(
        quicksum(x[i][j] for j in range(m) for i in range(n) if o[i]) >= 1)

    # define objective function
    model.setObjective(
        quicksum(o[i] * facility[i].cost + quicksum(x[i][j] * d[i][j]
                                                    for j in range(m))
                 for i in range(n)), "minimize")
    model.setHeuristics(SCIP_PARAMSETTING.AGGRESSIVE)
    model.optimize()

    status = model.getStatus()
    if status == 'optimal':
        print("%s 1" % (model.getObjVal()))
    else:
        print("%s 0" % (model.getObjVal()))
    '''
	cost = 0
	if status == 'optimal':
		for v in model.getVars():
			if v.name != "n":
				print("%s: %d" % (v, round(model.getVal(v))))
	else:
		print("* No variable is printed if model status is not optimal")
	'''
    res = []
    res = [0 for x in range(m)]
    for i in range(n):
        for j in range(m):
            if model.getVal(x[i][j]) > EPS:
                res[int(str(x[i][j]).split(',')[1])] = int(
                    str(x[i][j]).split(',')[0])
                #if(i==186):
                #	print ("%s %d %s %d %d" %(model.getVal(x[i][j]), round(model.getVal(x[i][j])), str(x[i][j]), int(str(x[i][j]).split(',')[0]), int(str(x[i][j]).split(',')[1])))

    for j in range(m):
        print(res[j], end=" ")
    '''
Ejemplo n.º 46
0
def maxConcurrentMFP(n, e, d, st):
    """
    maxConcurrentMFP: max concurrent multi-commodity flow Problem
    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 from node i to j
    Returns a model, ready to be solved.
    """
    print("\n========concurrent multi-commodity flow Problem======")

    model = Model("maxConcurrentMFP")
    x, m = {}, {}  # flow variable
    lamba = model.addVar(ub=1000000, lb=1.0, vtype="C", name="lamba")
    for (i, j) in e.keys():
        # f[i, j] = model.addVar(ub=100000000000, lb=0, vtype="I", 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 in d.keys():
            # ture flow
            m[i, j, s] = model.addVar(ub=100000000000,
                                      lb=0,
                                      vtype='C',
                                      name="m[%s,%s,%s]" % (i, j, s))
            for t in st[s]:
                # presudo flow
                x[i, j, s,
                  t] = model.addVar(ub=100000000,
                                    lb=0,
                                    vtype="C",
                                    name="x[%s,%s,%s,%s]" % (i, j, s, t))
                # model.addCons(x[i, j, s, t] <= e[i, j]['cap'], 'edges(%s, %s)' % (i, j))
        # f[i, j] = quicksum(x[i, j, s, t] for (s, t) in d.keys())
    # commodity flow conservation
    for (i, j) in e.keys():
        for s in st.keys():
            for t in st[s]:
                model.addCons(x[i, j, s, t] <= m[i, j, s],
                              'edges(%s, %s, %s)' % (i, j, s))
                # node flow conservation
                # for destination node
                if j == t:
                    model.addCons(
                        quicksum(m[i, j, s]
                                 for i in n.keys() if (i, j) in e.keys()) -
                        quicksum(m[j, i, s] for i in n.keys()
                                 if (j, i) in e.keys()) == lamba * d[s],
                        "DesNode(%s)" % j)
                # for source node
                elif j == s:
                    model.addCons(
                        quicksum(m[i, j, s]
                                 for i in n.keys() if (i, j) in e.keys()) -
                        quicksum(m[j, i, s] for i in n.keys()
                                 if (j, i) in e.keys()) == -lamba * d[s],
                        "SourceNode(%s)" % j)
                # for relay node
                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,
                        "InterNode(%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(
            quicksum(m[i, j, s] for s in st.keys()) <= 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 = m

    # model.setObjective(quicksum(f[i,j]*e[i,j]['cost'] for (i,j) in e.keys()), "minimize")
    model.setObjective(lamba, "maximize")
    return model
Ejemplo n.º 47
0
import os
from shutil import copyfile
from pyscipopt import Model

model = Model("Extension")  # model name is optional
a = model.addVar("a", vtype="CONTINUOUS")
b = model.addVar("b", vtype="CONTINUOUS")
c = model.addVar("c", vtype="CONTINUOUS")
o = model.addVar("o", vtype="CONTINUOUS")
tests = ["extension_test1"]

for test in tests:
    #me traigo el caso de test y le pongo de nombre input_B e input_N
    copyfile(os.path.join("tests","extension",test+"_B.txt"), "input_B.txt")
    copyfile(os.path.join("tests","extension",test+"_N.txt"), "input_N.txt")
    #Cargo en SCIP el problema en formato ZIMPL
    model.readProblem("extension.zpl")
    model.optimize()
    sol = model.getBestSol()
    #Busco solucion e imprimo puntos
    blanco = open('input_B.txt', 'r').read()
    negro = open('input_N.txt', 'r').read()
    print("\n\n###############################################")
    print("Test "+test+":\n")
    print("Blanco: \n"+blanco)
    print("Negro: \n"+negro+"\n")
    print("Solucion:")
    print("a: {}".format(sol[a]))
    print("b: {}".format(sol[b]))
    print("c: {}".format(sol[c]))
    print("o: {}".format(sol[o]))
Ejemplo n.º 48
0
    """prints results"""
    print("* %s *" % name)
    objSet = bool(m.getObjective().terms.keys())
    print("* Is objective set? %s" % objSet)
    if objSet:
        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")
Ejemplo n.º 49
0
def parity(number):
    """
    Prints if a value is even/odd/neither per each value in a example list

    This example is made for newcomers and motivated by:
    - modulus is unsupported for pyscipopt.scip.Variable and int
    - variables are non-integer by default
    Based on this: #172#issuecomment-394644046

    Args:
        number: value which parity is checked

    Returns:
        sval: 1 if number is odd, 0 if number is even, -1 if neither
    """
    sval = -1
    if verbose:
        print(80 * "*")
    try:
        assert number == int(round(number))
        m = Model()
        m.hideOutput()

        # x and n are integer, s is binary
        # Irrespective to their type, variables are non-negative by default
        # since 0 is the default lb. To allow for negative values, give None
        # as lower bound.
        # (None means -infinity as lower bound and +infinity as upper bound)
        x = m.addVar("x", vtype="I", lb=None, ub=None)  #ub=None is default
        n = m.addVar("n", vtype="I", lb=None)
        s = m.addVar("s", vtype="B")
        # CAVEAT: if number is negative, x's lower bound must be None
        # if x is set by default as non-negative and number is negative:
        #     there is no feasible solution (trivial) but the program
        #     does not highlight which constraints conflict.

        m.addCons(x == number)

        # minimize the difference between the number and twice a natural number
        m.addCons(s == x - 2 * n)
        m.setObjective(s)
        m.optimize()

        assert m.getStatus() == "optimal"
        boolmod = m.getVal(s) == m.getVal(x) % 2
        if verbose:
            for v in m.getVars():
                print("%*s: %d" % (fmtlen, v, m.getVal(v)))
            print("%*d%%2 == %d?" % (fmtlen, m.getVal(x), m.getVal(s)))
            print("%*s" % (fmtlen, boolmod))

        xval = m.getVal(x)
        sval = m.getVal(s)
        sstr = sdic[sval]
        print("%*d is %s" % (fmtlen, xval, sstr))
    except (AssertionError, TypeError):
        print("%*s is neither even nor odd!" % (fmtlen, number.__repr__()))
    finally:
        if verbose:
            print(80 * "*")
            print("")
    return sval
Ejemplo n.º 50
0
Profit = {"Dry": 15, "Medium": 18, "Sweet": 30}
Blends = Profit.keys()

Use = {
    ("Alfrocheiro", "Dry"): 2,
    ("Alfrocheiro", "Medium"): 1,
    ("Alfrocheiro", "Sweet"): 1,
    ("Baga", "Dry"): 1,
    ("Baga", "Medium"): 2,
    ("Baga", "Sweet"): 1,
    ("Castelao", "Dry"): 0,
    ("Castelao", "Medium"): 0,
    ("Castelao", "Sweet"): 1
}

# Create variables
x = {}
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")
show_dual(model)
Ejemplo n.º 51
0
def scip_solver(graph, weight='weight'):
    try:
        from pyscipopt import Model, quicksum
    except ImportError:
        raise ImportError(
            'SCIP Optimization Suit with Python support not found')
    nodes = graph.nodes()
    num_nodes = graph.number_of_nodes()
    c = nx.adjacency_matrix(graph, weight=weight)
    # Define the optimization problem
    model = Model('tsp')
    model.hideOutput()  # silent/verbose mode
    # Create the variables
    x = {}
    for i in xrange(num_nodes):
        for j in xrange(i + 1, num_nodes):
            x[i, j] = model.addVar(ub=1, name='x(%s,%s)' % (i, j))
    # Add the constraints
    for i in xrange(num_nodes):
        model.addCons(
            quicksum([x[j, i] for j in xrange(i)]) +
            quicksum([x[i, j] for j in xrange(i + 1, num_nodes)]) == 2,
            'Degree(%s)' % i)
    # Set minimization objective
    model.setObjective(
        quicksum(c[i, j] * x[i, j] for i in xrange(num_nodes)
                 for j in xrange(i + 1, num_nodes)), 'minimize')

    # Limit the number of edges in a connected component S to |S|-1
    def addcut(cut_edges):
        G = nx.Graph()
        G.add_edges_from(cut_edges)
        Components = list(nx.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 if j > i) <= len(S) - 1)
        return True

    # Solve
    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
    # Extract the tour from the edges
    G = nx.Graph()
    for e in edges:
        G.add_edge(nodes[e[0]], nodes[e[1]])
    tour_edges = nx.eulerian_circuit(G, source=graph.nodes_iter().next())
    tour = [e[0] for e in tour_edges]
    return tour
Ejemplo n.º 52
0
from pyscipopt import Model
import numpy as np

n = 10000

values = np.random.uniform(1, 5, n)
weights = np.random.uniform(1, 5, n)

capacity = np.sum(weights) * 0.2

model = Model()

x = np.array([model.addVar(vtype="i") for i in range(n)])

model.setObjective(-np.sum(values * x))
model.addCons(np.sum(weights * x) <= capacity)
for i in range(n):
    model.addCons(0 <= (x[i] <= 1))

model.optimize()

# print("Items to take:")
# for i in range(n):
#     print(f"\tItem {i:3}: {'*' if model.getVal(x[i]) > 0.5 else ' '}")
Ejemplo n.º 53
0
def transpt(L, L_tasks_mod, C, C_fictive, F, T, x_start, y_start, num_cities):
    """transp -- model for solving the transportation problem
    Parameters:
        L               - dict of tasks with modified city numbers according to the layers and fictive flights,
                          fighttime appended: {(o,d):[td, w, f_time]}
        L_tasks_mod     - dict of tasks with modified city numbers according to the layers,
                          fighttime appended: {(o,d):[td, w, f_time]}
        C               - list of  all cities over all layers plus fictive cities
        C_fictive       - list of fictive cities
        F               - dict of fleet {f:[w_max, tank_max]}
        T               - set of discretized times
        x_start         - dict of initial flights
        y_start         - dict of initial ground postions
    Returns a model, ready to be solved.
    """
    print('build optimisation problem...')
    model = Model("airfraight")

    # precision
    EPS = 1.e-6

    # T_mod for ground arc variables
    T_mod = np.arange(-0.5, T[-1] + 1, 1)

    #  ---------------------------------------------------------------------------------------------------------
    # Variables
    # Create variables x_fodt and y_ot
    x, y, z = {}, {}, {}

    print('building variables...')
    # decision variable x=1 if f flies from o to d with departure time t; x=0 else
    for f in F:
        for t in T:
            for o in C:
                for d in C:
                    if o != d:
                        x[f, o, d, t] = model.addVar(vtype="B",
                                                     name="x(%s, %s, %s, %s)" %
                                                     (f, o, d, t))

    # ground arc variables (y=1 if aircraft f at location o at time t)
    for f in F:
        for t in T_mod:
            for o in C:
                y[f, o, t] = model.addVar(vtype="B",
                                          name="y(%s, %s, %s)" % (f, o, t))

    # variable for tank at time t for an airplane f
    for f in F:
        for t in T:
            z[f, t] = model.addVar(vtype="C", name="z(%s, %s)" % (f, t))

# ---------------------------------------------------------------------------------------------------------
# Constraints

# (1) every task is flown exactly once
    for o in C:
        for d in C:
            if (o, d) in L_tasks_mod:
                model.addCons(
                    quicksum(x[f, o, d, t] for f in F for t in T) == 1)

    # (2) continuity between flights and ground arches (very old version -> understand the calculation and does not work)
    for f in F:
        for t in T:
            for o in C:
                outgo_flight = quicksum(x[f, o, d, t] for d in C
                                        if (o, d) in L)
                income_flight = quicksum(x[f, d, o, t - L[d, o][2]] for d in C
                                         if (d, o) in L.keys()
                                         if t - L[d, o][2] >= 0)
                model.addCons(y[f, o, t - 0.5] + income_flight - outgo_flight -
                              y[f, o, t + 0.5] == 0)

    # (3) assign the location of each aircraft in the beginning of optimisation
    if x_start != -1 and y_start != -1:
        # (3a) starting points for aircraft postition
        for k in y_start:
            model.addCons(y[k] == y_start[k])

        # (3b) starting points for aircraft starting times at position to position
        for k in x_start:
            model.addCons(x[k] == x_start[k])
    else:
        # (3c) starting from the base
        for f in F:
            model.addCons(y[f, C[0], T_mod[0]] == 1)
            C_mod = C[1:]
            for c in C_mod:
                model.addCons(y[f, c, T_mod[0]] == 0)

    # (6) no exceed of the capacity of the aircraft allowed
    for f in F:
        for t in T:
            for k, v in L_tasks_mod.items():
                model.addCons(F[f][0] - v[1] * x[f, k[0], k[1], t] >= 0)

    # (7) no exceed of the deadline of the task
    for f in F:
        for t in T:
            for k, v in L_tasks_mod.items():
                model.addCons(x[f, k[0], k[1], t] * t + v[2] <= v[0])

    # (8) full tank at time 0
    for f in F:
        model.addCons(z[f, 0] == F[f][1])

    # (9) refill at base (C[0])
    for f in F:
        for t in T:
            if t >= 1:

                C_without_base = []
                for c in C_fictive:
                    if t - L[c, C[0]][2] >= 0:
                        C_without_base.append(c)

                C2_without_base = []
                for o in C:
                    for d in C:
                        if (o, d) in L:
                            if d != C[0] and t - L[o, d][2] >= 0:

                                C2_without_base.append([o, d])

                base_at_t = quicksum(x[f, o, C[0], t - L[o, C[0]][2]]
                                     for o in C_without_base)
                tank_loss = quicksum(
                    (L[c[0], c[1]][2]) * x[f, c[0], c[1], t - L[c[0], c[1]][2]]
                    for c in C2_without_base)
                # the "fuel" you have now, is the sum of all "fuel"-loss subtracted from the tank and filled by every
                # pass of the base
                model.addCons(z[f, t] == z[f, t - 1] - tank_loss +
                              (-z[f, t - 1] + F[f][1]) * base_at_t)
                # at every time we need enough "fuel" in order to get back
                model.addCons(z[f, t] >= 0)

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

# calculate cost dict{(f,o,d,t)}
    cost = dict()
    for f in range(len(F)):
        for t in T:
            for k, v in L.items():
                if (k[0] % num_cities) == (k[1] % num_cities):
                    cost[f, k[0], k[1], t] = 0.01 / len(L_tasks_mod)
                else:
                    cost[f, k[0], k[1], t] = (F[f][0] - v[1]) * v[2]

    # Objective
    model.setObjective(
        quicksum(cost[f, o, d, t] * x[f, o, d, t] for f in F for o in C
                 for d in C for t in T if (f, o, d, t) in cost), "minimize")

    print('solve optimisation problem...')
    model.optimize()

    model.data = x, y, z
    return model
Ejemplo n.º 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'
Ejemplo n.º 55
0
def solve(epitopes):
    """
    Map each vertex to the set of incoming edge variables. 
    """
    incoming_edges = collections.defaultdict(list)
    outgoing_edges = collections.defaultdict(list)    
    source_edges = []
    sink_edges = []
    model = Model()
    print('got the model')
    print('size of epitopes: ' + str(len(epitopes)))
    for u, u_count in epitopes.items():
        #add incoming edge from source node
        variable = model.addVar(vtype='B')
        incoming_edges[u].append((variable, u))
        source_edges.append((u, variable))
        #add outgoing edge to sink node
        variable = model.addVar(vtype='B')
        outgoing_edges[u].append((variable, None))
        sink_edges.append(variable)
        for v, v_count in epitopes.items():
            if (not u == v) and u[1::] == v[0:-1]:
                #add a variable for the edge.
                variable = model.addVar(vtype='B', lb=0, ub=1)
                incoming_edges[v].append((variable, u))
                outgoing_edges[u].append((variable, v))
    
    print('added variables')
    
    for u, u_count in epitopes.items():
        #for each vertex, make sure at most one incoming edge is part of the path
        model.addCons(quicksum([x[0] for x in incoming_edges[u]]) <= 1)
        #balance the outgoing and incoming edges for each node
        model.addCons(quicksum([x[0] for x in incoming_edges[u]]) == quicksum([x[0] for x in outgoing_edges[u]]))
    #exactly one edge coming out of the source is part of the path.
    model.addCons(quicksum([x[1] for x in source_edges]) == 1)
    #exactly one edge going into the sink is part of the path
    model.addCons(quicksum(sink_edges) == 1)
    print('added constraints')
    #now, formulate the objective function.
    model.setObjective(quicksum([u_count*quicksum([x[0] for x in incoming_edges[u]]) for u,u_count in epitopes.items()]), 'maximize')
    print('set objective')
    model.optimize()
    starting_vertex = None
    for source_edge in source_edges:
        #sometimes it's slightly off by a tiny bit (like 10^-12 or something)
        if round(model.getVal(source_edge[1])) == 1:
            starting_vertex = source_edge[0]
            break
    assert(starting_vertex)
    path = [starting_vertex]
    while True:
        edges = outgoing_edges[starting_vertex]
        variable = None
        next_vertex = None
        for var, seq in edges:
            if round(model.getVal(var)) == 1:
                variable = var
                next_vertex = seq
                break
        
        if next_vertex:
            path.append(next_vertex)
            starting_vertex = next_vertex
        else:
            print('breaking')
            break
    assert(len(path) == len(set(path)))
    synthetic = path[0] + ''.join(x[-1] for x in path[1::])
    
    return synthetic
Ejemplo n.º 56
0
def solveCuttingStock(w, q, B):
    """solveCuttingStock: use column generation (Gilmore-Gomory approach).
    Parameters:
        - w: list of item's widths
        - q: number of items of a width
        - B: bin/roll capacity
    Returns a solution: list of lists, each of which with the cuts of a roll.
    """
    t = []  # patterns
    m = len(w)

    # Generate initial patterns with one size for each item width
    for (i, width) in enumerate(w):
        pat = [
            0
        ] * m  # vector of number of orders to be packed into one roll (bin)
        pat[i] = int(B / width)
        t.append(pat)

    # if LOG:
    #     print "sizes of orders=",w
    #     print "quantities of orders=",q
    #     print "roll size=",B
    #     print "initial patterns",t

    K = len(t)
    master = Model("master LP")  # master LP problem
    x = {}

    for k in range(K):
        x[k] = master.addVar(vtype="I", name="x(%s)" % k)

    orders = {}

    for i in range(m):
        orders[i] = master.addCons(
            quicksum(t[k][i] * x[k] for k in range(K) if t[k][i] > 0) >= q[i],
            "Order(%s)" % i)

    master.setObjective(quicksum(x[k] for k in range(K)), "minimize")

    # master.Params.OutputFlag = 0 # silent mode

    # iter = 0
    while True:
        # print "current patterns:"
        # for ti in t:
        #     print ti
        # print

        # iter += 1
        relax = master.relax()
        relax.optimize()
        pi = [relax.getDualsolLinear(c)
              for c in relax.getConss()]  # keep dual variables

        knapsack = Model("KP")  # knapsack sub-problem
        knapsack.setMaximize  # maximize
        y = {}

        for i in range(m):
            y[i] = knapsack.addVar(lb=0, ub=q[i], vtype="I", name="y(%s)" % i)

        knapsack.addCons(quicksum(w[i] * y[i] for i in range(m)) <= B, "Width")

        knapsack.setObjective(quicksum(pi[i] * y[i] for i in range(m)),
                              "maximize")

        knapsack.hideOutput()  # silent mode
        knapsack.optimize()
        # if LOG:
        #     print "objective of knapsack problem:", knapsack.ObjVal
        if knapsack.getObjVal() < 1 + EPS:  # break if no more columns
            break

        pat = [int(y[i].X + 0.5) for i in y]  # new pattern
        t.append(pat)
        # if LOG:
        #     print "shadow prices and new pattern:"
        #     for (i,d) in enumerate(pi):
        #         print "\t%5s%12s%7s" % (i,d,pat[i])
        #     print

        # add new column to the master problem
        col = Column()
        for i in range(m):
            if t[K][i] > 0:
                col.addTerms(t[K][i], orders[i])
        x[K] = master.addVar(obj=1, vtype="I", name="x(%s)" % K, column=col)

        # master.write("MP" + str(iter) + ".lp")
        K += 1

    # Finally, solve the IP
    # if LOG:
    #     master.Params.OutputFlag = 1 # verbose mode
    master.optimize()

    # if LOG:
    #     print
    #     print "final solution (integer master problem):  objective =", master.ObjVal
    #     print "patterns:"
    #     for k in x:
    #         if x[k].X > EPS:
    #             print "pattern",k,
    #             print "\tsizes:",
    #             print [w[i] for i in range(m) if t[k][i]>0 for j in range(t[k][i]) ],
    #             print "--> %s rolls" % int(x[k].X+.5)

    rolls = []
    for k in x:
        for j in range(int(x[k].X + .5)):
            rolls.append(
                sorted([
                    w[i] for i in range(m) if t[k][i] > 0
                    for j in range(t[k][i])
                ]))
    rolls.sort()
    return rolls
Ejemplo n.º 57
0
def assignment02(SCENARIO1Revenue, SCENARIO2Revenue, SCENARIO3Revenue,
                 SCENARIO1Yield, SCENARIO2Yield, SCENARIO3Yield,
                 Varieties, WineBrand, Percentage, Costs, Areas, Parcels, BigM, Scenarios):
    model = Model("assignment02")

    ###################
    # -- Variables -- #
    ###################

    x, y, z, a, t, g = {}, {}, {}, {}, {}, {}

    # x - amount of barels of vareity v used in wine w in scenario s
    # y - planted area of variety v in parcel p
    # t - "fake" varible that counts the produced quantity of varity v in scenario s
    # g - "fake" varible that counts the produced quantity of wine w in scenario s
    # a - binary variable that turns into 1 when we produce more than 5 barels of a wine brand in scenario s
    # z - binary variable that turns into 1 when we produce variety v in parcel p

    for v in Varieties:
        for w in WineBrand:
            for s in Scenarios:
                x[v, w, s] = model.addVar(vtype="C", name="x(%s,%s,%s)" % (v, w, s))

    for v in Varieties:
        for p in Parcels:
            z[v, p] = model.addVar(vtype="B", name="z(%s,%s)" % (v, p))
            y[v, p] = model.addVar(vtype="C", name="y(%s,%s)" % (v, p))

    for w in WineBrand:
        for s in Scenarios:
            a[w, s] = model.addVar(vtype="B", name="a(%s,%s)" % (w, s))

    for v in Varieties:
        for s in Scenarios:
            t[v, s] = model.addVar(vtype="C", name="t(%s,%s)" % (v, s))

    for w in WineBrand:
        for s in Scenarios:
            g[w, s] = model.addVar(vtype="C", name="g(%s,%s)" % (w, s))

    ######################
    # -- Restrictions -- #
    ######################

    for v in Varieties:
        model.addCons(t[v, 1] == quicksum(SCENARIO1Yield[v][p] * y[v, p] for p in Parcels))
        model.addCons(t[v, 2] == quicksum(SCENARIO2Yield[v][p] * y[v, p] for p in Parcels))
        model.addCons(t[v, 3] == quicksum(SCENARIO3Yield[v][p] * y[v, p] for p in Parcels))

    for s in Scenarios:
        for w in WineBrand:
            model.addCons(g[w, s] == quicksum(x[v, w, s] for v in Varieties))

    for v in Varieties:
        for p in Parcels:
            model.addCons(y[v, p] <= BigM * z[v, p], "Area Big M")

    model.addCons(quicksum(y[v, p] * Costs[v] + FIXED_COST * z[v, p] for v in Varieties for p in Parcels) <= B, "Budget")

    for p in Parcels:
        model.addCons(quicksum(y[v, p] for v in Varieties) <= Areas[p], "Maximum Area")

    for v in Varieties:
        for s in Scenarios:
            model.addCons(quicksum(x[v, w, s] for w in WineBrand) <= t[v, s], "Can't use more than what was produced")

    for v in Varieties:
        for w in WineBrand:
            for s in Scenarios:
                model.addCons(x[v, w, s] >= g[w, s] * Percentage[v][w], "Minimum Percentage")

    for w in WineBrand:
        for s in Scenarios:
            model.addCons(quicksum(x[v, w, s] for v in Varieties) >= 5 * a[w, s], "More than five Barrels")

    for s in Scenarios:
        model.addCons(quicksum(a[w, s] for w in WineBrand) >= 3, "At least three Brands")

    ###################
    # -- Objective -- #
    ###################

    ratio = 1 / 3

    model.setObjective((quicksum(g[w, 1] * SCENARIO1Revenue[w] * ratio for w in WineBrand) +
                        quicksum(g[w, 2] * SCENARIO2Revenue[w] * ratio for w in WineBrand) +
                        quicksum(g[w, 3] * SCENARIO3Revenue[w] * ratio for w in WineBrand)), "maximize")

    model.data = x, y, z, a, t, g

    return model
Ejemplo n.º 58
0
def scheduling_cutting_plane(J,p,r,w):
    """
    scheduling_cutting_plane: heuristic to one machine weighted completion time based on cutting planes

    Use a cutting-plane method as a heuristics for solving the
    one-machine total weighted completion time problem with release
    times.

    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 tuple with values of:
        - bestC: corresponding completion time of the best found solution
        - bestobj: best, best, hobj
    """

    model = Model("scheduling: cutting plane")

    C = {}   # completion time variable
    for j in J:
        C[j] = model.addVar(lb=r[j]+p[j], obj=w[j], vtype="C", name="C(%s)"%j)


    sumP = sum([p[j] for j in J])
    sumP2 = sum([p[j]**2 for j in J])
    model.addCons(C[j]*p[j] >= sumP2*0.5 + (sumP**2)*0.5, "AllJobs")

    model.setObjective(quicksum(w[j]*C[j] for j in J), "minimize")

    cut = 0
    bestobj = float("inf")
    while True:
        model.optimize()
        sol = sorted([(model.getVal(C[j]),j) for j in C])
        seq = [j for (completion,j) in sol]

        # print("Opt.value=",model.getObjVal()
        # print("current solution:", seq
        hC,hobj = evaluate(seq,p,r,w)
        if hobj < bestobj:
            # print("\t*** updating  best found solution:", bestobj, "--->", hobj, "***"
            bestC = hC
            bestobj = hobj
            best = list(seq)

        S,S_ = [],[]
        sumP,sumP2,f = 0,0,0
        for (C_,j) in sol:
            pj = p[j]
            delta = pj**2 + ((sumP+pj)**2 - sumP**2) - 2*pj*C_
            if f > 0 and delta <= 0:
                S = S_
                break
            f += delta/2.
            sumP2 += pj**2
            sumP += pj
            S_.append(j)

        if S == []:
            break

        cut += 1
        model.addCons(quicksum(C[j]*p[j] for j in S) >= sumP2*0.5 + (sumP**2)*0.5, "Cut(%s)"%cut)

    return bestC,bestobj,best
Ejemplo n.º 59
0
# @file tutorial/puzzle.py
# @brief solve a simple puzzle using SCIP
"""
On a beach there are octopuses, turtles and cranes.
The total number of legs of all animals is 80, while the number of heads is 32.
What are the minimum numbers of turtles and octopuses, respectively?

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

model = Model("puzzle", enablepricing=False)
x = model.addVar(vtype="I", name="octopusses")  #, pricedVar=True)
y = model.addVar(vtype="I", name="turtles")
z = model.addVar(vtype="I", name="cranes")

# Set up constraint for number of heads
model.addCons(x + y + z == 32, name="Heads")

# Set up constraint for number of legs
model.addCons(8 * x + 4 * y + 2 * z == 80, name="Legs")
# TODO infeasible, but answers
cons1 = model.addCons(x <= 1, initial=False, modifiable=True, removable=True)
cons2 = model.addCons(y <= 3)

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

# model.hideOutput()
# model.writeStatistics('/tmp/stat.out')
model.writeLP('./Lp.lp')
Ejemplo n.º 60
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-5