Skip to content

Commit

Permalink
fixed bug that left out many prefix move sequences
Browse files Browse the repository at this point in the history
The previous code restricted every move sequence to have exactly P moves instead of at most P moves, and also could unintentionally prevent certain moves from being used altogether.

stdout:
6x6
[000011, 000011, 000001],[000011, 000001, 000001]
threshold=28, P=6
#mvseqs=56724
 -1 -1 -1 -1  0  1
 -1 -1 -1 -1  2  3
 -1 -1 -1 -1  4  5
 -1 -1 -1 -1  6  7
  8  9 10 11 12 13
 14 15 16 17 18 19
[0, 2, 4, 6]
ncombos=116280
0:1
1:2
2:6
3:25
4:82
5:254
6:800
7:2356
8:6498
9:15370
10:27218
11:32295
12:22767
13:7720
14:871
15:15
#reached=116280
D=16
total time=311
 -1 -1 -1 -1 -1  0
 -1 -1 -1 -1 -1  1
 -1 -1 -1 -1 -1  2
 -1 -1 -1 -1 -1  3
  4  5  6  7  8  9
 10 11 12 13 14 15
[4, 5, 6, 7, 8]
ncombos=524160
0:1
1:2
2:6
3:21
4:58
5:156
6:441
7:1165
8:2945
9:7508
10:17927
11:38631
12:72472
13:108595
14:123522
15:99620
16:43574
17:7258
18:256
19:2
#reached=524160
D=20
total time=792
solvedscrm=[4, 10, 16, 22, 24, 25, 26, 27, 28]
subarrstart=[0, 4, 9]
total combos to reduce=709300008
[15, 14]: ncombos=1852830
  elapsed ms     #combos
        5000      948307
        9308     1852830
[14, 15]: ncombos=86769020
  elapsed ms     #combos
        5000     1247495
       13591     3316346
       20566     4861066
       28261     6361028
       36945     8548137
       46782    10950051
       57912    13533313
       70470    16464293
       84594    19811381
      100427    23524535
      118121    27746276
      137835    31920083
      159738    36937283
      184009    42344865
      210839    47959355
      240428    54706781
      272990    61423532
      308755    69212957
      347956    76389176
      390855    85486500
      396939    86769020
[15, 15]: ncombos=1494300
  elapsed ms     #combos
        5000      966044
        7876     1494300
[13, 16]: ncombos=336391280
  elapsed ms     #combos
        5000     1250675
       13591     3421150
       20566     5252796
       28261     6992352
       36945     8956406
       46782    11267976
       57912    13989996
       70470    17111957
       84594    20453767
      100427    24259965
      118121    28578417
      137835    33497995
      159738    39211182
      184009    45437529
      210839    51878522
      240428    58534930
      272990    65852438
      308753    74163730
      347956    82510968
      390855    92355259
      437717   104163338
      488829   116862946
      544492   130707119
      605024   145312907
      670764   161781640
      742065   179699166
      819305   198139044
      902880   217743526
      993208   238363051
     1090730   253601901
     1195910   279331304
     1309240   305064644
     1431233   328466248
     1468071   336391280
[14, 16]: ncombos=37952954
  elapsed ms     #combos
        5000      965943
       13591     2750011
       20566     4210314
       28261     5853662
       36945     7611932
       46782     9566138
       57912    11800698
       70470    14224843
       84594    16908632
      100427    20115141
      118121    23314117
      137835    26449857
      159738    29643911
      184009    33361787
      209699    37952954
[15, 16]: ncombos=653610
  elapsed ms     #combos
        3758      653610
[12, 17]: ncombos=165242886
  elapsed ms     #combos
        5000     1224028
       13591     3508586
       20566     5337838
       28261     7332337
       36945     9516511
       46782    12089078
       57912    15025430
       70470    18338505
       84594    21960951
      100427    26050482
      118121    30099276
      137835    34649809
      159738    38737235
      184009    44084267
      210839    50490565
      240428    58085204
      272990    65910252
      308753    74067594
      347956    81117694
      390855    91647724
      437717   103480480
      488829   115752070
      544492   129106052
      605024   143216085
      670764   159540761
      697385   165242886
