简体   繁体   中英

Adding a constraint in Linear Programming Optimization using PULP

The following code gives me the best places to go to vacation keeping the costs low :

from pulp import *
import numpy as np
import pandas as pd
import re 

#write a scaper before hand
data = pd.read_csv('clymb_adventures.csv')
problem_name = 'GoingOnVacation'
aval_vacation_days = 10

def optimize_vacation_schedule(aval_vacation_days):

# create the LP object, set up as a minimization problem --> since we 
want to minimize the costs 
prob = pulp.LpProblem(problem_name, pulp.LpMinimize)


#create decision variables
decision_variables = []
for rownum, row in data.iterrows():
    variable = str('x' + str(rownum))
    variable = pulp.LpVariable(str(variable), lowBound = 0, upBound = 1, cat= 'Integer') #make variables binary
    decision_variables.append(variable)

print ("Total number of decision_variables: " + str(len(decision_variables)))

#create objective Function -minimize the costs for the trip
total_cost = ""
for rownum, row in data.iterrows():
    for i, schedule in enumerate(decision_variables):
        if rownum == i:
            formula = row['cost']*schedule
            total_cost += formula

prob += total_cost
print ("Optimization function: " + str(total_cost)) 


#create constrains - total vacation days should be no more than 14
total_vacation_days = ""
for rownum, row in data.iterrows():
    for i, schedule in enumerate(decision_variables):
        if rownum == i:
            formula = row['duration']*schedule
            total_vacation_days += formula

prob += (total_vacation_days == aval_vacation_days)


#now run optimization
optimization_result = prob.solve()
assert optimization_result == pulp.LpStatusOptimal
prob.writeLP(problem_name + ".lp" )
print("Status:", LpStatus[prob.status])
print("Optimal Solution to the problem: ", value(prob.objective))
print ("Individual decision_variables: ")
for v in prob.variables():
    print(v.name, "=", v.varValue)

if __name__ == "__main__":
    optimize_vacation_schedule(aval_vacation_days)

Sample Dataset:

destination duration    cost    description                 location
0   Baja          7      899    Hike Bike                [31223,23123]
1   Nepal         11     899    culture of the Himalayas [91223,28123]
2   Spain         8      568    Sport climb              [66223,23123]
3   Yosemite      3      150    Guided hiking            [0223,23123]
4   Utah          6      156    Hike.                    [35523,23123]
5   Okla          1      136    Hike.                    [25523,23123]

I have added an extra field "location" in the dataset.

What I want to achieve is, if the solver gives me three 3 locations as the optimal solution then it has to make sure that the maximum manhattan distance between two consecutive suggested cites is not greater than 3000 using the location coordinates?

Example: If Yosemite,Utah and Okla are suggested by solver.Then before suggesting them it has to check that distance from Yosemite to Utah is below 3000 and Utah to Okla is below 3000.

This also makes it as routing problem.

So how can I add a constraint which keeps the distance between two consecutive suggested cities below 3000 using location coordinates. Please help

Thank you!!!!

If you want to add the condition x(i,j) == 1 as a constraint, then you would create a second set of decision variables. Have the key be the tuple(i, j) and the value is an LpVariable with cat='Binary'. Then you have to set some additional constraints.

NOTE: I'm assuming x is a dictionary where the key is a location and the value is a decision variable. I'm not sure why you used a list here. Some modification will be needed to match your structure.

import itertools

locations = ['Baja', 'Nepal', 'Spain', ...]
x = LpVariable.dicts('x', destinations, cat='Binary'

prob = LpProblem('Vacation', pulp.LpMinimize)

# non-duplicative cominations
destination_pairs = itertools.combinations(locations, 2)

# new decision variables
# i is destination1, j is destination2
y = {(i, j): LpVariable('y', cat='Binary') for i, j in destination_pairs}

# new constraints
# if x[i] or x[j] is 0, then y[(i,j)] has to be zero
# if y[(i, j)] is 1, then x[i] and x[j] both have to be one
for i, j in destination_pairs:
    prob += y[(i, j)] <= x[i]
    prob += y[(i, j)] <= x[j]
    prob += y[(i,j] >= x[i] + x[j] - 1

# this ensures that a combination is chosen
prob += lpSum(y.values()) >= 1

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM