[1153] | 1 | // -*- c++ -*- |
---|
| 2 | #include <iostream> |
---|
| 3 | #include <fstream> |
---|
| 4 | |
---|
| 5 | #include <lemon/time_measure.h> |
---|
[1241] | 6 | #include <lp_solver_glpk.h> |
---|
[1153] | 7 | |
---|
| 8 | using std::cout; |
---|
| 9 | using std::endl; |
---|
| 10 | using namespace lemon; |
---|
| 11 | |
---|
| 12 | /* |
---|
[1176] | 13 | On an 1537Mhz PC, the run times with |
---|
| 14 | glpk are the following. |
---|
| 15 | for n=3,4, some secondes |
---|
| 16 | for n=5, 25 hours |
---|
[1153] | 17 | */ |
---|
| 18 | |
---|
| 19 | int main(int, char **) { |
---|
[1243] | 20 | const int n=3; |
---|
[1153] | 21 | const double row_sum=(1.0+n*n)*n/2; |
---|
| 22 | Timer ts; |
---|
| 23 | ts.reset(); |
---|
[1241] | 24 | typedef LpGlpk LPSolver; |
---|
[1153] | 25 | typedef LPSolver::Col Col; |
---|
| 26 | LPSolver lp; |
---|
| 27 | typedef std::map<std::pair<int, int>, Col> Coords; |
---|
| 28 | Coords x; |
---|
| 29 | // we create a new variable for each entry |
---|
| 30 | // of the magic square |
---|
| 31 | for (int i=1; i<=n; ++i) { |
---|
| 32 | for (int j=1; j<=n; ++j) { |
---|
| 33 | Col col=lp.addCol(); |
---|
| 34 | x[std::make_pair(i,j)]=col; |
---|
| 35 | lp.setColLowerBound(col, 1.0); |
---|
| 36 | lp.setColUpperBound(col, double(n*n)); |
---|
| 37 | } |
---|
| 38 | } |
---|
| 39 | LPSolver::Expression expr3, expr4; |
---|
| 40 | for (int i=1; i<=n; ++i) { |
---|
| 41 | LPSolver::Expression expr1, expr2; |
---|
| 42 | for (int j=1; j<=n; ++j) { |
---|
| 43 | expr1+=x[std::make_pair(i, j)]; |
---|
| 44 | expr2+=x[std::make_pair(j, i)]; |
---|
| 45 | } |
---|
[1243] | 46 | |
---|
[1153] | 47 | // sum of rows and columns |
---|
| 48 | lp.addRow(expr1==row_sum); |
---|
| 49 | lp.addRow(expr2==row_sum); |
---|
[1243] | 50 | cout <<"Expr1: "<<expr1<<endl; |
---|
| 51 | cout <<"Expr2: "<<expr2<<endl; |
---|
| 52 | |
---|
[1153] | 53 | expr3+=x[std::make_pair(i, i)]; |
---|
| 54 | expr4+=x[std::make_pair(i, (n+1)-i)]; |
---|
| 55 | } |
---|
[1243] | 56 | cout <<"Expr3: "<<expr3<<endl; |
---|
| 57 | cout <<"Expr4: "<<expr4<<endl; |
---|
[1153] | 58 | // sum of the diagonal entries |
---|
| 59 | lp.addRow(expr3==row_sum); |
---|
| 60 | lp.addRow(expr4==row_sum); |
---|
| 61 | lp.solveSimplex(); |
---|
| 62 | cout << "elapsed time: " << ts << endl; |
---|
| 63 | for (int i=1; i<=n; ++i) { |
---|
| 64 | for (int j=1; j<=n; ++j) { |
---|
| 65 | cout << "x("<<i<<","<<j<<")="<<lp.getPrimal(x[std::make_pair(i,j)]) |
---|
| 66 | << endl; |
---|
| 67 | } |
---|
| 68 | } |
---|
[1243] | 69 | |
---|
| 70 | |
---|
| 71 | |
---|
| 72 | // // we make new binary variables for each pair of |
---|
| 73 | // // entries of the square to achieve that |
---|
| 74 | // // the values of different entries are different |
---|
| 75 | // lp.setMIP(); |
---|
| 76 | // for (Coords::const_iterator it=x.begin(); it!=x.end(); ++it) { |
---|
| 77 | // Coords::const_iterator jt=it; ++jt; |
---|
| 78 | // for(; jt!=x.end(); ++jt) { |
---|
| 79 | // Col col1=(*it).second; |
---|
| 80 | // Col col2=(*jt).second; |
---|
| 81 | // Col col=lp.addCol(); |
---|
| 82 | // lp.setColLowerBound(col, 0.0); |
---|
| 83 | // lp.setColUpperBound(col, 1.0); |
---|
| 84 | // lp.addRow(double(-n*n+1.0)<=1.0*col2-1.0*col1-double(n*n)*col<=-1.0); |
---|
| 85 | // lp.setColInt(col); |
---|
| 86 | // } |
---|
| 87 | // } |
---|
| 88 | // cout << "elapsed time: " << ts << endl; |
---|
| 89 | // lp.solveSimplex(); |
---|
| 90 | // // let's solve the integer problem |
---|
| 91 | // lp.solveBandB(); |
---|
| 92 | // cout << "elapsed time: " << ts << endl; |
---|
| 93 | // for (int i=1; i<=n; ++i) { |
---|
| 94 | // for (int j=1; j<=n; ++j) { |
---|
| 95 | // cout << "x("<<i<<","<<j<<")="<<lp.getMIPPrimal(x[std::make_pair(i,j)]) |
---|
| 96 | // << endl; |
---|
| 97 | // } |
---|
| 98 | // } |
---|
[1153] | 99 | } |
---|