**PuLP in SolverStudio
**PuLP is a modelling environment for building linear and integer programmes within Python. SolverStudio can run PuLP both using the built-in IronPython (via the SolverStudio language “PuLP (IronPython)” — this is the recommended choice) or using your own external (i.e. manually installed outside SolverStudio) Python installation (via the SolverStudio language “Python (external)”. (Read more about external Python in SolverStudio.)

PuLP comes by default with SolverStudio – you do not need to install it.

**Using PuLP with IronPython**

Please see the example below, and the “PuLP Examples.xlsx” example spreadsheet, for samples that illustrate using PuLP. Please also see this SolverStudio IronPython page for more details of IronPython’s ability to access the spreadsheet using the standard Excel objects* Application*, *ActiveSheet* and *ActiveWorkbook*.

**Using PuLP with External Python
**If you run PuLP using Python (External), you need to start your file with:

*from SolverStudio import **

which (1) gives you read and write access to the SovlerStudio Data Items on the sheet, (2) gives you access to the standard Excel objects

*Application*,

*ActiveSheet*and

*ActiveWorkbook*, and (3) adds SolverStudio’s PuLP files the external Python’s path, allowing you to then say:

*from pulp import **

in the normal way. PuLP works with Python 2.7 and 3.x. Don’t forget that you need to install Python, but not PuLP. (When using SolverStudio, your external Python installation will use the PuLP included in SolverStudio.)

**PuLP Solvers under both IronPython and Python (external)
**PuLP supports a range of solvers. Of these, you can use the “_CMD” solvers under both the “PuLP (IronPython)” and “Python (external) languages, including CBC (i.e. COIN_CMD()), Gurobi (GUROBI_CMD()) and Cplex (CPLEX_CMD()). The other solvers, such as GUROBI(), are only available under “Python(external).”

The default PuLP solver is CBC, which is included with SolverStudio. You can solve using CBC with any of the following commands:

1 2 3 4 |
prob.solve() # Solve using PuLP's default Solver (usually CBC) prob.solve(COIN_CMD()) # Solve using CBC prob.solve(COIN_CMD(msg=1)) # Solve using CBC with logging prob.solve(COIN()) # COIN is an alias for COIN_CMD |

Other options for CBC include `COIN_CMD`

(*path=None*, *keepFiles=0*, *mip=1*, *msg=0*, *cuts=None*, *presolve=None*, *dual=None*, *strong=None*, *options=[]*, *fracGap=None*, *maxSeconds=None*, *threads=None*)

If you have installed the Gurobi or Cplex solver, PuLP can use it (under the “PuLP (IronPython)” language) using one of

1 2 3 |
prob.solve(GUROBI_CMD()) # Solve using Gurobi prob.solve(COIN_CMD(msg=1)) # Solve using CBC with logging prob.solve(CPLEX_CMD()) # Solve using Cplex |

The “PuLP Examples.xlsx” workbook (included in the SolverStudio download) has code on the “IronPython Solvers” sheet to list the available solvers.

**PuLP Solvers under Python (External)**

If you run PuLP using the “Python (External)” language (i.e. CPython), you can use any of the installed solvers. The “PuLP Examples.xlsx” workbook (included in the SolverStudio download) has code on the “Python (external) Solvers” sheet to list the available solvers.

**SolverStudio with Cut/Column Generation using DIPPY under Python (External)**

SolverStudio can work with Dippy, the ‘big brother’ of PuLP that allows column and cut generation. Be sure to run under the *Python (External)* language.

**Advanced SolverStudio Usage
**SolverStudio can work with Dippy, the ‘big brother’ of PuLP that allows column and cut generation. Dippy is a joint collaboration between Ted Ralphs and Michael O’Sullivan. Ted has some excellent SolverStudio examples using Dippy on his COIN-Fest 2015 page. Be sure to run under the

*Python (External)*language.

COIN Fest 2015: Workshop on Modeling and the COIN-OR Optimization Suite

**PuLP Resources
**To work with PuLP in SolverStudio, you need some understanding of Python.

The PuLP developer, Stu Mitchell, has some useful resources including:

PuLP on PyPi – the definitive site for installing PuLP

PuLP Package Documentation from PyPi – the definitive documentation

A comprehensive introduction to PuLP;

Tips for efficient Python modelling using PuLP;

Pulp a linear programming interpreter for Python;

PuLP: A Linear Programming Toolkit for Python (PDF paper);

An Introduction to PuLP for Python Programmers (PDF).

See also Pulp and GLPK.

The latest version of PuLP is available on PyPi.

If you have any PuLP questions, please direct them to the PuLP Google Forum.

**PuLP Example using IronPython
**

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
""" The Beer Distribution Problem for the PuLP Modeller Authors: Antony Phillips, Dr Stuart Mitchell 2007 SolverStudio version: Andrew Mason """ # Import PuLP modeller functions from pulp import * # Creates the 'prob' variable to contain the problem data prob = LpProblem("Beer Distribution Problem",LpMinimize) # Creates a list of tuples containing all the possible routes for transport Routes = [(w,b) for w in Warehouses for b in Bars] # A dictionary called 'Vars' is created to contain the referenced variables (the routes) vars = LpVariable.dicts("Route",(Warehouses,Bars),0,None,LpInteger) # The objective function is added to 'prob' first prob += lpSum([vars[w][b]*costs[w,b] for (w,b) in Routes]), "Sum_of_Transporting_Costs" # The supply maximum constraints are added to prob for each supply node (warehouse) for w in Warehouses: prob += lpSum([vars[w][b] for b in Bars])<=supply[w], "Sum_of_Products_out_of_Warehouse_%s"%w # The demand minimum constraints are added to prob for each demand node (bar) for b in Bars: prob += lpSum([vars[w][b] for w in Warehouses])>=demand[b], "Sum_of_Products_into_Bar%s"%b # The problem data is written to an .lp file prob.writeLP("BeerDistributionProblem.lp") # The problem is solved using PuLP's choice of Solver prob.solve(COIN_CMD(msg=1)) # The status of the solution is printed to the screen print "Status:", LpStatus[prob.status] # Each of the variables is printed with it's resolved optimum value for v in prob.variables(): print v.name, "=", v.varValue # The optimised objective function value is printed to the screen print "Total Cost of Transportation = ", value(prob.objective) # Copy values of decision variables into data item "flow" on the sheet for (w,b) in Routes: flow[w,b]=vars[w][b].varValue SolverResult = LpStatus[prob.status] |

Note: To run this under an external CPython, please add “from SolverStudio import *” before the “from pulp import *” line.

I am using PULP and a loop to repeatedly add cuts and resolve. I don’t go out of my way to reset/re-declare the variable array before resolving, so it has the previous solution in there when the solver is called again. Does that mean it uses this as an the starting solution or is there a special command you have to use during the call to solver that tells it to? Thanks

Linear Solvers like CBC and Gurobi do not normally use an existing solution as a starting point. If they are solving an integer programme, then an existing solution may be used to help the search if it is feasible, but I doubt that PuLP takes advantage of this. Hope this helps. Andrew

Hi Andrew,

is there a limit on variables in SolverStudio used with PuLP? My model is working correctly with around 28000 variables, but as soon as they are increased to around 42000, I immediately receive a KeyError pointing to my objective function.

There is no limit that SolverStudio imposes; I suggest you loop thru printing the values and their indices and see when it goes wrong. Andrew

Solve(CPLEX) returning infeasible solution as optimal

Anyone ever have any issues with external solvers like CPLEX returning an infeasible solution as “optimal” *sometimes* and other times returning the proper feasible solution? I have a PULP procedure that solves and generates a new constraint and resolves. About 75% of the time I run the program the CPLEX solver will ignore the new constraint and return a solution that violates it. The COIN_CMD solve always works fine and honours the new constraint.

I even generated the .lp and .mps files directly before solving step and visually inspected to verify that the new constraint did indeed make it to the problem – and yep, it is there, yet CPLEX returns a solution that blatantly violates the new constraint about 75% of the time (seemingly random).

I have not seen that before; most unusual. Does CBC show the same behaviour? Andrew

No, prob.solve() does not show the same behavior as prob.solve(CPLEX_CMD()). prob.solve() will *not* return an infeasible solution.

It would be unusual for CPLEX to have an error. However, errors do occur; my SolverStudio developer, Oscar Dowson, recently found a bug in Gurobi that silently changed models. If you can reproduce the error, and ideally do so without relying on PuLP, then I am sure that CPLEX would like to know about this. Andrew

Thank-you all for your work on Solver Studio, and for allowing me to use it.

In the included examples, “Common Formulations.xlsx” the Kanpsack-PuLP spreadsheet, the relevant equations to feed Solver Studio are given.

Considering an identical problem, what if one more limit [constraint?] is required? How would I write the code to limit the total number of unique items to 4 or 5?

I’m NOT stating I want the sum of the solution to equal 4 or 5, I’m saying I want the solution to be comprised of only 4 or 5 unique items from the Item list.

I appreciate you patience and help – afraid I’ve been retired a little too long and my background with visual basic for macros is of little use to me at this point.

You need a constraint saying the sum of the variables must be less than or equal to 5. Good luck. Andrew

Hi, also new to all of this (Solverstudio+python), have been using open solver so far, but got stuck due to too many variables (around 50,000…)

I tried learning from one of your examples the syntax, but I keep getting an error saying that instead of an expected index, a float was found

The problematic line of the code was:

prob += lpSum([vars2[p]* price[p] -vars[p]* price[p] for p in price]),”sum of revenue”

after defining vars and vars2 like this:

vars = LpVariable.dicts(“Route”,price,0,maxcharge,LpContinuous)

vars2 = LpVariable.dicts(“Route”,price,0,maxdischarge,LpContinuous)

price is a set of 50,000 real positive values (representing prices in a market), and the variables are charge and discharge rates of a battery, constrained by:

vars = LpVariable.dicts(“Route”,price,0,maxcharge,LpContinuous)

vars2 = LpVariable.dicts(“Route”,price,0,maxdischarge,LpContinuous)

#creates the upper and lower bounds for the variables

for a in vars:

vars[a].bounds(0, maxcharge)

vars2[a].bounds(0, maxdischarge)

Can you tell what the problem is with my code?

I don’t think you mean “price[p] for p in price]” as I assume “price” is indexed by integers, not by the actual prices. Andrew

