Advertisement
Guest User

puzzle-8-Astar

a guest
Apr 24th, 2011
113
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 12.98 KB | None | 0 0
  1.  
  2. /* puzzle 8 by hanhan */
  3. /* belum beres :D */
  4. #include <iostream>
  5. #include <cstdlib>
  6. //#include "random_state.h"
  7.  
  8. using std::cout;
  9. using std::endl;
  10.  
  11. #define atas -3
  12. #define bawah 3
  13. #define kanan 1
  14. #define kiri -1
  15.  
  16. //int pAwal[9] = {7,2,4,5,0,6,1,8,3};
  17. //int pAwal[9] = {4,2,1,3,5,6,0,7,8};
  18. //int pAwal[9] = {2,8,3,1,6,4,7,0,5};     //bisa
  19. //int pAwal[9] = {2,8,1,4,6,3,0,7,5};
  20. //int pAwal[9] = {1,2,3,8,0,4,6,5,7};               //gagal
  21.  
  22. //int pAwal[9] = {1,3,4,8,6,2,7,0,5};           //berhasil
  23. //int pAwal[9] = {1,3,4,8,0,2,7,6,5};           //berhasil
  24. int pAwal[9] = {1,2,3,8,0,4,6,5,7};               //gagal
  25.  
  26. int pAkhir[9] = {1,2,3,8,0,4,7,6,5};
  27.  
  28. clock_t start, finish;
  29. double waktu;
  30.  
  31. struct PuzzleNode {
  32.     int node[9];
  33.     int g;
  34.     int h;
  35.     int f;
  36.     int langkah;
  37.     PuzzleNode *parent;
  38.     int plangkah;   //langkah parent
  39.     PuzzleNode *next;
  40. };
  41.  
  42. PuzzleNode neighbors[4];
  43. PuzzleNode *first = NULL;                   //first list open
  44. PuzzleNode *last = NULL;                    //last list open
  45. PuzzleNode *akhir = NULL;                   //awal list closed
  46. PuzzleNode *awal = NULL;                    //akhir list closed
  47.  
  48. void cp(int a[], int b[])   //salin posisi
  49. {
  50.     for(int i=0;i<9;i++)
  51.     {
  52.         a[i]=b[i];
  53.     }
  54. }
  55.  
  56. int abs(int x)  //fungsi absolut (kenapa ga bisa pakai yang sudah jadi ya?
  57. {
  58.     if(x<0) return (x*-1);
  59.     return x;
  60. }
  61.  
  62. int compare(int pState[], int pGoal[])  //bandingkan dua posisi
  63. {
  64.     int sama =0;
  65.     for(int i=0;i<9;i++)
  66.     {
  67.         if(pState[i]!=pGoal[i])
  68.         {
  69.             sama=0;
  70.             break;
  71.         }
  72.         else
  73.             sama=1;
  74.     }
  75.     return sama;
  76. }
  77.  
  78. int manhattanHeuristic(int pState[]) //pakai manhattan distance
  79. {
  80.     int distance=0;
  81.     int row, col,r,c;
  82.     for(r=0;r<9;r++)
  83.     {
  84.         for(c=0;c<9;c++)
  85.         {
  86.             if(pState[r]!=0)
  87.             {
  88.                 if(pState[r]==pAkhir[c])
  89.                 {
  90.                     row = r%3;
  91.                     col = r/3;
  92.                     distance += abs(row-(c%3)) + abs(col-(c/3));
  93.                 }
  94.             }
  95.         }
  96.     }
  97.     return distance;
  98. }
  99.  
  100. void cetakPuzzle(int pState[])  //cetak puzzle
  101. {
  102.     for(int i=0;i<9;i++)
  103.     {
  104.         if(i%3==0)
  105.             cout<<endl;
  106.         cout<<pState[i]<<" ";
  107.     }
  108.     cout<<endl;
  109. }
  110.  
  111. int cariNol(int pState[])       //cari posisi Nol
  112. {
  113.     int posisi;
  114.     for(int i=0;i<9;i++)
  115.     {
  116.         if(pState[i]==0)
  117.             posisi = i;
  118.     }
  119.     return posisi;
  120. }
  121.  
  122. void gerak(int pState[], int arah, int p[])
  123. {
  124.     int pNol,temp2;
  125.     //int p[9];
  126.     cp(p,pState);                        //salin state[] ke temp
  127.     pNol=cariNol(p);                     //cari posisi nol ada di mana
  128.     //gerak berdasarkan posisi nol
  129.     temp2= p[pNol];                      //tukar-tukar
  130.     p[pNol] = p[pNol+arah];
  131.     p[pNol+arah] = temp2;
  132. }
  133.  
  134. void cekNeighbors(PuzzleNode *pState)
  135. {
  136.     int posNol = cariNol(pState->node);
  137.     switch(posNol)
  138.     {
  139.     case 0:
  140.         gerak(pState->node,kanan,neighbors[0].node);
  141.         gerak(pState->node,bawah,neighbors[1].node);
  142.         neighbors[0].langkah = kanan;
  143.         neighbors[1].langkah = bawah;
  144.         break;
  145.     case 1:
  146.         gerak(pState->node,kiri,neighbors[0].node);
  147.         gerak(pState->node,kanan,neighbors[1].node);
  148.         gerak(pState->node,bawah,neighbors[2].node);
  149.         neighbors[0].langkah = kiri;
  150.         neighbors[1].langkah = kanan;
  151.         neighbors[2].langkah = bawah;
  152.         break;
  153.     case 2:
  154.         gerak(pState->node,kiri,neighbors[0].node);
  155.         gerak(pState->node,bawah,neighbors[1].node);
  156.         neighbors[0].langkah = kiri;
  157.         neighbors[1].langkah = bawah;
  158.         break;
  159.     case 3:
  160.         gerak(pState->node,atas,neighbors[0].node);
  161.         gerak(pState->node,kanan,neighbors[1].node);
  162.         gerak(pState->node,bawah,neighbors[2].node);
  163.         neighbors[0].langkah = atas;
  164.         neighbors[1].langkah = kanan;
  165.         neighbors[2].langkah = bawah;
  166.         break;
  167.     case 4:
  168.         gerak(pState->node,kiri,neighbors[0].node);
  169.         gerak(pState->node,atas,neighbors[1].node);
  170.         gerak(pState->node,kanan,neighbors[2].node);
  171.         gerak(pState->node,bawah,neighbors[3].node);
  172.         neighbors[0].langkah = kiri;
  173.         neighbors[1].langkah = atas;
  174.         neighbors[2].langkah = kanan;
  175.         neighbors[3].langkah = bawah;
  176.         break;
  177.     case 5:
  178.         gerak(pState->node,kiri,neighbors[0].node);
  179.         gerak(pState->node,atas,neighbors[1].node);
  180.         gerak(pState->node,bawah,neighbors[2].node);
  181.         neighbors[0].langkah = kiri;
  182.         neighbors[1].langkah = atas;
  183.         neighbors[2].langkah = bawah;
  184.         break;
  185.     case 6:
  186.         gerak(pState->node,atas,neighbors[0].node);
  187.         gerak(pState->node,kanan,neighbors[1].node);
  188.         neighbors[0].langkah = atas;
  189.         neighbors[1].langkah = kanan;
  190.         break;
  191.     case 7:
  192.         gerak(pState->node,kiri,neighbors[0].node);
  193.         gerak(pState->node,atas,neighbors[1].node);
  194.         gerak(pState->node,kanan,neighbors[2].node);
  195.         neighbors[0].langkah = kiri;
  196.         neighbors[1].langkah = atas;
  197.         neighbors[2].langkah = kanan;
  198.         break;
  199.     case 8:
  200.         gerak(pState->node,kiri,neighbors[0].node);
  201.         gerak(pState->node,atas,neighbors[1].node);
  202.         neighbors[0].langkah = kiri;
  203.         neighbors[1].langkah = atas;
  204.         break;
  205.     }
  206. }
  207.  
  208. //samentawis
  209. void cetakOpen()
  210. {
  211.     cout<<"=======Isi open==========="<<endl;
  212.     PuzzleNode *current = first;
  213.     while(current)
  214.     {
  215.         cetakPuzzle(current->node);
  216.         cout<<"F: "<<current->f<<"| G: "<<current->g<<" | H: "<<current->h<<endl;
  217.         current = current->next;
  218.     }
  219.     cout<<"=======sampai sini==========="<<endl;
  220. }
  221.  
  222. void cetakClose()
  223. {
  224.     cout<<"=======Isi close==========="<<endl;
  225.     PuzzleNode *current = awal;
  226.     while(current->next)
  227.     {
  228.         cetakPuzzle(current->node);
  229.         cout<<"F: "<<current->f<<"| G: "<<current->g<<" | H: "<<current->h<<endl;
  230.         current = current->next;
  231.     }
  232.     cout<<"=======sampai sini==========="<<endl;
  233. }
  234.  
  235. void bestNode(PuzzleNode *temp)
  236. {
  237.     PuzzleNode *lOpen = first;
  238.     //PuzzleNode *temp = new PuzzleNode;
  239.     int min = lOpen->f;
  240.     cp(temp->node,lOpen->node);
  241.     temp->f = lOpen->f;
  242.     temp->g = lOpen->g;
  243.     temp->h = lOpen->h;
  244.     temp->langkah = lOpen->langkah;
  245.     //cp(temp->parent,lOpen->parent);
  246.     temp->parent=lOpen->parent;
  247.     //bandingkan f terkecil
  248.     while(lOpen)
  249.     {
  250.        // cout<<"nilai Min= "<<min<<endl;
  251.         if(lOpen->f<min)
  252.         {
  253.             min = lOpen->f;
  254.             temp->f = lOpen->f;
  255.             cp(temp->node,lOpen->node);
  256.             temp->f = lOpen->f;
  257.             temp->g = lOpen->g;
  258.             temp->h = lOpen->h;
  259.             temp->langkah = lOpen->langkah;
  260.             //cp(temp->parent,lOpen->parent);
  261.             //temp->parent=lOpen->parent;
  262.         }
  263.         lOpen= lOpen->next;
  264.     }
  265.     //
  266.     //cout<<"node terbaik dengan F: "<<temp->f<<endl;
  267.    // cetakPuzzle(temp->node);
  268. }
  269.  
  270. void inputList(PuzzleNode *pState)
  271. {
  272.     //cout<<"input list open"<<endl;
  273.     PuzzleNode *lOpen = new PuzzleNode;
  274.     cp(lOpen->node,pState->node);
  275.     lOpen->f = pState->f;
  276.     lOpen->g = pState->g;
  277.     lOpen->h = pState->h;
  278.     lOpen->langkah = pState->langkah;
  279.     lOpen->plangkah = pState->plangkah;
  280.     //cp(lOpen->parent,pState->parent);
  281.     lOpen->parent=pState->parent;
  282.  
  283.     if(!first)
  284.     {
  285.         first = lOpen;
  286.         last = lOpen;
  287.     } else
  288.     {
  289.         last->next = lOpen;
  290.         last = lOpen;
  291.     }
  292.  
  293. }
  294.  
  295. void delNode(PuzzleNode *pState)
  296. {
  297.     PuzzleNode *current = first;
  298.     while(current)
  299.     {
  300.         if(compare(current->node,pState->node)==1)
  301.         {
  302.             if(current==first)
  303.             {
  304.                //if(current->next){
  305.                     first = current->next;
  306.                //}
  307.                 delete current;
  308.             }else if(current==last)
  309.             {
  310.                 PuzzleNode *pos;
  311.                 pos = first;
  312.                 while(pos->next != last)
  313.                         pos = pos->next;
  314.                 pos->next = NULL;
  315.                 last = pos;
  316.                 delete current;
  317.             }
  318.             else {
  319.                 PuzzleNode *pos;
  320.                 pos = first;
  321.                 while(pos->next != current)
  322.                         pos = pos->next;
  323.                 pos->next = current->next;
  324.                 delete current;
  325.             }
  326.  
  327.             break;
  328.  
  329.         }
  330.  
  331.         current=current->next;
  332.     }
  333.  
  334.  
  335. }
  336.  
  337. void inputClose(PuzzleNode *pState)
  338. {
  339.    // cout<<"input close akan dimasukkan F: "<<pState->f<<" G: "<<pState->g<<" H: "<<pState->h<<endl;
  340.     PuzzleNode *temp = new PuzzleNode;
  341.     cp(temp->node,pState->node);
  342.     temp->f = pState->f;
  343.     temp->g = pState->g;
  344.     temp->h = pState->h;
  345.     temp->langkah = pState->langkah;
  346.     temp->plangkah = pState->plangkah;
  347.     //cp(temp->parent,pState->parent);
  348.     temp->parent=pState->parent;
  349.     if(!awal)
  350.     {
  351.         awal = temp;
  352.         akhir = temp;
  353.     } else
  354.     {
  355.         akhir->next = temp;
  356.         akhir = temp;
  357.     }
  358. }
  359.  
  360. int cekInClosed(int pState[])
  361. {
  362.     int sama =0;
  363.     PuzzleNode *lClosed = awal;
  364.     while(lClosed)
  365.     {
  366.         if(compare(lClosed->node,pState)==1)
  367.         {
  368.             sama =1;
  369.             break;
  370.         }
  371.         lClosed = lClosed->next;
  372.     }
  373.     return sama;
  374. }
  375.  
  376. void rekonstruksi(PuzzleNode *pNode)
  377. {
  378.     //belum beresss
  379.     cout<<"langkah:"<<endl;
  380.     //int s= compare(pNode->node,pAwal);
  381.     cout<<pNode->langkah<<endl;
  382.     while(compare(pNode->node,pAwal)!=1)
  383.     {
  384.         cout<<pNode->langkah<<endl;
  385.         pNode= pNode->parent;
  386.     }
  387.     //   while(pNode->langkah==0)
  388.     //   {
  389.     //     cout<<pNode->langkah<<endl;
  390.     //     pNode->langkah = pNode->plangkah;
  391.      //  }
  392. }
  393.  
  394. void AStar()
  395. {
  396.     start = clock();
  397.     PuzzleNode *pState = new PuzzleNode;
  398.     PuzzleNode *x = new PuzzleNode;
  399.     PuzzleNode *y = new PuzzleNode;
  400.     int g=0;
  401.     //int j=0;
  402.     bool lanjut=true;
  403.     cp(pState->node,pAwal);
  404.     pState->h = manhattanHeuristic(pState->node);
  405.     pState->f = pState->h;
  406.     pState->g = 0;
  407.     pState->langkah = 0;
  408.     //cp(pState->parent,pAwal);
  409.     pState->parent = NULL;
  410.     //1. masukkan state awal ke openList
  411.     inputList(pState);
  412.     //car node terbaik
  413.     //selama ada isinya di open
  414.     PuzzleNode *open = first;
  415.     while(lanjut){
  416.  
  417.         //cout<<"iterasi: "<<g<<endl;
  418.         g++;
  419.  
  420.         //cetakOpen();
  421.         bestNode(x);
  422.         //delete di open
  423.         delNode(x);
  424.         //masukkan x ke close;
  425.         //cetakPuzzle(x->node);
  426.         inputClose(x);
  427.         if(compare(x->node,pAkhir)==1)
  428.         {
  429.             cout<<"\n\nHoreee...ketemu"<<endl;
  430.             cout<<"Posisi awal"<<endl;
  431.             cetakPuzzle(pAwal);
  432.             cout<<"\nPosisi Akhir"<<endl;
  433.             cetakPuzzle(x->node);
  434.             cout<<"Waktu iterasi: "<<g<<endl;
  435.             //rekonstruksi(x);
  436.             break;
  437.         }
  438.  
  439.         cekNeighbors(x);
  440.         for(int i=0;i<4;i++)
  441.         {
  442.             if((neighbors[i].langkah!=0) )
  443.             {
  444.                 //cek apakah ada di closed
  445.                 if(cekInClosed(neighbors[i].node)!=1)
  446.                 {
  447.                     //cp(y->parent,x->node);
  448.                     y->parent=x;
  449.                     y->plangkah = x->langkah;
  450.                     y->langkah = neighbors[i].langkah;
  451.                     //cout<<"nilai plangkah: "<<x->langkah<<endl;
  452.                     y->g = x->g + 1 ;
  453.                     y->h = manhattanHeuristic(neighbors[i].node);
  454.                     y->f = y->g + y->h;
  455.                     cp(y->node,neighbors[i].node);
  456.                     //masukkan ke openlist
  457.                     inputList(y);
  458.                 }
  459.             }
  460.         }
  461.         //cetakClose();
  462.         if(open)
  463.             lanjut = true;
  464.         else
  465.             break;
  466.     }
  467.     finish = clock();
  468.     waktu = (double(finish)-double(start))/CLOCKS_PER_SEC;
  469.     cout<<"waktu : "<<waktu<<" detik"<<endl;
  470.  
  471. }
  472.  
  473. void menu()
  474. {
  475.     int pilih;
  476.     cout<<"\n\t1. {1,3,4,8,6,2,7,0,5}"<<endl;
  477.     cout<<"\t2. {2,8,1,0,4,3,7,6,5}"<<endl;      //katanya hard
  478.     cout<<"\t3. {2,8,1,4,6,3,0,7,5}"<<endl;
  479.     cout<<"\t4. {5,6,7,4,0,8,3,2,1}"<<endl;
  480.     //cout<<"\t5. Random"<<endl;
  481.     cout<<"\n\tPilih State Awal: ";
  482.     //std::cin>>pilih;
  483.     pilih =5;
  484.     int p[9];
  485.     int xrand=0;
  486.     switch(pilih)
  487.     {
  488.     case 1:
  489.         p= {1,3,4,8,6,2,7,0,5};
  490.         cp(pAwal,p);
  491.         AStar();
  492.         break;
  493.     case 2:
  494.         p= {2,8,1,0,4,3,7,6,5};
  495.         cp(pAwal,p);
  496.         AStar();
  497.         break;
  498.     case 3:
  499.         p= {2,8,1,4,6,3,0,7,5};
  500.         cp(pAwal,p);
  501.         AStar();
  502.         break;
  503.     case 4:
  504.         p= {5,6,7,4,0,8,3,2,1};
  505.         cp(pAwal,p);
  506.         AStar();
  507.         break;
  508.    
  509.     default:
  510.         p= {2,8,3,1,6,4,7,0,5};
  511.         cp(pAwal,p);
  512.         AStar();
  513.         break;
  514.     }
  515. }
  516.  
  517. int main()
  518. {
  519.     menu();
  520.     return 0;
  521. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement