How to use pyomo2nl to generate NL file

335 views
Skip to first unread message

mchehreg

unread,
Nov 7, 2013, 11:00:22 PM11/7/13
to coopr...@googlegroups.com
How can I use pyomo2nl  to generate a NL file from an instance in a script?

I defined variables and constraints of the model, then after creating the instance I want to export a nl file so that I can solve it using another solver which I don't have on my PC.
Is it possible to add a command in my script after the following line to generate a nl file of the instance?

instance = model.create()


Thank you
M

William Hart

unread,
Nov 8, 2013, 2:12:02 AM11/8/13
to coopr forum
Execute the following:

from coopr.opt import ProblemFormat
instance.write(filename, format=ProblemFormat.nl)

--Bill


--
You received this message because you are subscribed to the Google Groups "coopr forum" group.
To unsubscribe from this group and stop receiving emails from it, send an email to coopr-forum...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

mchehreg

unread,
Nov 8, 2013, 5:21:17 PM11/8/13
to coopr...@googlegroups.com
Thank you Bill.

It worked and created mytoy.nl, mytoy.col, and mytoy.row files.
I used mytoy.nl to solve the problem and got mytoy.sol results using 'wantsol = 1' option.

Now I'm wondering how should I load the results to the same instance to display the solution; something similar to instance.load(results)
The following didn't work:

instance.load('mytoy.sol')

I appreciate your help.
M

Gabriel Hackebeil

unread,
Nov 12, 2013, 3:33:51 PM11/12/13
to coopr...@googlegroups.com
This will be a little more complicated as Pyomo was designed to call the solver and collect the solution inside a single process. You are going to have to create an instance of the SOL file reader, e.g.,

from coopr.opt.reader.sol import ResultsReader_sol
# if on coopr trunk
# from coopr.opt.plugins.sol ResultsReader_sol

sol_reader = ResultsReader_sol()
results = sol_reader('mytol.sol')

Unfortunately this is only half of the story. You will not be able to load this results object via instance.load(results) because it lacks what we call a symbol map. Fortunately, you can create one using the 'mytol.row' and 'mytol.col' files. For instance, parsing the 'mytol.col' file, will give you a mapping from a symbol inside the results object you just created above to variable name in your instance. The 'mytoy.row' file works the same for constraints and the objective, where the last name in the file is for the objective. Rather than going into more detail, here is the rest of the code that you would need to generate these symbols and load the results:

# Parse row and col files
with open('mytoy.col') as f:
    varnames = [line.strip() for line in f.readlines()]
with open('mytoy.row') as f:
    connames = [line.strip() for line in f.readlines()]
objname = connames.pop()

# Create symbol map identical to that generated by
# the NL file interface
symbol_map = SymbolMap(instance)
symbol_list = []
for cntr, name in enumerate(varnames):
    symbol = 'v'+str(cntr)
    component = instance.find_component(name)
    symbol_list.append((component, symbol))
for cntr, name in enumerate(connames):
    symbol = 'c'+str(cntr)
    component = instance.find_component(name)
    symbol_list.append((component, symbol))
symbol = 'o'+str(cntr)
component = instance.find_component(objname)
symbol_list.append((component, symbol))

symbol_map.updateSymbols(symbol_list)

# Add symbol_map to results object and load results
results._symbol_map = symbol_map
instance.load(results)

This is clearly a hack for your use case, and will look much different if you decide to use a different solver interface (e.g., LP files), so don't expect this to work in all cases and note that it is subject to break at any point in the future if we update Pyomo.

Gabe

Gabriel Hackebeil

unread,
Nov 12, 2013, 3:37:41 PM11/12/13
to coopr...@googlegroups.com
You'll need to add the following import as well:

from coopr.pyomo.base import SymbolMap

Gabe

Federico Lozano Santamaria

unread,
Jul 1, 2015, 3:24:33 PM7/1/15
to pyomo...@googlegroups.com, coopr...@googlegroups.com, gabe...@gmail.com
Hello,

I have been trying to use the code posted by Gabe to create the symbol map. I just copied it and pasted it in my problem. However, when I use the function find_component it doesn't work when the indexes are float numbers. For example, I have a variable (x) indexed in a continuous set (0, 0.1, 0.2, ... 1) and for this variable the function find_component returns none for x[0.1], x[0.2] ... but it returns the pyomo object for x[0] and x[1]. 
Is it a bug in the code? Am I doing something wrong?
I am working with a concrete model and I checked the .col file and the name of the variables are 'x[0]', 'x[0.1]', 'x[0.2]' and so on.

Federico

Gabriel Hackebeil

unread,
Jul 1, 2015, 7:57:38 PM7/1/15
to Federico Lozano Santamaria, pyomo...@googlegroups.com
It’s an issue caused by the '.', which normally implies the component lives on a subblock of a model. The author of that code might have a quick fix for that, but it exposes a larger issue with this approach, which is that the names that appear in the .row and .col files are written to be human parsable. They are not in a format that is sufficient for recovering any general component on more complex nested models (with various index types).

Are you launching the solve on the other machine while the local process is still running? I ask because the call to model.write() returns the symbol map that was generated (if you on trunk or later, it’s a little different but we can deal with that later) You could use that instead of rebuilding one. If not, it might be easier to save the symbol_map that is returned. I can show you how to do this if necessary.

Gabe

Federico Lozano Santamaria

unread,
Jul 5, 2015, 4:51:19 PM7/5/15
to pyomo...@googlegroups.com, felo...@gmail.com
Hello Gabe,

I have the .sol file from a previous solutions and I load the results using ResultReader_sol, but I am also calling model.write() to create the nl file. I am using the latest release version and It will be very useful if you can show me how to use the symbol map created with model.write().

Thank you

Federico

Gabriel Hackebeil

unread,
Jul 6, 2015, 5:28:10 AM7/6/15
to pyomo...@googlegroups.com, felo...@gmail.com
You would use it the same way you use the symbol_map that you were building manually. E.g.,

results._symbol_map = symbol_map
instance.load(results)

(Note that there will be some slight changes to these two lines in the upcoming Pyomo release but this will still work in your current release).

Do you obtain the sol file while the process that called .write() is still running? If so then there is nothing else to worry about since you have the original symbol map in memory. If not, then I’m assuming what you do is recreate the instance and load the solution into that. In this case, the easiest thing to do would be to call the write() method on this new instance to obtain a new symbol map (and just throw away the NL file that gets generated).

One issue to be aware of is that it is possible to generate models in such a way that the symbol_map can be different from run to run. This would be true, for instance, if the order in which you declared components on a model depended on the iteration order of a Python dict. To be sure the symbol_map you regenerated matches the original, you might want to compare the order of the original .row and .col files to the new ones to verify that they are the same. Additionally, setting the I/O option ‘file_determinism’ to 3 should be sufficient to always ensure matching NL files (and thus symbol_maps). This would look like

model.write(…, io_options={’symbolic_solver_labels’: True, ‘file_determinism’: 3})

The default setting for file_determinism is usually sufficient, but you still might want to verify the matching row and col files.

Gabe

-- 
You received this message because you are subscribed to the Google Groups "Pyomo Forum" group.
To unsubscribe from this group and stop receiving emails from it, send an email to pyomo-forum...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply all
Reply to author
Forward
0 new messages