コード例 #1
1
ファイル: diet_std.py プロジェクト: SCIP-Interfaces/PySCIPOpt
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
コード例 #2
0
ファイル: prodmix_soco.py プロジェクト: fserra/PySCIPOpt
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
コード例 #3
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
コード例 #4
0
def scheduling_time_index(J,p,r,w):
    """
    scheduling_time_index: model for the one machine total weighted tardiness problem

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

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

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

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

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

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

    model.data = X
    return model
コード例 #5
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
コード例 #6
0
ファイル: tsp_flow.py プロジェクト: SCIP-Interfaces/PySCIPOpt
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
コード例 #7
0
ファイル: gcp_fixed_k.py プロジェクト: mattmilten/PySCIPOpt
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
コード例 #8
0
ファイル: gcp.py プロジェクト: SCIP-Interfaces/PySCIPOpt
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
コード例 #9
0
def gcp_sos(V, E, K):
    """gcp_sos -- model for minimizing the number of colors in a graph
    (use sos type 1 constraints)
    Parameters:
        - V: set/list of nodes in the graph
        - E: set/list of edges in the graph
        - K: upper bound to the number of colors
    Returns a model, ready to be solved.
    """
    model = Model("gcp - sos constraints")
    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)
        model.addConsSOS1([x[i, k] for k in range(K)])
    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))
    for k in range(K - 1):
        model.addCons(y[k] >= y[k + 1], "LowColor(%s)" % k)
    model.setObjective(quicksum(y[k] for k in range(K)), "minimize")
    model.data = x, y
    return model
コード例 #10
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
コード例 #11
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
コード例 #12
0
ファイル: eld.py プロジェクト: zhenjames/PySCIPOpt
def eld_another(U,p_min,p_max,d,brk):
    """eld -- economic load dispatching in electricity generation
    Parameters:
        - U: set of generators (units)
        - p_min[u]: minimum operating power for unit u
        - p_max[u]: maximum operating power for unit u
        - d: demand
        - brk[u][k]: (x,y) coordinates of breakpoint k, k=0,...,K for unit u
    Returns a model, ready to be solved.
    """
    model = Model("Economic load dispatching")

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

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

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

    model.data = p
    return model
コード例 #13
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
コード例 #14
0
ファイル: mctransp.py プロジェクト: zhenjames/PySCIPOpt
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
コード例 #15
0
ファイル: flp.py プロジェクト: Rotaka92/py-ga-VRPTW
def flp(I, J, d, M, f, c):
    model = Model("flp")
    x, y = {}, {}
    for j in J:
        #j = 1
        y[j] = model.addVar(vtype="B", name="y(%s)" % j)
        for i in I:
            #i = 1
            x[i, j] = model.addVar(vtype="C", name="x(%s,%s)" % (i, j))
    for i in I:
        #i = 1,2,3,4,5
        model.addCons(quicksum(x[i, j] for j in J) == d[i], "Demand(%s)" % i)
    for j in M:
        #j = 1,2,3
        model.addCons(
            quicksum(x[i, j] for i in I) <= M[j] * y[j], "Capacity(%s)" % i)
    for (i, j) in x:
        #(i,j) = (1,1), (2,1), ...
        model.addCons(x[i, j] <= d[i] * y[j], "Strong(%s,%s)" % (i, j))
    model.setObjective(
        quicksum(f[j] * y[j] for j in J) + quicksum(c[i, j] * x[i, j]
                                                    for i in I
                                                    for j in J), "minimize")
    model.data = x, y
    return model
コード例 #16
0
ファイル: kmedian.py プロジェクト: SCIP-Interfaces/PySCIPOpt
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
コード例 #17
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
コード例 #18
0
ファイル: transp.py プロジェクト: fserra/PySCIPOpt
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
コード例 #19
0
ファイル: mctransp.py プロジェクト: SCIP-Interfaces/PySCIPOpt
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
コード例 #20
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
コード例 #21
0
ファイル: diet_std.py プロジェクト: npwebste/UPS_Controller
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
コード例 #22
0
def scheduling_disjunctive(J,p,r,w):
    """
    scheduling_disjunctive: model for the one machine total weighted completion time problem

    Disjunctive optimization model for 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 model, ready to be solved.
    """
    model = Model("scheduling: disjunctive")

    M = max(r.values()) + sum(p.values())       # big M
    s,x = {},{}      # start time variable, x[j,k] = 1 if job j precedes job k, 0 otherwise
    for j in J:
        s[j] = model.addVar(lb=r[j], vtype="C", name="s(%s)"%j)
        for k in J:
            if j != k:
                x[j,k] = model.addVar(vtype="B", name="x(%s,%s)"%(j,k))
    for j in J:
        for k in J:
            if j != k:
                model.addCons(s[j] - s[k] + M*x[j,k] <= (M-p[j]), "Bound(%s,%s)"%(j,k))
            if j < k:
                model.addCons(x[j,k] + x[k, j] == 1, "Disjunctive(%s,%s)"%(j,k))
    model.setObjective(quicksum(w[j] * s[j] for j in J), "minimize")
    model.data = s, x
    return model
コード例 #23
0
def mkp(I,J,v,a,b):
    """mkp -- model for solving the multi-constrained knapsack
    Parameters:
        - I: set of dimensions
        - J: set of items
        - v[j]: value of item j
        - a[i,j]: weight of item j on dimension i
        - b[i]: capacity of knapsack on dimension i
    Returns a model, ready to be solved.
    """
    model = Model("mkp")

    # Create Variables
    x = {}
    for j in J:
        x[j] = model.addVar(vtype="B", name="x(%s)"%j)

    # Create constraints
    for i in I:
        model.addCons(quicksum(a[i,j]*x[j] for j in J) <= b[i], "Capacity(%s)"%i)

    # Objective
    model.setObjective(quicksum(v[j]*x[j] for j in J), "maximize")
    model.data = x

    return model
コード例 #24
0
ファイル: vrp_lazy.py プロジェクト: SCIP-Interfaces/PySCIPOpt
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
コード例 #25
0
ファイル: atsp.py プロジェクト: fserra/PySCIPOpt
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
コード例 #26
0
ファイル: diet.py プロジェクト: whille/PySCIPOpt
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)    # number of dishes of Food j
        y[j] = model.addVar(vtype="B", name="y(%s)" % j)    # take or not of Food j
    for i in N:
        z[i] = model.addVar(lb=a[i], ub=b[i], name="z(%s)" % j)
    v = model.addVar(vtype="C", name="v")
    # Constraints:
    for i in N:
        # a <= z <= b, use variable z for constrains
        model.addCons(quicksum(d[j][i] * y[j] * x[j] for j in F) == z[i], name="Nutr(%s)" % i)
    model.addCons(quicksum(c[j] * x[j] for j in F) == v, name="Cost")
    for j in F:
        model.addCons(y[j] <= x[j], name="Eat(%s)" % j)
    # Objective: take minimum number of distinct foods.
    model.setObjective(quicksum(y[j] for j in F), "minimize")
    # min total cost is common objective
    # model.setObjective(v, "minimize")
    model.data = x, y, z, v
    return model
コード例 #27
0
def flp(I, J, d, M, f, c):
    """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 = {}, {}
    for j in J:
        y[j] = model.addVar(vtype="B", name="y(%s)" % j)
        for i in I:
            x[i, j] = model.addVar(vtype="C", name="x(%s,%s)" % (i, j))
    # constrains
    for i in I:
        model.addCons(quicksum(x[i, j] for j in J) == d[i], "Demand(%s)" % i)
    for j in M:
        model.addCons(
            quicksum(x[i, j] for i in I) <= M[j] * y[j], "Capacity(%s)" % i)
    for (i, j) in x:
        model.addCons(x[i, j] <= d[i] * y[j], "Strong(%s,%s)" % (i, j))

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

    return model
コード例 #28
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
コード例 #29
0
ファイル: weber_soco.py プロジェクト: zhenjames/PySCIPOpt
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
コード例 #30
0
def solveX(AGVs={}, costAGV2Rack={}, Faces={}, ALPHA={}):
    #ALPHA
    ALPHA1 = ALPHA[1]
    ALPHA2 = ALPHA[2]
    ALPHA3 = ALPHA[3]
    model = Model('Tri-partite-X')
    X = {}
    for (i, j) in crossproduct(AGVs, Faces):
        X[i,
          j] = model.addVar(vtype='B',
                            name='To assign %s to %s - %s' % (i, j[0], j[1]))
    #Adding Constraints (1) An AGV can be assigned to at most 1 Face
    for i in AGVs:
        model.addCons(quicksum(X[i, j] for j in Faces) <= 1,
                      name='Cons (1) for %s' % i)
    #Adding Constraints (3) A Face can be assigned to at most 1 AGV
    for j in Faces:
        model.addCons(quicksum(X[i, j] for i in AGVs) == 1,
                      name='Cons (3) for %s-%s' % (j[0], j[1]))
    model.setObjective(
        ALPHA1 * quicksum(X[i, j] for (i, j) in X) +
        ALPHA2 * quicksum(X[i, j] * costAGV2Rack[i, j[0]] for (i, j) in X),
        "minimize")
    model.data = X
    model.optimize()
    faces_agv = {}
    for (i, j) in X:
        a = model.getVal(X[i, j])
        if a > 0.5:
            print(i, j), a
            faces_agv[j] = i
    return model, faces_agv
