//is called by main, starts the recursive function off, looping properly for the first tile void FindSolutionDriver(Board &board, const std::vector<Tile*> &tiles, std::vector<Location> &locations,bool all_solutions,bool allow_rotations) { //for each possible beginning place, run the recursive FindSolution function bool go_on=true; int count=0,rotation=0; std::vector<std::vector<Location> > alreadyfoundsolutions; std::vector<Board> previousboards; std::vector<Tile*> rotatedtiles; for (int i=0;i<board.numRows();++i) { for (int j=0;j<board.numColumns();++j) { FindSolution(board,tiles,locations,0,i,j,go_on,count,all_solutions, allow_rotations,alreadyfoundsolutions,previousboards, rotation,rotatedtiles); if (!go_on) return; } } if (count>0){ if (all_solutions){ std::cout<<"Found "<<count<<" Solution(s)."; } }else std::cout<<"No Solution."; for (int i=0;i<rotatedtiles.size();i++) { delete rotatedtiles[i]; } }
void Try(int x, int y) { int i; for(i=0; i<8; i++) { if(!InRange(x+dx[i])) continue; if(!InRange(y+dy[i])) continue; if(bVisited[x+dx[i]][y+dy[i]]) continue; bVisited[x+dx[i]][y+dy[i]] = 1; cntVisited ++; seqVisited[x+dx[i]][y+dy[i]] = ++seq; if(cntVisited == (N+1)*(N+1)) FindSolution(); else { if(x==4 && y==3) { int x6=0; x6++; } Try(x+dx[i], y+dy[i]); } bVisited[x+dx[i]][y+dy[i]] = 0; cntVisited --; seqVisited[x+dx[i]][y+dy[i]] =0, seq--; } }
void TryItem(int iPosBegin) { int i; for(i=1; i<=2; i++) { if(i==1) { if(sum + t[iPosBegin] > T) continue; bTaken[iPosBegin] = 1; sum += t[iPosBegin]; cntItem ++; } if(iPosBegin==N) FindSolution(); else TryItem(iPosBegin+1); if(i==1) { bTaken[iPosBegin] = 0; sum -= t[iPosBegin]; cntItem --; } } }
int solve_nsnipers(int *battlefield, int n) { if (battlefield == NULL) return 0; if (FindSolution(battlefield, 0, n) == 0) { return 0; } return 1; }
//What to do if Solution button is clicked void Fifteen::SolutionClick() { if (!usedSolution) { usedSolution = true; endOfGame = true; FindSolution(); } else { PromptOK(SOLUTIONMSG); } }
int FindSolution(int *battlefield, int column, int n) { if (column >= n) { return 1; } for (int row_index = 0; row_index < n; row_index++) { if (isSafe(battlefield, row_index, column, n) == true) { *((battlefield + row_index*n) + column) = 1; if (FindSolution(battlefield, column + 1, n) == true) return 1; *((battlefield + row_index*n) + column) = 0; } } return 0; }
//recursive function that does all the work void FindSolution(Board &board, const std::vector<Tile*> &tiles, std::vector<Location> &locations,int tilenumber,int rownum,int colnum, bool &go_on,int& count,bool all_solutions,bool allow_rotations, std::vector<std::vector<Location> > &alreadyfoundsolutions, std::vector<Board> &previousboards,int rotation,std::vector<Tile*> &rotatedtiles) { //this makes new tiles corresponding to rotated versions of themselves to //test the rotated cases Tile* updatedtile=tiles[tilenumber]; int originallocationssize=alreadyfoundsolutions.size(); if (rotation==90) { updatedtile=new Tile(updatedtile->getWest(),updatedtile->getNorth(), updatedtile->getEast(),updatedtile->getSouth()); }else if (rotation==180) { updatedtile=new Tile(updatedtile->getSouth(),updatedtile->getWest(), updatedtile->getNorth(),updatedtile->getEast()); }else if (rotation==270){ updatedtile=new Tile(updatedtile->getEast(),updatedtile->getSouth(), updatedtile->getWest(),updatedtile->getNorth()); } /*each direction checks to see if that direction is an edge and if so that the coinciding edge of the tile is a pasture. Otherwise it checks that its a NULL tile. If it is neither of these things, it finally checks that the connecting edges are the same */ bool north=(rownum==0 && updatedtile->getNorth()=="pasture") || rownum!=0 && (board.getTile(rownum-1,colnum)==NULL || board.getTile(rownum-1,colnum)->getSouth()==updatedtile->getNorth()); bool south=(rownum+1==board.numRows() && updatedtile->getSouth()=="pasture") || rownum+1!=board.numRows() && (board.getTile(rownum+1,colnum)==NULL || board.getTile(rownum+1,colnum)->getNorth()==updatedtile->getSouth()); bool east =(colnum+1==board.numColumns() && updatedtile->getEast()=="pasture") || colnum+1!=board.numColumns() && (board.getTile(rownum,colnum+1)==NULL || board.getTile(rownum,colnum+1)->getWest()==updatedtile->getEast()); bool west =(colnum==0 && updatedtile->getWest()=="pasture") || colnum!=0 && (board.getTile(rownum,colnum-1)==NULL || board.getTile(rownum,colnum-1)->getEast()==updatedtile->getWest()); if (north && east && south && west) { if (tilenumber==(tiles.size()-1)){//if it's the last tile entered board.setTile(rownum,colnum,updatedtile); locations.push_back(Location(rownum,colnum,rotation)); //prepares the new board, whether it's right or not for testing if(BoardIsCorrect(board)) { bool notinsidealready=true; //initial check to see if the final solution already exists. //because this only checks the locations vector, we will need a second,more //intensive checker for shifted boards and rotated pieces for (int iter=0;iter<alreadyfoundsolutions.size();++iter) { if (locations==alreadyfoundsolutions[iter]) { notinsidealready=false; break; } } if (notinsidealready) { //more complicated checker,no point in bothering if it's the first solution if (alreadyfoundsolutions.size()>0) notinsidealready=Boardcomparator(previousboards,board); if (notinsidealready) { alreadyfoundsolutions.push_back(locations); previousboards.push_back(board); if (!all_solutions) go_on=false;//if we only want the first, "stops" here std::cout<<"Solution: "; for (int i = 0; i < locations.size(); i++) { std::cout << locations[i]; } std::cout<<std::endl; board.Print(); count++; } } } board.clearTile(rownum,colnum); locations.pop_back(); //fixes the board so that it is back at it's previous state (whether it was a //a solution or not) } else { int rotationcounter=0; do { board.setTile(rownum,colnum,updatedtile); locations.push_back(Location(rownum,colnum,rotation)); Tile* tileiterator; for (int i=0;i<board.numRows();++i) { for (int j=0;j<board.numColumns();++j) {//enables a check of every single tile tileiterator=board.getTile(i,j); //for every tile, if it's not empty, tries to put the current tile in the //adjacent empty tiles if (tileiterator!=NULL) { if (i>0 && board.getTile(i-1,j)==NULL && (all_solutions || go_on)) {//north FindSolution(board,tiles,locations,tilenumber+1,i-1,j,go_on, count,all_solutions,allow_rotations,alreadyfoundsolutions, previousboards,90*rotationcounter,rotatedtiles); }if (j+1<board.numColumns() && board.getTile(i,j+1)==NULL && (all_solutions || go_on)) {//east FindSolution(board,tiles,locations,tilenumber+1,i,j+1,go_on, count,all_solutions,allow_rotations,alreadyfoundsolutions, previousboards,90*rotationcounter,rotatedtiles); }if (i+1<board.numRows() && board.getTile(i+1,j)==NULL && (all_solutions || go_on)) {//south FindSolution(board,tiles,locations,tilenumber+1,i+1,j,go_on, count,all_solutions,allow_rotations,alreadyfoundsolutions, previousboards,90*rotationcounter,rotatedtiles); }if (j>0 && board.getTile(i,j-1)==NULL && (all_solutions || go_on)) {//west FindSolution(board,tiles,locations,tilenumber+1,i,j-1,go_on, count,all_solutions,allow_rotations,alreadyfoundsolutions, previousboards,90*rotationcounter,rotatedtiles); } } } } //probably a for loop for each tile to look around it and recurse //also make it not replace others (if board^==null) board.clearTile(rownum,colnum); locations.pop_back(); //fixes the board so that it is back at it's previous state rotationcounter++; } while (allow_rotations && rotationcounter<4); } } //check to see if the thing has been saved, if not delete it, otherwise save it if (!(updatedtile==tiles[tilenumber])){ if (originallocationssize<alreadyfoundsolutions.size()) { rotatedtiles.push_back(updatedtile); }else { delete updatedtile; } } }
extern int ImproveAlignment(StarCatRec *PStarCatBaseProp, StarCatRec *PStarCatProp, SuperAlignParmRec *PSAPP, float *PBestdX, float *PBestdY, float *PBestRotAngle) /* BestX > 0 ... means PStarCatProp is to the right of PStarCatBaseProp */ /* BestX < 0 ... means PStarCatProp is to the left of PStarCatBaseProp */ /* BestRotAngle > 0 means PStarCatProp is CCW of PStarCatBaseProp */ /* BestRotAngle < 0 means PStarCatProp is CW of PStarCatBaseProp */ { FILE *fout; int NL1,NL2,I,J; float CosF,SinF,ShiftX,ShiftY,RotateAng; float *X1,*Y1,*M1,*X2,*Y2,*M2,BestdX,BestdY,BestOrient,BestScore,Score; float *TX2,*TY2,NumC,YDiff,XDiff,TempX2,TempY2,BestNumC; int *POK1,*POK2,*ind,*ind2; int *NNeigh,**NeighList; float *PAng1,*PAng2,*PAngT,*PDist1,*PDist2,*PDistT,Ang; DetermineGuess(PStarCatBaseProp,PStarCatProp, &ShiftX,&ShiftY,&RotateAng); Verbose = 1; fprintf(stdout,"Aligning %s (%i objs) to %s (%i objs)\n", PStarCatProp->FN,PStarCatProp->NObj, PStarCatBaseProp->FN,PStarCatBaseProp->NObj); ShowGuess(PStarCatBaseProp,PStarCatProp,ShiftX,ShiftY,RotateAng); NL1 = PStarCatBaseProp->NObj; X1 = (float *)calloc(NL1,sizeof(float)); Y1 = (float *)calloc(NL1,sizeof(float)); M1 = (float *)calloc(NL1,sizeof(float)); POK1 = (int *)calloc(NL1,sizeof(int)); for (I=0;I<NL1;I++) { X1[I] = PStarCatBaseProp->PX[I]; Y1[I] = PStarCatBaseProp->PY[I]; M1[I] = pow(10.0,-0.4*PStarCatBaseProp->PM[I]); } CosF = cos(M_PI*RotateAng/180); SinF = sin(M_PI*RotateAng/180); NL2 = PStarCatProp->NObj; TX2 = (float *)calloc(NL2,sizeof(float)); TY2 = (float *)calloc(NL2,sizeof(float)); X2 = (float *)calloc(NL2,sizeof(float)); Y2 = (float *)calloc(NL2,sizeof(float)); M2 = (float *)calloc(NL2,sizeof(float)); POK2 = (int *)calloc(NL2,sizeof(int)); for (I=0;I<NL2;I++) { TX2[I] = ShiftX+PStarCatProp->PX[I]*CosF+ PStarCatProp->PY[I]*SinF; TY2[I] = ShiftY-PStarCatProp->PX[I]*SinF+ PStarCatProp->PY[I]*CosF; X2[I] = PStarCatProp->PX[I]; Y2[I] = PStarCatProp->PY[I]; M2[I] = pow(10.0,-0.4*PStarCatProp->PM[I]); } RemoveClosePairs(X1,Y1,NL1,1,PSAPP); RemoveClosePairs(TX2,TY2,NL2,-1,PSAPP); NNeigh = (int *)calloc(NL1,sizeof(int)); NeighList = (int **)calloc(NL1,sizeof(int *)); NeighborList(X1,Y1,NL1,TX2,TY2,NL2,PSAPP->MaxDist, NNeigh,NeighList); BestdX = ShiftX; BestdY = ShiftY; BestOrient = RotateAng; FindSolution(&BestdX,&BestdY,&BestOrient,X1,Y1,M1,NL1,X2,Y2,M2,NL2, NNeigh,NeighList,PSAPP); Score = CalcSigma(BestdX,BestdY,BestOrient,X1,Y1,M1,NL1,X2,Y2,M2,NL2, NNeigh,NeighList,PSAPP,1,POK1,POK2,&NumC); free(X1); free(Y1); free(M1); free(POK1); free(TX2); free(TY2); free(X2); free(Y2); free(M2); free(POK2); *PBestdX = BestdX; *PBestdY = BestdY; *PBestRotAngle = BestOrient; fprintf(stdout,"Converged on %g good stars.\n",NumC); /* fprintf(stdout,"Solution: dx = %.2f, dy = %.2f, theta = %.2f\n", BestdX,BestdY,BestOrient);*/ }
extern int TryAlignment(StarCatRec *PStarCatBaseProp, StarCatRec *PStarCatProp, SuperAlignParmRec *PSAPP, float *PBestdX, float *PBestdY, float *PBestRotAngle) /* BestX > 0 ... means PStarCatProp is to the right of PStarCatBaseProp */ /* BestX < 0 ... means PStarCatProp is to the left of PStarCatBaseProp */ /* BestRotAngle > 0 means PStarCatProp is CCW of PStarCatBaseProp */ /* BestRotAngle < 0 means PStarCatProp is CW of PStarCatBaseProp */ { FILE *fout; int NL1,NL2,I,J; float CosF,SinF,ShiftX,ShiftY,RotateAng; float *X1,*Y1,*M1,*X2,*Y2,*M2,BestdX,BestdY,BestOrient,BestScore,Score; float *TX2,*TY2,NumC,YDiff,XDiff,TempX2,TempY2,BestNumC; int *POK1,*POK2,*ind,*ind2; int *NNeigh,**NeighList; float *PAng1,*PAng2,*PAngT,*PDist1,*PDist2,*PDistT,Ang; int K,K1,LL,HL,L,Tot,NTot; DetermineGuess(PStarCatBaseProp,PStarCatProp, &ShiftX,&ShiftY,&RotateAng); Verbose = 1; fprintf(stdout,"Aligning %s (%i objs) to %s (%i objs)\n", PStarCatProp->FN,PStarCatProp->NObj, PStarCatBaseProp->FN,PStarCatBaseProp->NObj); ShowGuess(PStarCatBaseProp,PStarCatProp,ShiftX,ShiftY,RotateAng); NL1 = PStarCatBaseProp->NObj; X1 = (float *)calloc(NL1,sizeof(float)); Y1 = (float *)calloc(NL1,sizeof(float)); M1 = (float *)calloc(NL1,sizeof(float)); POK1 = (int *)calloc(NL1,sizeof(int)); for (I=0;I<NL1;I++) { X1[I] = PStarCatBaseProp->PX[I]; Y1[I] = PStarCatBaseProp->PY[I]; M1[I] = pow(10.0,-0.4*PStarCatBaseProp->PM[I]); } CosF = cos(M_PI*RotateAng/180); SinF = sin(M_PI*RotateAng/180); NL2 = PStarCatProp->NObj; TX2 = (float *)calloc(NL2,sizeof(float)); TY2 = (float *)calloc(NL2,sizeof(float)); X2 = (float *)calloc(NL2,sizeof(float)); Y2 = (float *)calloc(NL2,sizeof(float)); M2 = (float *)calloc(NL2,sizeof(float)); POK2 = (int *)calloc(NL2,sizeof(int)); for (I=0;I<NL2;I++) { TX2[I] = ShiftX+PStarCatProp->PX[I]*CosF+ PStarCatProp->PY[I]*SinF; TY2[I] = ShiftY-PStarCatProp->PX[I]*SinF+ PStarCatProp->PY[I]*CosF; X2[I] = PStarCatProp->PX[I]; Y2[I] = PStarCatProp->PY[I]; M2[I] = pow(10.0,-0.4*PStarCatProp->PM[I]); } OutputXYM(X1,Y1,M1,NL1,"A"); OutputXYM(TX2,TY2,M2,NL2,"B"); OutputXYM(X2,Y2,M2,NL2,"C"); RemoveClosePairs(X1,Y1,NL1,1,PSAPP); RemoveClosePairs(TX2,TY2,NL2,-1,PSAPP); NNeigh = (int *)calloc(NL1,sizeof(int)); NeighList = (int **)calloc(NL1,sizeof(int *)); NeighborList(X1,Y1,NL1,TX2,TY2,NL2,PSAPP->MaxShiftErr, NNeigh,NeighList); BestScore = 0; ind2 = (int *)calloc(NL2,sizeof(int)); PAngT = (float *)calloc(NL2,sizeof(float)); PDistT = (float *)calloc(NL2,sizeof(float)); PAng2 = (float *)calloc(NL2,sizeof(float)); PDist2 = (float *)calloc(NL2,sizeof(float)); PAng1 = (float *)calloc(NL1,sizeof(float)); PDist1 = (float *)calloc(NL1,sizeof(float)); ind = (int *)calloc(NL1,sizeof(int)); hpsort(NL1,M1,ind); BestdX = 0.0; BestdY = 0.0; BestOrient = 0.0; for (I=NL1-1;I>=0;I--) { int Wh; Wh = ind[I]; if (!strcmp(PStarCatBaseProp->FN, PStarCatProp->FN)) { NNeigh[Wh] = 0; I = 0; } for (J=0;J<NNeigh[Wh];J++) { float Score,dX,dY; for (K=0;K<NL2;K++) { XDiff = X2[K] - X2[NeighList[Wh][J]]; YDiff = Y2[K] - Y2[NeighList[Wh][J]]; PAngT[K] = (180/M_PI)*atan2(YDiff,XDiff); PDistT[K] = sqrt(YDiff*YDiff+XDiff*XDiff); } hpsort(NL2,PAngT,ind2); for (K=0;K<NL2;K++) { PAng2[K] = PAngT[ind2[K]]; PDist2[K] = PDistT[ind2[K]]; } for (K=0;K<NL1;K++) { XDiff = X1[K]-X1[Wh]; YDiff = Y1[K]-Y1[Wh]; PAng1[K] = (180/M_PI)*atan2(YDiff,XDiff); PDist1[K] = sqrt(YDiff*YDiff+XDiff*XDiff); for (K1=-1;K1<2;K1++) { LL = BinSearchF(PAng2,PAng1[K]+RotateAng-PSAPP->MaxRotErr+K1*360, NL2-1,TakeBound); HL = BinSearchF(PAng2,PAng1[K]+RotateAng+PSAPP->MaxRotErr+K1*360, NL2-1,TakeBound)+1; if (LL < 0) { LL = BinSearchF(PAng2,PAng1[K]+RotateAng-PSAPP->MaxRotErr+K1*360, NL2-1,TakeBound); HL = BinSearchF(PAng2,PAng1[K]+RotateAng+PSAPP->MaxRotErr+K1*360, NL2-1,TakeBound)+1; } for (L=LL;L<HL;L++) { if ((fabs(PAng1[K]+RotateAng+K1*360-PAng2[L])<PSAPP->MaxRotErr)&& (fabs(PDist1[K] - PDist2[L]) < PSAPP->MaxDist)) { Ang = PAng2[L]-PAng1[K]; CosF = cos(M_PI*Ang/180); SinF = sin(M_PI*Ang/180); TempX2 = X2[NeighList[Wh][J]]*CosF+Y2[NeighList[Wh][J]]*SinF; TempY2 = -X2[NeighList[Wh][J]]*SinF+Y2[NeighList[Wh][J]]*CosF; dX = X1[Wh]-TempX2; dY = Y1[Wh]-TempY2; Score = CalcSigma(dX,dY,Ang,X1,Y1,M1,NL1,X2,Y2,M2,NL2, NNeigh,NeighList,PSAPP, 0,NULL,NULL,&NumC); if (Score > BestScore) { BestScore = CalcSigma(dX,dY,Ang,X1,Y1,M1,NL1,X2,Y2,M2,NL2, NNeigh,NeighList,PSAPP, 0,NULL,NULL,&NumC); BestdX = dX; BestdY = dY; BestOrient = Ang; BestNumC = NumC; if (NumC > 18) { /* if more than 30 matches are obtained, this is good enough and we will simply abort. */ I = 0; J = NNeigh[Wh]; L = HL; K1 = 2; K = NL1; } } } } } } } } /* Attempt one last iterative improvement to best transformation obtained above */ FindSolution(&BestdX,&BestdY,&BestOrient,X1,Y1,M1,NL1,X2,Y2,M2,NL2, NNeigh,NeighList,PSAPP); Score = CalcSigma(BestdX,BestdY,BestOrient,X1,Y1,M1,NL1,X2,Y2,M2,NL2, NNeigh,NeighList,PSAPP,1,POK1,POK2,&NumC); free(X1); free(Y1); free(M1); free(POK1); free(TX2); free(TY2); free(X2); free(Y2); free(M2); free(POK2); free(ind); free(ind2); free(PAngT); free(PDistT); free(PAng2); free(PDist2); free(PAng1); free(PDist1); free(NNeigh); for (I=0;I<NL1;I++) free(NeighList[I]); free(NeighList); *PBestdX = BestdX; *PBestdY = BestdY; *PBestRotAngle = BestOrient; fprintf(stdout,"Converged on %g good stars.\n",NumC); /* fprintf(stdout,"Solution: dx = %.2f, dy = %.2f, theta = %.2f\n", BestdX,BestdY,BestOrient);*/ }
//reset window state when solve starts void StartSolve() { siSolveInfo.running=true; FindSolution(); }