HI,

I am new to solver studio and python programming language. I have a few questions to ask:

1. can one do multiple optimizations using a for loop in iron python. For example, in inventory management after solving for the first horizon and setting the decision variables for the first peeriod and moving on to the next horizon and doing the same and keep looping until end of all the periods.Kindly explain!

Yes. Most modelling languages will let you loop, and all programming languages have this as standard. Python and PuLP will do what you want, for example. Andrew

What’s the best strategy for handling “output” Data that has dynamic dimensions?

Here’s an example: I have “input” Data that defines tuple sets IE and SE, and then my PuLP(IronPython) model has a decision variable that’s defined for all combinations SEI=[(s,e,i) for (i,e) in IE for (s,e) in SE]. My model is able to read IE and SE, create the model, solve the model, but then crashes when writing the results. The issue is that I don’t know beforehand the combinations in SEI, and so the output Data in the Excel worksheet isn’t yet defined with all the keys. SolverStudio then often throws an error when trying to write new keys to the output Data that weren’t already in the Excel worksheet, and skips rows (without deleting the old contents) for rows defined in Excel worksheet that are in the current (s,e,i) key set.

What I have done to get around this is very manual. I expanded my PuLP(IronPython) to:

1. clear the old contents of the output Data in the Excel worksheet, including keys, using

