Skip to content

Commit

Permalink
New version, with mps read/write support, and updated documentation.
Browse files Browse the repository at this point in the history
  • Loading branch information
chmduquesne committed Aug 22, 2012
1 parent 60bab5b commit 1c28a29
Show file tree
Hide file tree
Showing 9 changed files with 271 additions and 11 deletions.
3 changes: 3 additions & 0 deletions Changelog
Expand Up @@ -13,3 +13,6 @@ O.3.0:
0.3.1:
Corrected a minor bug in the setup script that prevented yaposib to be
compiled with fortmp support.

0.3.2:
Adding a mini mps solver named yaposib-solve
36 changes: 36 additions & 0 deletions docs/GettingStarted.rst
Expand Up @@ -133,6 +133,42 @@ features of yaposib:
for col in prob.cols:
print("%s=%s" % (col.name, col.solution))

It is also easy to write a generic command line solver in a few lines of
code. The following script is part of the yaposib distribution and is
shipped as the command line utility `yaposib-solve`

::

import yaposib
import sys

def main():
"""Extra simple command line mps solver"""

if len(sys.argv) <= 1:
print("Usage: yaposib-solve <file1.mps> [<file2.mps> ...]")
sys.exit(0)

solver = yaposib.available_solvers()[0]

for filename in sys.argv[1:]:

problem = yaposib.Problem(solver)

print("Will now solve %s" % filename)
err = problem.readMps(filename)
if not err:
problem.solve()
if problem.status == 'optimal':
print("Optimal value: %f" % problem.obj.value)
for var in problem.cols:
print("\t%s = %f" % (var.name, var.solution))
else:
print("No optimal solution could be found.")

if __name__ == "__main__":
main()

Other examples are available in the examples_ directory.

.. _examples: http://code.google.com/p/yaposib/source/browse/#git%2Fexamples
4 changes: 2 additions & 2 deletions docs/conf.py
Expand Up @@ -48,9 +48,9 @@
# built documents.
#
# The short X.Y version.
version = '0.3.1'
version = '0.3.2'
# The full version, including alpha/beta/rc tags.
release = '0.3.1'
release = '0.3.2'

# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
Expand Down
152 changes: 152 additions & 0 deletions examples/p0033.mps
@@ -0,0 +1,152 @@
*NAME: p0033
*ROWS: 16
*COLUMNS: 33
*INTEGER: 33
*NONZERO: 98
*BEST SOLN: 3089 (opt)
*LP SOLN: 2520.57
*SOURCE: Crowder-Johnson-Padberg test set
*
* E. Andrew Boyd (Rice University)
*APPLICATION: unknown
*COMMENTS: pure 0/1 IP
* 5 SOS constraints
*
NAME P0033
ROWS
N R100
L R114
L R115
L R116
L R117
L R118
L R119
L R120
L R121
L R122
L R123
L R124
L R125
L R126
L R127
L R128
L ZBESTROW
COLUMNS
MARK0000 'MARKER' 'INTORG'
C157 R100 171 R114 1
C157 R122 -300 R123 -300
C158 R100 171 R114 1
C158 R126 -300 R127 -300
C159 R100 171 R114 1
C159 R119 300 R120 -300
C159 R123 -300
C160 R100 171 R114 1
C160 R119 300 R120 -300
C160 R121 -300
C161 R100 163 R115 1
C161 R119 285 R120 -285
C161 R124 -285 R125 -285
C162 R100 162 R115 1
C162 R119 285 R120 -285
C162 R122 -285 R123 -285
C163 R100 163 R115 1
C163 R128 -285
C164 R100 69 R116 1
C164 R119 265 R120 -265
C164 R124 -265 R125 -265
C165 R100 69 R116 1
C165 R119 265 R120 -265
C165 R122 -265 R123 -265
C166 R100 183 R117 1
C166 R118 -230
C167 R100 183 R117 1
C167 R124 -230 R125 -230
C168 R100 183 R117 1
C168 R119 230 R120 -230
C168 R125 -230
C169 R100 183 R117 1
C169 R119 230 R120 -230
C169 R123 -230
C170 R100 49 R119 190
C170 R120 -190 R122 -190
C170 R123 -190
C171 R100 183 R117 1
C172 R100 258 R118 -200
C173 R100 517 R118 -400
C174 R100 250 R126 -200
C174 R127 -200
C175 R100 500 R126 -400
C175 R127 -400
C176 R100 250 R127 -200
C177 R100 500 R127 -400
C178 R100 159 R119 200
C178 R120 -200 R124 -200
C178 R125 -200
C179 R100 318 R119 400
C179 R120 -400 R124 -400
C179 R125 -400
C180 R100 159 R119 200
C180 R120 -200 R125 -200
C181 R100 318 R119 400
C181 R120 -400 R125 -400
C182 R100 159 R119 200
C182 R120 -200 R122 -200
C182 R123 -200
C183 R100 318 R119 400
C183 R120 -400 R122 -400
C183 R123 -400
C184 R100 159 R119 200
C184 R120 -200 R123 -200
C185 R100 318 R119 400
C185 R120 -400 R123 -400
C186 R100 114 R119 200
C186 R120 -200 R121 -200
C187 R100 228 R119 400
C187 R120 -400 R121 -400
C188 R100 159 R128 -200
C189 R100 318 R128 -400
MARK0001 'MARKER' 'INTEND'
RHS
RHS R114 1 R115 1
RHS R116 1 R117 1
RHS R118 -5 R119 2700
RHS R120 -2600 R121 -100
RHS R122 -900 R123 -1656
RHS R124 -335 R125 -1026
RHS R126 -5 R127 -500
RHS R128 -270
BOUNDS
UP ONE C157 1
UP ONE C158 1
UP ONE C159 1
UP ONE C160 1
UP ONE C161 1
UP ONE C162 1
UP ONE C163 1
UP ONE C164 1
UP ONE C165 1
UP ONE C166 1
UP ONE C167 1
UP ONE C168 1
UP ONE C169 1
UP ONE C170 1
UP ONE C171 1
UP ONE C172 1
UP ONE C173 1
UP ONE C174 1
UP ONE C175 1
UP ONE C176 1
UP ONE C177 1
UP ONE C178 1
UP ONE C179 1
UP ONE C180 1
UP ONE C181 1
UP ONE C182 1
UP ONE C183 1
UP ONE C184 1
UP ONE C185 1
UP ONE C186 1
UP ONE C187 1
UP ONE C188 1
UP ONE C189 1
ENDATA
30 changes: 30 additions & 0 deletions scripts/yaposib-solve
@@ -0,0 +1,30 @@
#!env python
import yaposib
import sys