[13, 17]: ncombos=56031760
  elapsed ms     #combos
        5000     1195790
       13591     3180562
       20566     4841125
       28261     6650259
       36945     8617718
       46782    10803879
       57912    13178048
       70470    15734420
       84594    18870463
      100427    22354262
      118121    26101555
      137835    30335229
      159738    35191260
      184009    40050102
      210839    45457113
      240428    51831547
      261171    56031760
[14, 17]: ncombos=6321718
  elapsed ms     #combos
        5000      999736
       13591     2556608
       20566     3769039
       28261     5037837
       35903     6321718
[15, 17]: ncombos=108870
  elapsed ms     #combos
         723      108870
[11, 18]: ncombos=8267520
  elapsed ms     #combos
        5000     1246574
       13591     3298761
       20566     4969956
       28261     6804268
       34468     8267520
[12, 18]: ncombos=5828352
  elapsed ms     #combos
        5000     1181262
       13591     3097513
       20566     4623208
       26329     5828352
[13, 18]: ncombos=1976320
  elapsed ms     #combos
        5000      961509
       11057     1976320
[14, 18]: ncombos=222976
  elapsed ms     #combos
        1560      222976
[15, 18]: ncombos=3840
  elapsed ms     #combos
          29        3840
[10, 19]: ncombos=54436
  elapsed ms     #combos
         289       54436
[11, 19]: ncombos=64590
  elapsed ms     #combos
         295       64590
[12, 19]: ncombos=45534
  elapsed ms     #combos
         258       45534
[13, 19]: ncombos=15440
  elapsed ms     #combos
         111       15440
[14, 19]: ncombos=1742
  elapsed ms     #combos
          20        1742
[15, 19]: ncombos=30
  elapsed ms     #combos
           1          30
time=3167242

Process finished with exit code 0
  • Loading branch information
coolcomputery committed Jun 28, 2021
1 parent 3ca54f8 commit 64b6b4c
Showing 1 changed file with 64 additions and 74 deletions.
138 changes: 64 additions & 74 deletions LoopoverBFSImprove.java
Expand Up @@ -11,19 +11,32 @@ public class LoopoverBFSImprove {
private static int mod(int n, int k) {
return (n%k+k)%k;
}
private static int[] inv(int[] P) {
//return inverse permutation of P
int[] I=new int[P.length];
for (int i=0; i<P.length; i++)
I[P[i]]=i;
return I;
}
private static int[] prodperm(int[] A, int[] B) {
//B is a permutation array
//return [ B[A[i]] for all i]
int[] out=new int[A.length];
for (int i=0; i<A.length; i++)
out[i]=B[A[i]];
return out;
}
private static String boardStr(int[] solvedscrm, int[] scrm, int R, int C) {
int[] display=new int[R*C]; Arrays.fill(display,-1);
for (int i=0; i<scrm.length; i++)
display[scrm[i]]=solvedscrm[i];
StringBuilder out=new StringBuilder();
String form="%"+(R*C<=26?1:3)+"s";
for (int r=0; r<R; r++) {
for (int c=0; c<C; c++)
out.append(String.format(form,display[r*C+c]==-1?".":(R*C<=26?""+(char)('A'+display[r*C+c]):(display[r*C+c]+1))));
out.append('\n');
}
return out.toString();
}
private static int[] scrambleAction(int R, int C, int[] mvseq, int[][] mvactions) {
int[] out=new int[R*C]; for (int i=0; i<R*C; i++) out[i]=i;
for (int mvi:mvseq) out=prodperm(out,mvactions[mvi]);
return out;
}
private static void improve(int R, int C, String[] Rfrees, String[] Cfrees, int threshold, int P, boolean[] allActions) {
System.out.println(R+"x"+C+"\n"+Arrays.toString(Rfrees)+","+Arrays.toString(Cfrees)+"\nthreshold="+threshold+", P="+P);
int M=0;
Expand Down Expand Up @@ -53,34 +66,31 @@ private static void improve(int R, int C, String[] Rfrees, String[] Cfrees, int
}
}
int[][] mvreduc=LoopoverBFS.mvreduc(mvs);
boolean[][] mvreducmat=new boolean[M][M];
for (int m=0; m<M; m++) for (int m2:mvreduc[m]) mvreducmat[m][m2]=true;
List<int[]> mvseqs=new ArrayList<>();
//generate all possible (non-redundant) sequences of moves of length <=P
for (int len=1; len<=P; len++) {
int[] seq=new int[P];
while (seq[P-1]<M) {
boolean good=true;
for (int p=0; p<P-1&&good; p++)
if (!mvreducmat[seq[p]][seq[p+1]])
good=false;
if (good)
mvseqs.add(seq.clone());
seq[0]++;
for (int p=0; p<P-1&&seq[p]==P; p++) {
seq[p]=0;
seq[p+1]++;
//BFS over all nonredundant move sequences of length <=P
List<int[]> mvseqs=new ArrayList<>(); List<int[]> mvseqactions=new ArrayList<>(); {
List<int[]> mvseqfront=new ArrayList<>();
mvseqfront.add(new int[] {});
Set<String> seen=new HashSet<>();
seen.add(Arrays.toString(scrambleAction(R,C,mvseqfront.get(0),mvactions)));
for (int D=0; D<P; D++) {
List<int[]> nmvseqfront=new ArrayList<>();
for (int[] mseq:mvseqfront)
for (int mi:mvreduc[mseq.length==0?M:mseq[D-1]]) {
int[] nmseq=new int[D+1];
System.arraycopy(mseq,0,nmseq,0,D);
nmseq[D]=mi;
int[] action=scrambleAction(R,C,nmseq,mvactions);
String code=Arrays.toString(action);
if (!seen.contains(code)) {
seen.add(code);
nmvseqfront.add(nmseq);
mvseqs.add(nmseq);
mvseqactions.add(action);
}
}
mvseqfront=nmvseqfront;
}
}
List<int[]> mvseqactions=new ArrayList<>();
for (int[] seq:mvseqs) {
int[] ret=new int[R*C];
for (int i=0; i<R*C; i++) ret[i]=i;
for (int p=0; p<P; p++)
ret=prodperm(ret,mvactions[seq[p]]);
mvseqactions.add(ret);
}
System.out.println("#mvseqs="+mvseqs.size());

//create BFS trees
Expand All @@ -91,24 +101,6 @@ private static void improve(int R, int C, String[] Rfrees, String[] Cfrees, int
for (int t=0; t<T-1; t++)
if (allActions[t])
trees[t].computeAllActions();
//binnedCodes[t][d] contains the codes of all scrambles for tree t at depth d
int[][][] binnedCodes=new int[T][][];
for (int t=0; t<T; t++) {
int D=trees[t].D, ncombos=trees[t].ncombos;
int[] freqs=new int[D];
for (int c=0; c<ncombos; c++) {
int d=trees[t].depth(c);
if (d!=-1) freqs[d]++;
}
binnedCodes[t]=new int[D][];
for (int d=0; d<D; d++)
binnedCodes[t][d]=new int[freqs[d]];
int[] idxs=new int[D];
for (int c=0; c<ncombos; c++) {
int d=trees[t].depth(c);
if (d!=-1) binnedCodes[t][d][idxs[d]++]=c;
}
}
//the collection of all trees creates a total list of pieces that the trees collectively solve
int tK=0; for (LoopoverBFS t:trees) tK+=t.K;
int[] solvedscrm=new int[tK];
Expand All @@ -128,7 +120,7 @@ private static void improve(int R, int C, String[] Rfrees, String[] Cfrees, int
int totdepth=0; for (int d:depths) totdepth+=d;
if (totdepth>threshold) {
long ncombos=1;
for (int t=0; t<T; t++) ncombos*=binnedCodes[t][depths[t]].length;
for (int t=0; t<T; t++) ncombos*=trees[t].codesAtDepth(depths[t]).length;
totcombos+=ncombos;
depthSets.add(depths.clone());
}
Expand All @@ -143,12 +135,12 @@ private static void improve(int R, int C, String[] Rfrees, String[] Cfrees, int
for (int[] depths:depthSets) {
{
long ncombos=1;
for (int t=0; t<T; t++) ncombos*=binnedCodes[t][depths[t]].length;
for (int t=0; t<T; t++) ncombos*=trees[t].codesAtDepth(depths[t]).length;
System.out.println(Arrays.toString(depths)+": ncombos="+ncombos);
}
int[][] bins=new int[T][];
for (int t=0; t<T; t++)
bins[t]=binnedCodes[t][depths[t]];
bins[t]=trees[t].codesAtDepth(depths[t]);
int[] idxs=new int[T];
long st=System.currentTimeMillis();
long stage=0, mark0=5000, mark=mark0;
Expand All @@ -162,7 +154,7 @@ private static void improve(int R, int C, String[] Rfrees, String[] Cfrees, int
int[] scrm=solvedscrm.clone();
//rescramble this solved state
for (int t=T-1; t>-1; t--)
scrm=prodperm(scrm,inv(trees[t].solveaction(codes[t])));
scrm=prodperm(scrm,trees[t].scrambleaction(codes[t]));
//scrm[i]=the location where the piece solvedscrm[i] goes to
//the locations that all the pieces of trees[t].pcstosolve go to
// are described by the subarray scrm[subarrstart[t]]...scrm[subarrstart[t+1]-1]
Expand All @@ -172,7 +164,9 @@ private static void improve(int R, int C, String[] Rfrees, String[] Cfrees, int
int[] nscrm=prodperm(scrm,mvseqactions.get(mvsi));
int ntotdepth=mvseqs.get(mvsi).length;
/*seqs.clear();
seqs.add(mvseqs.get(mvsi));*/
seqs.add(new ArrayList<>());
for (int mi:mvseqs.get(mvsi))
seqs.get(0).add(mvs[mi]);*/
for (int t=0; t<T; t++) {
//TODO: CUT OUT PREFIX OF nscrm AFTER EACH PHASE OF SOLVING
int i=subarrstart[t], j=subarrstart[t+1];
Expand All @@ -187,14 +181,7 @@ private static void improve(int R, int C, String[] Rfrees, String[] Cfrees, int
}
if (!reduced) {
System.out.println("NOT REDUCED:");
int[] display=new int[R*C]; Arrays.fill(display,-1);
for (int i=0; i<tK; i++)
display[scrm[i]]=solvedscrm[i];
for (int r=0; r<R; r++) {
for (int c=0; c<C; c++)
System.out.print(display[r*C+c]==-1?'.':(char)('A'+display[r*C+c]));
System.out.println();
}
System.out.print(boardStr(solvedscrm,scrm,R,C));
for (int t=0; t<T; t++) {
System.out.println("t="+t);
List<int[]> tmp=trees[t].solvemvs(codes[t]);
Expand All @@ -203,15 +190,8 @@ private static void improve(int R, int C, String[] Rfrees, String[] Cfrees, int
}
return;
}
/*{
int[] display=new int[R*C]; Arrays.fill(display,-1);
for (int i=0; i<tK; i++)
display[scrm[i]]=solvedscrm[i];
for (int r=0; r<R; r++) {
for (int c=0; c<C; c++)
System.out.print(display[r*C+c]==-1?'.':(char)('A'+display[r*C+c]));
System.out.println();
}
/*if (Math.random()<0.000001) {
System.out.print(boardStr(solvedscrm,scrm,R,C));
for (List<int[]> tmp:seqs) {
for (int[] mv:tmp) System.out.print(" "+Arrays.toString(mv));
System.out.println();
Expand All @@ -238,10 +218,20 @@ public static void main(String[] args) {
improve(6,6,
new String[] {"000011","000011","000001"},
new String[] {"000011","000001","000001"},
//28,>6
28,7,
28,6,
new boolean[] {true,true}
);
/*improve(6,6,
new String[] {"111111","001111","000111"},
new String[] {"111111","001111","000111"},
//27,1
//26,>5
);*/
System.out.println("time="+(System.currentTimeMillis()-st));
//TODO: REVERT BACK TO 2-WAY BFS OPT?
//TODO: 6x6:4x5-5x5-6x6: 38,5; 6x6:4x4-4x5-5x5:27,X
//TODO: 6x6:0x0-2x2-3x3: <27?
//TODO: 3-WAY 6x6:4x4-4x5-5x5-6x6
//TODO: 4-WAY 5x5:0x0-2x2-3x3-4x4-5x5
}
}

0 comments on commit 64b6b4c

Please sign in to comment.