Application.Worksheets(‘Opt_Production’).Range(‘Table_Opt_Production’).ClearContents()

2. write the desired keys to the Excel worksheet, using

row = 0

rg = Application.Worksheets(‘Opt_Production’).Range(‘Table_Opt_Production’)

for (s,e,i) in SEI:

row += 1

rg.Cells(row,1).Value = s

rg.Cells(row,2).Value = e

rg.Cells(row,3).Value = i

3. create and solve the PuLP model

4. assign values to the output Data, using

for (s,e,i) in SEI:

output_production[s,e,i] = x[site,e,i].varValue

# SolverStudio’s internal way of writing to Excel ranges is faster than using rg.Cells(row,4).Value

The downsides of this impementation are that

– a lot of lines need to be added to the PuLP(IronPython) script

– the script contains hard-coded references to specific names in the Excel file (easily broken)

– when new keys are added to SEI, it seems like you need to run the model twice for it to really display the correct solution. When you run it only once, all the keys are shown in the output Data in the Excel worksheet, but none of the values.

There has to be a simpler way to do this. Do you have any suggestions?

One idea: is there a SolverStudio function available in PuLP(IronPython) for “write Data now” or “update keys for Data now”?

It is a good idea and one on our list… it’s a long list! Andrew

One idea is to write VBA macros for “clear output tables” and “write keys for output tables”, and attached those macros to buttons for the user, but this wouldn’t cover the instance where I only want the optimized decision variable values displayed that are non-zero (i.e. the keys to be displayed are determined after the solution is obtained).