コード例 #31
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
コード例 #32
0
def kcover(I,J,c,k):
    """kcover -- minimize the number of uncovered 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-center")

    z,y,x = {},{},{}
    for i in I:
        z[i] = model.addVar(vtype="B", name="z(%s)"%i, obj=1)
    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) + z[i] == 1, "Assign(%s)"%i)
        for j in J:
            model.addCons(x[i,j] <= y[j], "Strong(%s,%s)"%(i,j))

    model.addCons(sum(y[j] for j in J) == k, "k_center")
    model.data = x,y,z

    return model
コード例 #33
0
ファイル: gcp.py プロジェクト: zkcz/PySCIPOpt
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
コード例 #34
0
ファイル: tsp_flow.py プロジェクト: npwebste/UPS_Controller
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
コード例 #35
0
ファイル: weber_soco.py プロジェクト: fserra/PySCIPOpt
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
コード例 #36
0
ファイル: kmedian.py プロジェクト: whille/PySCIPOpt
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
コード例 #37
0
ファイル: kcenter.py プロジェクト: SCIP-Interfaces/PySCIPOpt
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
コード例 #38
0
def scheduling_time_index(J,p,r,w):
    """
    scheduling_time_index: model for the one machine total weighted tardiness problem

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

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

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

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

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

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

    model.data = X
    return model
コード例 #39
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
コード例 #40
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
コード例 #41
0
ファイル: eoq_soco.py プロジェクト: SCIP-Interfaces/PySCIPOpt
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
コード例 #42
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
コード例 #43
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
コード例 #44
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
コード例 #45
0
ファイル: gpp.py プロジェクト: SCIP-Interfaces/PySCIPOpt
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
コード例 #46
0
ファイル: flp-benders.py プロジェクト: mattmilten/PySCIPOpt
def flp(I,J,d,M,f,c):
    """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.
    """

    master = Model("flp-master")
    subprob = Model("flp-subprob")

    # creating the problem
    y = {}
    for j in J:
        y[j] = master.addVar(vtype="B", name="y(%s)"%j)

    master.setObjective(
        quicksum(f[j]*y[j] for j in J),
        "minimize")
    master.data = y

    # creating the subproblem
    x,y = {},{}
    for j in J:
        y[j] = subprob.addVar(vtype="B", name="y(%s)"%j)
        for i in I:
            x[i,j] = subprob.addVar(vtype="C", name="x(%s,%s)"%(i,j))

    for i in I:
        subprob.addCons(quicksum(x[i,j] for j in J) == d[i], "Demand(%s)"%i)

    for j in M:
        subprob.addCons(quicksum(x[i,j] for i in I) <= M[j]*y[j], "Capacity(%s)"%i)

    for (i,j) in x:
        subprob.addCons(x[i,j] <= d[i]*y[j], "Strong(%s,%s)"%(i,j))

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

    return master, subprob