def main():
"""Extra simple command line mps solver"""

if len(sys.argv) <= 1:
print("Usage: yaposib-solve <file1.mps> [<file2.mps> ...]")
sys.exit(0)

solver = yaposib.available_solvers()[0]

for filename in sys.argv[1:]:

problem = yaposib.Problem(solver)

print("Will now solve %s" % filename)
err = problem.readMps(filename)
if not err:
problem.solve()
if problem.status == 'optimal':
print("Optimal value: %f" % problem.obj.value)
for var in problem.cols:
print("\t%s = %f" % (var.name, var.solution))
else:
print("No optimal solution could be found.")

if __name__ == "__main__":
main()
5 changes: 3 additions & 2 deletions setup.py
Expand Up @@ -11,6 +11,7 @@
import sys

def pkgconfig(*packages, **kw):
"""Finds a package using pkg-config"""
flag_map = {'-I': 'include_dirs', '-L': 'library_dirs', '-l': 'libraries'}
for token in subprocess.check_output("pkg-config --libs --cflags %s" % ' '.join(packages), shell=True).split():
kw.setdefault(flag_map.get(token[:2]), []).append(token[2:])
Expand Down Expand Up @@ -77,7 +78,7 @@ def yaposib_extension():
)

setup(name="yaposib",
version="0.3.1",
version="0.3.2",
description= __doc__,
long_description = open("README").read(),
license = open("COPYING").read(),
Expand All @@ -95,5 +96,5 @@ def yaposib_extension():
packages = ['yaposib', 'yaposib.test'] ,
ext_modules = [ yaposib_extension() ],
package_data = { "" : [ "lib/*" ] },
scripts = [ "scripts/yaposib-config" ]
scripts = [ "scripts/yaposib-config", "scripts/yaposib-solve" ]
)
18 changes: 17 additions & 1 deletion yaposib/Binding.cpp
Expand Up @@ -55,12 +55,28 @@ BOOST_PYTHON_MODULE(_yaposib)
"- isDualObjectiveLimitReached\n"
"- isIterationLimitReached\n"
)
.def("readLp",
&Problem::readLp,
"Read the problem from an lp file. Return the error count"
)
.def("readMps",
&Problem::readMps,
"Read the problem from an mps file. Return the error count."
)
.def("writeLp",
&Problem::writeLp,
"Write the problem in a file (lp format). The argument is appended the extension '.lp'"
"Write the problem in a lp file. The argument is appended "
"the extension '.lp'"
)
.def("writeLp",
&Problem::writeDefaultLp)
.def("writeMps",
&Problem::writeMps,
"Write the problem in a mps file. The argument is appended "
"the extension '.mps'"
)
.def("writeLp",
&Problem::writeDefaultMps)
.add_property("maxNumIterations",
&Problem::getMaxNumIterations,
&Problem::setMaxNumIterations,
Expand Down
20 changes: 16 additions & 4 deletions yaposib/Problem.cpp
Expand Up @@ -459,7 +459,7 @@ void Problem::setObjCoef(int index, double value)
}

//-------------------------------------------------------------//
// _rows
// ROWS
//-------------------------------------------------------------//
Rows Problem::getRows()
{
Expand Down Expand Up @@ -816,8 +816,6 @@ Values Problem::getRowElements(int row)
res.push_back((vector.getElements())[i]);
}
return res;
//Values res(vector.getNumElements(), vector.getElements());
return res;
}

Indices Problem::getColIndices(int col)
Expand Down Expand Up @@ -849,11 +847,25 @@ Values Problem::getColElements(int col)
{
res.push_back((vector.getElements())[i]);
}
//Values res(vector.getNumElements(), vector.getElements());
return res;
}

int Problem::readLp(std::string filename)
{
return _solver->readLp(filename.data());
}

int Problem::readMps(std::string filename)
{
return _solver->readMps(filename.data());
}

void Problem::writeLp(std::string filename) const
{
_solver->writeLp(filename.data());
}

void Problem::writeMps(std::string filename) const
{
_solver->writeMps(filename.data());
}
14 changes: 12 additions & 2 deletions yaposib/Problem.hpp
Expand Up @@ -235,9 +235,19 @@ class Problem
// - isIterationLimitReached
std::string getSolverStatus() const;

// write the problem in a file (lp format)
// read the problem from an lp file
int readLp(std::string filename);

// read the problem from an mps file
int readMps(std::string filename);

// write the problem in a lp file
void writeLp(std::string filename) const;
void writeDefaultLp() const{this->writeLp("debug.lp");}
void writeDefaultLp() const{this->writeLp("debug");}

// write the problem in a mps file
void writeMps(std::string filename) const;
void writeDefaultMps() const{this->writeLp("debug");}

//-------------------------------------------------------------//
// TUNING
Expand Down

0 comments on commit 1c28a29

Please sign in to comment.