For those interested, this is the approach I ended up using. I defined my output tables in Excel as tables, so that they automatically resize when new rows are added. I defined data variable in SolverStudio for each output table, which will also expand if new rows are added to the tables, because of how SolverStudio handles references. I then wrote a VBA macro that clears the output tables, including values and keys, and writes the correct keys (thus resizing the table and the SolverStudio data variable references). The user runs the VBA macro with a button and then solves the SolverStudio model.

Alex: Would you be happy to share your workbook with us? I’d like to understand more about what you’ve done. Also, I have a long term plan to expand data item ranges automatically when the model is run (or the Data Items editor invoked) so that they include newly added rows/columns. I assume this is would meet your needs? Andrew

A quick answer before I rush out of the office; if the input indices change, then I assume the output indices should also change (and ideally be the same as the input indices?). If so, then could you index the output data over the ranges used for the input data? Then all output items will exists in thr output data item, perhaps as None/Nothing if they are blank. But, because they exist, they can be updated. Andrew

I think this only works if the index of the output data can be known and entered into the Excel worksheet before the SolverStudio model script is ran. Is there a way to edit the index of a SolverStudio Data variable within the model script, and have that updated in the worksheet too (indexes added/deleted in the model script -> rows added/deleted from the worksheet)?

Another option: is there a way to write a table of data with IronPython to a worksheet, in a way that is as quick as how SolverStudio read/writes Data variables? I find that for-looping over the indexes and writing each cell one at a time using

Application.Worksheets(‘Opt_Production’).Range(x).Value = y

is pretty slow

Accessing cells individually is slow. SolverStudio works hard to this fast. You can use arrays of variants to do the same whee you pass an entire array in one go. You can also have a big table indexed from 1, 2, … and write to the data and a nice ‘index’ for the user (but not SolverStudio). The new version of SolverStudio will make this a bit easier. Andrew

Thanks for the reply Andrew! Is there a faster method I could try within PuLP(IronPython) to write the data with the row/col headers, rather than one cell at a time? Also, when is that next version projected to be released? It sounds interesting.

See http://solverstudio.org/languages/ironpython/ for code that illustrates fast access. Hope this helps. Andrew

Hello,

I am trying to get PuLP/CBC to solve a quadratic problem. I will have X1*X2, etc in the objective function (Xi is binary). So I thought about creating a dummy variable X12 = X1*X2, where X1 + X2 < X12 + 1, I am minimizing so X12 will be 1 only if both X1 and X2 are 1, all variables being binary.