コード例 #47
0
ファイル: mintreeMFP.py プロジェクト: yuuzhang/ndnSIM20180908
def MaxMFP(n, e, d):
    """
    MaxMFP: Max sum 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========Max multi-commodity flow Problem======")
    model = Model("MaxMFP")
    x, vard = {}, {}  # flow variable
    for (s, t) in d.keys():
        vard[s, t] = model.addVar(ub=1000000,
                                  lb=0.0,
                                  vtype="C",
                                  name="vard[%s,%s]" % (s, t))
    for (i, j) in e.keys():
        for (s, t) in d.keys():
            x[i, j, s, t] = model.addVar(ub=1000000,
                                         lb=0.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()) == vard[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()) == -vard[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():
        model.addCons(
            quicksum(x[i, j, s, t] for (s, t) in d.keys()) <= e[i, j]['cap'],
            'edge(%s,%s)' % (i, j))
    model.data = x, vard

    model.setObjective(quicksum(vard[s, t] for (s, t) in d.keys()), "maximize")
    return model
コード例 #48
0
ファイル: flp3a.py プロジェクト: Rotaka92/py-ga-VRPTW
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
    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])

        #demand has to be completely served by only one facility

    for i in range(I):
        model.addCons(quicksum(y2[i, j] for j in range(len(J))) == 1.0)

        ####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
コード例 #49
0
ファイル: mintreeMFP.py プロジェクト: yuuzhang/ndnSIM20180908
def maxConcurrentFlowMinCostMFP(n, e, d):
    """
    maxConcurrentMFP: max concurrent multi-commodity flow and min Cost Problem
    2018-3-27 如果目标函数中没有加入最小代价,在Mac和Ubuntu下的计算结果都不一样,显然同样的lamb下有多中路由方式。而且也可以去除环路
    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 = {}  # flow variable
    lamb = model.addVar(ub=1000000, lb=1.0, vtype="C", name="lamb")
    for (i, j) in e.keys():
        for (s, t) in d.keys():
            x[i, j, s, t] = model.addVar(ub=1000000,
                                         lb=0.0,
                                         vtype="I",
                                         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] * lamb,
                    "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] * lamb,
                    "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():
        model.addCons(
            quicksum(x[i, j, s, t] for (s, t) in d.keys()) <= e[i, j]['cap'],
            'edge(%s,%s)' % (i, j))
    model.data = lamb, x
    model.setObjective(
        lamb - 0.0001 * quicksum(
            quicksum(x[i, j, s, t] for (s, t) in d.keys())
            for (i, j) in e.keys()), "maximize")
    #model.setObjective(lamb-(quicksum(0.00000001*quicksum(x[i,j,s,t] for (s,t) in d.keys()) for (i,j) in e.keys())), "maximize")
    return model
コード例 #50
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
コード例 #51
0
def flp_nonlinear_cc_dis_strong(I,J,d,M,f,c,K):
    """flp_nonlinear_bin --  use convex combination model, with binary variables
    Parameters:
        - I: set of customers
        - J: set of facilities
        - d[i]: demand for customer i
        - M[j]: capacity of facility j
        - f[j]: fixed cost for using a facility in point j
        - c[i,j]: unit cost of servicing demand point i from facility j
        - K: number of linear pieces for approximation of non-linear cost function
    Returns a model, ready to be solved.
    """
    a,b = {},{}
    for j in J:
        U = M[j]
        L = 0
        width = U/float(K)
        a[j] = [k*width for k in range(K+1)]
        b[j] = [f[j]*math.sqrt(value) for value in a[j]]

    model = Model("nonlinear flp -- piecewise linear version with convex combination")
    
    x = {}
    for j in J:
        for i in I:
            x[i,j] = model.addVar(vtype="C", name="x(%s,%s)"%(i,j))  # i's demand satisfied from j
    

    # total volume transported from plant j, corresponding (linearized) cost, selection variable:
    X,F,z = {},{},{}
    for j in J:
        # add constraints for linking piecewise linear part:
        X[j],F[j],z[j] = convex_comb_dis(model,a[j],b[j])
        X[j].ub = M[j]
        for i in I:
            model.addCons(
                x[i,j] <= \
                quicksum(min(d[i],a[j][k+1]) * z[j][k] for k in range(K)),\
                "Strong(%s,%s)"%(i,j))

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

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

    model.setObjective(quicksum(F[j] for j in J) +\
                       quicksum(c[i,j]*x[i,j] for j in J for i in I),\
                       "minimize")

    model.data = x,X,F
    return model
