Search code examples
pythonmathematical-optimizationpulp

Formulating constraints of a LP in Pulp Python


I have this LP problem, and I'm trying to solve it using PuLP in Python-3. One option that I can think of is to write all variable explicitly, but I want to avoid it. Is there a way that I can use lists/dicts in this problem? (I did refer to https://pythonhosted.org/PuLP/CaseStudies/a_sudoku_problem.html where dicts were being used, but didn't quite understand the entire solution)

Assume wt{i,j,type} denotes the number of traded goods between person[i] and person[j] of type.

LP Problem: The objective function image

(Here, cost{i,j} is a known cost of pairing for all (i,j) pairs.

subject to:

The constraint equations image

I would be really grateful for any help, as I'm a beginner to both optimization and python/pulp.


Solution

  • The 'lists/dicts' is a way to define variables over domains (indexed variables). The indexs argument of LpVariable.dicts() defines the domain - cartesian product of the supplied sets. See also documentation of PuLP - LpVariable.

    The code sample below does not contain all your constraints, but I believe you can easily fill-in the remaining ones. Constraint 1 (with const1 and const2) is treated via the lower and upper bound of the wt variable instead.

    from pulp import LpProblem, LpVariable, LpMaximize, LpInteger, lpSum, value
    
    prob = LpProblem("problem", LpMaximize)
    
    # define 'index sets'
    I = range(10) # [0, 1, ..., 9]
    J = range(10)
    T = range(3)
    
    # define parameter cost[i,j]
    cost = {}
    for i in I:
        for j in J:
            cost[i,j] = i + j # whatever
    
    # define wt[i,j,t]
    const1 = 0 # lower bound for w[i,j,t]
    const2 = 100 # upper bound for w[i,j,t]
    wt = LpVariable.dicts(name="wt", indexs=(I, J, T), lowBound=const1, upBound=const2, cat=LpInteger)
    
    # define assign[i,j]
    assign = LpVariable.dicts(name="assign", indexs=(I, J))
    
    # contraint 
    for i in I:
        for j in J:
            prob += assign[i][j] == lpSum(wt[i][j][t] for t in T), ""
    
    # objective
    prob += lpSum(cost[i,j] * assign[i][j] for i in I for j in J)
    
    prob.solve()
    
    for i in I:
        for j in J:
            for t in T:
                print "wt(%s, %s, %s) = %s" % (i, j, t, value(wt[i][j][t]))
    
    for i in I:
        for j in J:
            print "assign(%s, %s) = %s" % (i, j, value(assign[i][j]))