(Wonder if PuLP/CBC would let themselves be tricked… but I haven't gotten that far.)

I am having a PuLP/Python hurdle:

To create the X12 I think I need a list of lists, instead of tuples (this may be the key to my problem), so I am trying:

# this would be the list of Xi referenced above

Allocated = [(p,l) for (p,l) in allocations]

#this would be the list of Xij

Allocated_pair = []

for (p,l) in allocations:

for (p2,l2) in allocations:

Allocated_pair += [[Allocated[(p,l)],Allocated[(p2,l2)]] for (p,l) in allocations for (p2,l2) in allocations ]

but I get error "expected index value, got tuple" (google returns nothing for this error)

This is somewhat related (analogous) to the problem I had two years ago (above in this page).

Then after some time I figured a bit of the difference between tuples and lists (I assume a tuple cannot be an index and a list can) so removed the parenthesis from the last line and get this:

Allocated_pair += [[Allocated[p,l],Allocated[p2,l2]] for (p,l) in allocations for (p2,l2) in allocations ]

and the error message becomes "…takes exactly 1 argument (2 given)"

Hopefully my logic is not totally flawed and one comma in the right place will get me going.

Can anyone see an obvious/easy fix here?

Thank you

Well this got me going:

Allocated_pair += [[[p,l],[p2,l2]] for (p,l) in allocations for (p2,l2) in allocations ]

…now I am running out of memory.

But I found the PuLP Google forum, a better place for my type of questions.

Thank you

Pleased you got it going. Stu Mitchell said you were using Allocated, which is a list, as if it were a dictionary. Your memory error is not surprising as you are taking a cross product of 2 large sets. Hope you can get it to work. Andrew

Yes, thank you for checking that for me. The problem will be even bigger with the real data so I think I will find a non-linear option. I’ve used GAMS before so that will be my next try.

Thanks again and best regards

You can try a GAMS model via NEOS, or think about more efficient ways of modelling the problem. If you need a non-linear objective, you could try Pyomo. Julia/JuMP is also worth a look on account of its speed at building the model. Please let us know how you get on. Andrew. PS: What is the problem… why are you getting so many variables?

Yes! I was using GAMS with NEOS before I found OpenSolver and SolverStudio. I am trying to model and solve a warehouse slotting problem. Since the problem will be solved once (or once in a while) I think that NEOS will work well, timeliness not being an issue. And I look forward to having the communication with NEOS taken care of.

Thanks again.

Hi

I’m building a Network optimization tool using solverstudio and pulp. I’m building a constraint for supply in the network and have 3 types to model – fixed, min and max.

I’m wondering if there is a way to model of all these types of supply together in 1 equation where in the sign of the constraint is dependent on the supply type, i.e. “=” if it is fixed, “>=” if it is min and “<=" if it is max.

Otherwise I will have to break the data in to three sets and write three equations.

Thanks!

You will be adding these as separate equations in Pull so you could let the user enter a < , > or = on the sheet and then use this to add the right equation in Pulp. Andrew

Hi everyone!

Firstly I would like to thank you if you can help me ^^.

We are actually working on a LP problem for a student project at the univerity.

We have had a lot of errors but we still have one unsolved and honestly we don’t understand why…^^

The message error is:”Error execting model code: name’k’is not defined.

Traceback (most recent call last): File””, line…, in NameError: name ‘k’ is not defined

Our variables are declared like that:

Deltavars = LpVariable.dicts(“Delta”,(Produits,Jours),0,1,LpInteger)

And it is more or less the same declaration for our data (^^)

And our unsolved error is for this constraint:

# largeur de gamme

for t in Jours:

for s in SousFamille:

prob += lpSum([Deltavars[p][j]*Esp[p,k] for p in Produits if (t==j and s==k)]) >= LGmin[s]*lpSum([Esp[p,k] for p in Produits if (s==k)]), “largeur_de _gamme_%s_%s”%(t,s)

Thanks a lot!!

Cheers

You have no value(s) specified for the variable (i.e. index) ‘k’ which is needed to look up Esp[p,k]. You may need to loop over something like “for k in XX”. By the way, is this part of a course where you are taught SolverStudio, or did you find SolverStudio yourself? Andrew

Hi, me again 😉

thanks für the answer to me problem realy helped me out.

But now I have a different problem. I use this code to simulate a heat storage for my heating grid

var_WS_load_unload = LpVariable.dicts (“heat storage load or unload”,Zeit, -WS_unload_max,WS_load_max,LpContinuous)

WS_load = {}

WS_load_now = WS_load_at_start

for i in Time

WS_load[i] = WS_load_now + var_WS_load_unload[i]

WS_load_now = WS_load[i] * WS_loss

prob += WS_load[i] = WS_load_min

The Code just takes the actual load of the heating storage adds or subtracts the new amount of heat subtracts the losses and that is the load for the next time step

This works good if my model dosent have more then 2500 time steps.

If I go over that i geht the message “system out of memory exception” and the solving process stops.

Is there anything i can do or a other way to simulat that problem ?

Thanks in advace for your help

It looks like you have a big optimisation problem to solve. I would try a machine with more memory (and a 64 bit OS), or another modelling language, or shorter (or no) text descriptions in your model.

Hi yes it is a big problem going on a 64 bit os is ok but is it important that excel is a 64 bit version too or is it ok to have the 32 bit version running on a 64 bit os ?

Which modeling language would you suggest ?

Thanks for your help

PuLP will only get access to a a full 64-bit worth of memory if Excel is a 64 bit version. Alternative4ly, install your own 64 bit version of Python (from python.org), and change the Python (External) as your language (after adding “from SolverStudio import *” as shown in the examples). Hope this helps.

Hi amas008,

thanks for your help. I installed CPython and Pulp as 64 bit version on my computer solver studio is working with the external Python and starts creating the data file solverstudio.py and the model file model.py

but i get the error invalid syntax if I try to import the data file solverstudio.py with the line

“from SolverStudio import *”

This ist what the output shows me:

## Executing C:\Program Files (x86)\SolverStudio_00_06_03_00 20140829\SolverStudio\SolverStudio\CPython\RunCPython.py

## Building CPython input file, module ‘SolverStudio.py’, for 139 data items

## Writing data items

## Running CPython (c:\Python34\python.exe)

## with file: C:\Users\Patrick_Netbook\AppData\Local\Temp\SolverStudio gffhkjxz\model.py

Traceback (most recent call last):

File “C:\Users\Patrick_Netbook\AppData\Local\Temp\SolverStudio gffhkjxz\model.py”, line 28, in

from SolverStudio import *

File “C:\Users\Patrick_Netbook\AppData\Local\Temp\SolverStudio gffhkjxz\SolverStudio.py”, line 648

except Exception, ex:

^

SyntaxError: invalid syntax

## CPython did not complete; no solution is available.

## Done

did not finde any solution yet maybe you have a hint for me.

Thanks in advance

This appears to be a Python 3 issue; I have sent you a patch for testing, and will include this in the next release. Thanks for letting me know about this. Andrew

Hi I have a Problem with a constrain i am trying to add to my Problem.

prob = LpProblem (“Heating Costs”,LpMinimize)

var_plant1_th = LpVariable.dicts (“heating power plant1”,Time,0,32,LpContinuous)

var_plant2_th = LpVariable.dicts (“heating power plant2″,Time,5,90,LpContinuous)

prob += lpSum([var_plant1_th[i]*Costs_plant1 + var_plant2_th[i]*Costs_plant2 for i in Zeit]),”Total Costs for heating”

prob += [var_plant1_th[i]+ var_plant2_th[i] == demand_heating[i] for i in Zeit]), “Sum of power for each plant = demand of heating”

