# HG changeset patch # User marci # Date 1108653253 0 # Node ID 4b0468de3a31df3bb344ce57f53348f67888ceb6 # Parent 1765ff9fefa1d1f4b15db090943f3a5a222caf57 if you have a nuclear power plant and wanna compute small magic squares, then let's do it diff -r 1765ff9fefa1 -r 4b0468de3a31 src/work/marci/lp/lp_solver_base.h --- a/src/work/marci/lp/lp_solver_base.h Wed Feb 16 21:40:16 2005 +0000 +++ b/src/work/marci/lp/lp_solver_base.h Thu Feb 17 15:14:13 2005 +0000 @@ -619,6 +619,8 @@ virtual void _setColCont(int i) = 0; /// \e virtual void _setColInt(int i) = 0; + /// \e + virtual _Value _getMIPPrimal(int i) = 0; public: /// \e void setColCont(Col col) { @@ -628,6 +630,10 @@ void setColInt(Col col) { _setColInt(col_iter_map[col]); } + /// \e + _Value getMIPPrimal(Col col) { + return _getMIPPrimal(col_iter_map[col]); + } //@} }; @@ -1096,9 +1102,11 @@ void setMIP() { lpx_set_class(lp, LPX_MIP); } protected: /// \e - void _setColCont(int i) {lpx_set_col_kind(lp, i, LPX_CV); } + void _setColCont(int i) { lpx_set_col_kind(lp, i, LPX_CV); } /// \e - void _setColInt(int i) {lpx_set_col_kind(lp, i, LPX_IV); } + void _setColInt(int i) { lpx_set_col_kind(lp, i, LPX_IV); } + /// \e + double _getMIPPrimal(int i) { return lpx_mip_col_val(lp, i); } }; /// @} diff -r 1765ff9fefa1 -r 4b0468de3a31 src/work/marci/lp/magic_square.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/work/marci/lp/magic_square.cc Thu Feb 17 15:14:13 2005 +0000 @@ -0,0 +1,88 @@ +// -*- c++ -*- +#include +#include + +#include +#include + +using std::cout; +using std::endl; +using namespace lemon; + +/* + for n=3,4 , the program is very fast + for n=5, with glpk, the run takes hours + */ + +int main(int, char **) { + const int n=4; + const double row_sum=(1.0+n*n)*n/2; + Timer ts; + ts.reset(); + typedef LPGLPK LPSolver; + typedef LPSolver::Col Col; + LPSolver lp; + typedef std::map, Col> Coords; + Coords x; + // we create a new variable for each entry + // of the magic square + for (int i=1; i<=n; ++i) { + for (int j=1; j<=n; ++j) { + Col col=lp.addCol(); + x[std::make_pair(i,j)]=col; + lp.setColLowerBound(col, 1.0); + lp.setColUpperBound(col, double(n*n)); + } + } + LPSolver::Expression expr3, expr4; + for (int i=1; i<=n; ++i) { + LPSolver::Expression expr1, expr2; + for (int j=1; j<=n; ++j) { + expr1+=x[std::make_pair(i, j)]; + expr2+=x[std::make_pair(j, i)]; + } + // sum of rows and columns + lp.addRow(expr1==row_sum); + lp.addRow(expr2==row_sum); + expr3+=x[std::make_pair(i, i)]; + expr4+=x[std::make_pair(i, (n+1)-i)]; + } + // sum of the diagonal entries + lp.addRow(expr3==row_sum); + lp.addRow(expr4==row_sum); + lp.solveSimplex(); + cout << "elapsed time: " << ts << endl; + for (int i=1; i<=n; ++i) { + for (int j=1; j<=n; ++j) { + cout << "x("<