-
Notifications
You must be signed in to change notification settings - Fork 18
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add GLPK solver reading #187
Conversation
Also, I have no idea what is up with this typing issue! Does anyone have any thoughts, else I will look at it again next week :) |
Hi @trevorb1. The typing issue is raised by the static type checker mypy. You can use it as part of the pre-commit configuration bundled in the otoole package (perhaps you already are). The typing error raised is src/otoole/results/results.py:453: error: Incompatible types in assignment (expression has type "float", target has type "str")
src/otoole/results/results.py:461: error: Incompatible return value type (got "Tuple[Dict[str, str], Any]", expected "Tuple[Dict[str, Union[str, float]], Any]") Fix by adding a type hint inline to line 433 of src/otoole/results/results.py status: Dict[str, Union[str, float]] = {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @trevorb1. Nice work. It would be handy to access the GLPK solution, using otoole, although it's probably of limited overall utility given that glpsol is only used for relatively small models. Still it's a useful exercise.
I think the current implementation is okay. Performance-wise, looping over the lines of the text file is not so efficient. It's worth using pandas' read_csv function as it's much faster than parsing each line in a loop. It is also worth looking at the CBC reading of linopy for inspiration.
Thanks so much for the feedback, @willu47! I guess I always thought directly reading in a text/csv file was more efficient then using pandas (since it uses built in datatypes) at the expense of being less useful to work with the data. So it is good to know I updated the I landed on reading everything in all at once, then parsing out the header information from the solution information via slicing and splitting the strings. Alternatively, we could read in the csv in parts (similar to shown below) to have def read_solution(self, file_path: Union[str, TextIO]) -> Tuple[Dict[str, Union[str, float]], pd.DataFrame]:
# get status information
df_status = pd.read_csv(file_path, header=None, nrows=7, sep=":", index_col=0)
status["name"] = df_status.loc["c Problem", 1].strip()
status["status"] = df_status.loc["c Status", 1].strip()
status["objective"] = float(df_status.loc["c Objective", 1].split()[2])
file_path.seek(0) # would need to type check this
# get solution infromation
df = pd.read_csv(
file_path,
header=None,
skiprows=[x for x in range(0, 8)],
sep=r"\s+",
names=["ID", "NUM", "STATUS", "PRIM", "DUAL"],
)
return status, df I also slightly changed the logic of Please let me know if you have any other thoughts! Else I think we should be good to merge :) |
Regarding renaming of classes, how about changing |
Hi @willu47, thanks for the pointers! All functionality to close this issue has been implemented, including the integration of reading GLPK with the Python API update. So I am going to go ahead and merge this. Possibly a new issue will be how the If you think refactoring how this works is needed, please just let me know or create a new issue and assign me to it. Thanks! Lines 146 to 180 in 5a194de
|
Description
In this PR I add a the class
ReadGlpk(...)
which allows a user to process GLPK solution files. Associated unit tests have also been added. This PR addresses one of the comments in the JOSS review about being able to use only a single solver with otoole.Issue Ticket Number
Closes #19
Documentation
A sample use case has been added to the examples page on the documentation site. Notably, the user must use the
--wglp
and--write
flags when creating the*.lp
and solution filesThen when processing the solution file with otoole, the user must also pass in the new optional flag
--glpk_model
added to otoole.As elaborated in issue #19, and the GLPK wiki, while GLPK can write out a human readable format file (using the
--output
flag), it is suggested to use the--wglp
and--write
flags for machine readable files. Both these files are needed to extract out all solution values.Questions
--glpk_model
flag to otoole make sense? I couldn't really come up with a better way to do this. I don't know if this is making it too confusing though?ReadGlpk()
class inherits from theReadResultsCBC()
to use its functionality to convert between wide and long formatted dataframes. This means that nowReadCbc()
,ReadGurobi()
, andReadGlpk()
all inherit from theReadResultsCBC()
class. The nameReadResultsCBC()
may be a little outdated now. Should we change it to something more general likeConvertReadResults()
or something like that, since its main function is to convert wide data to long data?