the last constrain allways givs me the error ” Need more then 1 value to unpack”

I tried so many things but could not finde any solution

I hope someone could help me

Stu Mitchel says:

You need an explicit loop to add the constraints

for i in Zeit:

prob += var_plant1_th[i]+ var_plant2_th[i] == demand_heating[i] for i in Zeit, “Sum of power for plant %s = demand of heating” % i

Hi,

I modeled an MIP with PuLP through SolverStudio and solved with cbc.

Because the model is hard to solve I use a time limit to stop optimization.

I want to see how good is my solution by checking the LowerBound but I don’t know how to get it.

So here my questions :

– What is the function to get back the LowerBound ? To get the objective the function to use is “prob.objective”, is there an equivalent function to get the lowerBound ?

– Is it possible to save the trace/log file after an optimization ? When I solve the MIP by calling the solver like this prob.solve(COIN_CMD(msg=1,maxSeconds=120)), I can see the log but at the end of the optimization the log is quiting and not saving.

Thank you for your help

I’m not sure how to do this (although it is a good thing to do). I suggest checking the PuLP documentation or contacting the PuLP maintainer Stu Mitchell. Sorry I cannot be of more help. Andrew

Hi,

I modeled an LP with COIN.

Because of the complexity of this model, i can’t get the optimal solution in a reasonnable amount of time.

