Skip to main content
added 1522 characters in body
Source Link
RobPratt
  • 14.3k
  • 1
  • 31
  • 59

By request, here's the SAS code I used:

proc optmodel;
   /* declare parameters */
   num n = 4;
   set ROWS = 1..n;
   set COLS = ROWS;
   set CELLS = ROWS cross COLS;
   set NEIGHBORHOOD {<i,j> in CELLS} = {<i2,j2> in CELLS: abs(i-i2) + abs(j-j2) <= 1};

   /* construct primes */
   num maxprime = 200;
   set COMPOSITES = union {i in 3..sqrt(maxprime) by 2} i*i..maxprime by 2*i;
   set PRIMES = {2} union (3..maxprime by 2 diff COMPOSITES);
   put PRIMES=;

   /* declare decision variables */
   var NumMoves {CELLS} >= 0 integer;
   var IsCellPrime {CELLS, PRIMES} binary;

   /* declare objective */
   min TotalNumMoves = sum {<i,j> in CELLS} NumMoves[i,j];

   /* declare constraints */
   con OnePrimePerCell {<i,j> in CELLS}:
      sum {p in PRIMES} IsCellPrime[i,j,p] = 1;
   con AtMostOneCellPerPrime {p in PRIMES}:
      sum {<i,j> in CELLS} IsCellPrime[i,j,p] <= 1;
   con Link {<i,j> in CELLS}:
      sum {<i2,j2> in NEIGHBORHOOD[i,j]} NumMoves[i2,j2] 
    = sum {p in PRIMES} p * IsCellPrime[i,j,p];

   /* call MILP solver */
   solve;

   /* print solution */
   print NumMoves;
   num sol {CELLS};
   for {<i,j> in CELLS} do;
      for {p in PRIMES: IsCellPrime[i,j,p].sol > 0.5} do;
         sol[i,j] = p;
         leave;
      end;
   end;
   print sol;
quit;

By request, here's the SAS code I used:

proc optmodel;
   /* declare parameters */
   num n = 4;
   set ROWS = 1..n;
   set COLS = ROWS;
   set CELLS = ROWS cross COLS;
   set NEIGHBORHOOD {<i,j> in CELLS} = {<i2,j2> in CELLS: abs(i-i2) + abs(j-j2) <= 1};

   /* construct primes */
   num maxprime = 200;
   set COMPOSITES = union {i in 3..sqrt(maxprime) by 2} i*i..maxprime by 2*i;
   set PRIMES = {2} union (3..maxprime by 2 diff COMPOSITES);
   put PRIMES=;

   /* declare decision variables */
   var NumMoves {CELLS} >= 0 integer;
   var IsCellPrime {CELLS, PRIMES} binary;

   /* declare objective */
   min TotalNumMoves = sum {<i,j> in CELLS} NumMoves[i,j];

   /* declare constraints */
   con OnePrimePerCell {<i,j> in CELLS}:
      sum {p in PRIMES} IsCellPrime[i,j,p] = 1;
   con AtMostOneCellPerPrime {p in PRIMES}:
      sum {<i,j> in CELLS} IsCellPrime[i,j,p] <= 1;
   con Link {<i,j> in CELLS}:
      sum {<i2,j2> in NEIGHBORHOOD[i,j]} NumMoves[i2,j2] 
    = sum {p in PRIMES} p * IsCellPrime[i,j,p];

   /* call MILP solver */
   solve;

   /* print solution */
   print NumMoves;
   num sol {CELLS};
   for {<i,j> in CELLS} do;
      for {p in PRIMES: IsCellPrime[i,j,p].sol > 0.5} do;
         sol[i,j] = p;
         leave;
      end;
   end;
   print sol;
quit;
deleted 7 characters in body
Source Link
RobPratt
  • 14.3k
  • 1
  • 31
  • 59

Via integer linear programming, the minimum number of moves turns out to be:

6798

    Moves         Result
     42  28  39  84   11 2923 4143 3713
    1 3 4 222 15 110   13 317 37 59 5331
     0  2 24 0 165    7 233 47 43
53 29
    0  017 1 0  0    217 19 341 19 175

This same solution minimizes the largest prime.

Via integer linear programming, the minimum number of moves turns out to be:

67

    Moves         Result
     4  2  3  8   11 29 41 37
     3  2 15 11   13 31 59 53
     0  2  0 16    7 23 47 43
     0  0 1   0    2  3 19 17

This same solution minimizes the largest prime.

Via integer linear programming, the minimum number of moves turns out to be:

98

    Moves        Result
    2  8  9  4   11 23 43 13
    1  4 22  0    7 37 59 31
    0  2 24  5    3 47 53 29
    0 17  0  0   17 19 41  5

This same solution minimizes the largest prime.

Source Link
RobPratt
  • 14.3k
  • 1
  • 31
  • 59

Via integer linear programming, the minimum number of moves turns out to be:

67

    Moves         Result
     4  2  3  8   11 29 41 37
     3  2 15 11   13 31 59 53
     0  2  0 16    7 23 47 43
     0  0 1   0    2  3 19 17

This same solution minimizes the largest prime.