marci@1153: // -*- c++ -*- marci@1153: #include marci@1153: #include marci@1153: marci@1153: #include marci@1153: #include marci@1153: marci@1153: using std::cout; marci@1153: using std::endl; marci@1153: using namespace lemon; marci@1153: marci@1153: /* marci@1176: On an 1537Mhz PC, the run times with marci@1176: glpk are the following. marci@1176: for n=3,4, some secondes marci@1176: for n=5, 25 hours marci@1153: */ marci@1153: marci@1153: int main(int, char **) { marci@1153: const int n=4; marci@1153: const double row_sum=(1.0+n*n)*n/2; marci@1153: Timer ts; marci@1153: ts.reset(); marci@1153: typedef LPGLPK LPSolver; marci@1153: typedef LPSolver::Col Col; marci@1153: LPSolver lp; marci@1153: typedef std::map, Col> Coords; marci@1153: Coords x; marci@1153: // we create a new variable for each entry marci@1153: // of the magic square marci@1153: for (int i=1; i<=n; ++i) { marci@1153: for (int j=1; j<=n; ++j) { marci@1153: Col col=lp.addCol(); marci@1153: x[std::make_pair(i,j)]=col; marci@1153: lp.setColLowerBound(col, 1.0); marci@1153: lp.setColUpperBound(col, double(n*n)); marci@1153: } marci@1153: } marci@1153: LPSolver::Expression expr3, expr4; marci@1153: for (int i=1; i<=n; ++i) { marci@1153: LPSolver::Expression expr1, expr2; marci@1153: for (int j=1; j<=n; ++j) { marci@1153: expr1+=x[std::make_pair(i, j)]; marci@1153: expr2+=x[std::make_pair(j, i)]; marci@1153: } marci@1153: // sum of rows and columns marci@1153: lp.addRow(expr1==row_sum); marci@1153: lp.addRow(expr2==row_sum); marci@1153: expr3+=x[std::make_pair(i, i)]; marci@1153: expr4+=x[std::make_pair(i, (n+1)-i)]; marci@1153: } marci@1153: // sum of the diagonal entries marci@1153: lp.addRow(expr3==row_sum); marci@1153: lp.addRow(expr4==row_sum); marci@1153: lp.solveSimplex(); marci@1153: cout << "elapsed time: " << ts << endl; marci@1153: for (int i=1; i<=n; ++i) { marci@1153: for (int j=1; j<=n; ++j) { marci@1153: cout << "x("<