As a result I use the MaxSeconds option when I call the solver : prob.solve(COIN_CMD(msg=1,maxSeconds=30))

At the end of the resolution I would like to get the best bound to be aware of the solution’s quality.

Unfortunately, I don’t know how to get this information. I can look at the trace but it’s not really convenient cause the window close really fast after optimisation.

So here my question :

– Is it possible to get the best bound with a function like we can get objective with the function prob.objective ?

– Is it possible to save the trace in a log file after an optimisation ?

Best regards

Hi this is Stuart Mitchell here maintainer of PuLP, Unfortunately Pulp does not record the bound gap when the problem is terminated early. You can however use the fracGap argument to the solver so that it terminates once the bound gap is small enough (i.e. fracGap = 0.1 terminates within 10% of the optimal solution)

Stu

Hi,

How can I choose which language to use. My problem is linear and has over Million Variables and Constraints. So I probably should stay away from the trials like CPLEX and GUROBI. but how do I choose if its better to code with PUPL or COOPR/PYOMO ? Which one is faster ? which one is easier to use? ,…

Thank you for your help

Pleased you got it going. Cheers, Andrew

I think both PuLP and Pyomo will struggle with your problem. PuLP is perhaps easier to learn as it avoids the idea of abstract models; I’d start with that on a scaled down test problem. Let me know how you get on. Andrew

Thank you Andrew. What if we decide to get the licence for CPLEX, GUROBI, or other not free ones. Would they be able to solve a problem with this size?

If anything can, Gubori or CPLEX (or other commercial solvers such as ExpressMP) are the ones to try. Andrew

Mario, what exactly is aux? Can you please give us the result of the print statements?

aux is the second variable I want to create (the first one is vars)

so

print aux[t][d]

gives

Auxiliar_tool1_day1

and

print vars[(i,j,k),d)]

gives

Variable_((‘material1′,_’tool1′,_qty1),_’day1’)

Not sure why vars has quotes and aux doesn’t or if that’s part of the problem.

Thank you

I am not sure if I have a SolverStudio or a PuLP problem. I am trying to create a second set of variables.

This is the code I have:

vars = LpVariable.dicts(“Variable”,Sched,0,1,LpInteger)

aux = LpVariable.dicts(“Auxiliar”,(tools,workdays),0,1,LpInteger)

Everything related to vars works. Sched, tools and workdays are being used in other portions of the code and are correctly defined (I think).

But this doesn’t work:

for d in workdays:

prob += 25 >= lpSum([aux[(t,d)] for t in tools])

The error points to the line above and says:

KeyError: (‘tool1’, ‘day1’)

where tool1 is the first t in tools and day1 is the first d in workdays.

If I replace (tools,workdays) above with a tuple (like I did when creating vars) it tells me the list is unhashable.

What am I doing wrong? This is probably very silly… Thanks

I’ve realized this lets me print the variables (I wasn’t able before):

for t in tools:

for d in workdays:

print aux[t][d]

but still this doesn’t work:

for d in workdays:

prob += 25 >= lpSum([aux[t][d] for t in tools])

the error is:

TypeError: expected index value, got str

I assume it is bad Python syntax but couldn’t find anything similar online.

Any hints?

Thank you

I fixed my problem:

#Create a second tuple

AuxVars = [((t),d) for (t) in tools for d in turndays]

#Created the variable with the tuple

aux = LpVariable.dicts(“Auxiliar”,AuxVars,0,1,LpInteger)

#Create the cosntraint

for d in turndays:

prob += 25 >= lpSum([aux[((t),d)] for t in tools]), “Tool repeat limits for %s” %d

I was also missing an index in the data items editor.

Thank you