コード例 #52
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
コード例 #53
0
def staff(I,T,N,J,S,c,b):
    """
    staff: staff scheduling
    Parameters:
        - I: set of members in the staff
        - T: number of periods in a cycle
        - N: number of working periods required for staff's elements in a cycle
        - J: set of shifts in each period (shift 0 == rest)
        - S: subset of shifts that must be kept at least consecutive days
        - c[i,t,j]: cost of a shift j of staff's element i on period t
        - b[t,j]: number of staff elements required in period t, shift j
    Returns a model, ready to be solved.
    """
    Ts = range(1,T+1)
    model = Model("staff scheduling")

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


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

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


    model.data = x
    return model
コード例 #54
0
ファイル: eoq_en.py プロジェクト: SCIP-Interfaces/PySCIPOpt
def eoq(I,F,h,d,w,W,a0,aK,K):
    """eoq --  multi-item capacitated economic ordering quantity model
    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)
        - a0: lower bound on the cycle time (x axis)
        - aK: upper bound on the cycle time (x axis)
        - K: number of linear pieces to use in the approximation
    Returns a model, ready to be solved.
    """

    # construct points for piecewise-linear relation, store in a,b
    a,b = {},{}
    delta = float(aK-a0)/K
    for i in I:
        for k in range(K):
            T = a0 + delta*k
            a[i,k] = T                          # abscissa: cycle time
            b[i,k] = F[i]/T + h[i]*d[i]*T/2.    # ordinate: (convex) cost for this cycle time

    model = Model("multi-item, capacitated EOQ")

    x,c,w_ = {},{},{}
    for i in I:
        x[i] = model.addVar(vtype="C", name="x(%s)"%i)  # cycle time for item i
        c[i] = model.addVar(vtype="C", name="c(%s)"%i)  # total cost for item i
        for k in range(K):
            w_[i,k] = model.addVar(ub=1, vtype="C", name="w(%s,%s)"%(i,k)) #todo ??

    for i in I:
        model.addCons(quicksum(w_[i,k] for k in range(K)) == 1)
        model.addCons(quicksum(a[i,k]*w_[i,k] for k in range(K)) == x[i])
        model.addCons(quicksum(b[i,k]*w_[i,k] for k in range(K)) == c[i])

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

    model.setObjective(quicksum(c[i] for i in I), "minimize")

    model.data = x,w
    return model
コード例 #55
0
ファイル: gpp.py プロジェクト: SCIP-Interfaces/PySCIPOpt
def gpp_qo_ps(V,E):
    """gpp_qo_ps -- quadratic optimization, positive semidefinite 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 = {}
    for i in V:
        x[i] = model.addVar(vtype="B", name="x(%s)"%i)

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

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

    model.data = x
    return model
コード例 #56
0
ファイル: bpp.py プロジェクト: fserra/PySCIPOpt
def bpp(s,B):
    """bpp: Martello and Toth's model to solve the bin packing problem.
    Parameters:
        - s: list with item widths
        - B: bin capacity
    Returns a model, ready to be solved.
    """
    n = len(s)
    U = len(FFD(s,B)) # upper bound of the number of bins
    model = Model("bpp")
    # setParam("MIPFocus",1)
    x,y = {},{}
    for i in range(n):
        for j in range(U):
            x[i,j] = model.addVar(vtype="B", name="x(%s,%s)"%(i,j))
    for j in range(U):
        y[j] = model.addVar(vtype="B", name="y(%s)"%j)

    # assignment constraints
    for i in range(n):
        model.addCons(quicksum(x[i,j] for j in range(U)) == 1, "Assign(%s)"%i)

    # bin capacity constraints
    for j in range(U):
        model.addCons(quicksum(s[i]*x[i,j] for i in range(n)) <= B*y[j], "Capac(%s)"%j)

    # tighten assignment constraints
    for j in range(U):
        for i in range(n):
            model.addCons(x[i,j] <= y[j], "Strong(%s,%s)"%(i,j))

    # tie breaking constraints
    for j in range(U-1):
        model.addCons(y[j] >= y[j+1],"TieBrk(%s)"%j)

    # SOS constraints
    for i in range(n):
        model.addConsSOS1([x[i,j] for j in range(U)])

    model.setObjective(quicksum(y[j] for j in range(U)), "minimize")
    model.data = x,y

    return model