1. 程式人生 > >鑽石獨立棋的用HASH表和棧改進版

鑽石獨立棋的用HASH表和棧改進版

  雖然只是小程式,呵呵,順便多學點STL吧,就把它由原來的遍歷搜尋改成用HASHMAP儲存改進,時間加快了不少哦,嗯,HASHKEY有二種,一種就用一個LONG LONG來表示,呀,剛好多了二位,不然INT就夠了,另一種就用一串STRING來了,這裡是用STRING的,這樣的搜尋模板就更完整了哦:)
/*
CODY BY 我的BLOG AT 2004.10.9
獨立鑽石棋問題, 深度優先搜尋,儘量清除重複點
2004.10.18
利用HASHMAP改進CLOSED集,利用STACK改進OPEN集.

棋盤編號佈局如下:
      01 02 03
      04 05 06
07 08 09 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
   28 29 30
   31 32 33
*/
#include <iostream>
#include <fstream>
#include <algorithm>
#include <stack>
#include <string>
#include <hash_map>

#include "Node.h"
using namespace std;
using namespace stdext;

stack<Node> open;
hash_map<string,Node> closed;
typedef pair <string, Node> Pair;
hash_map<string,Node>:: const_iterator rcIter;


// 判斷next結點是否已擴充套件過,是返回true,否則false
bool extended(Node &next);
// 搜尋解
void search();

int main(void)
{
 search();
 system("pause");
 return 0;
}

void search()
{
 // 初始化
 Node first;
 for(int i=1;i<=33;i++){
  first.c[i] = 1;
 }
 first.c[17] = 0;
 first.key = 0;
 open.push(first);

 // 開始迴圈
 while(!open.empty()){
  //cout<<"正在搜尋......         已擴充套件結點:"<<closed.size()<<"/n";
  Node tmp = open.top();
  open.pop();

  // 看所取節點是否為目標節點
  if(tmp.moveid[0] >= 31 && tmp.c[17] == 1){
   tmp.output(cout);      // 輸出解並返回
   ofstream out("out.txt");
   tmp.output(out);      
   return ;
  }

  // 若不是則生成所有的子狀態
  Node next;
  bool hadit;
  for(int i = 1;i <= 33 ;i++){
   if(tmp.c[i] != 0){
    if( tmp.down(i,next)){
     if(extended(next) == false){ // 還沒擴充套件過
      open.push(next);
     }
    }
    if( tmp.up(i,next)){
     if(extended(next) == false){ // 還沒擴充套件過
      open.push(next);
     }
    }
    if( tmp.left(i,next)){
     if(extended(next) == false){ // 還沒擴充套件過
      open.push(next);
     }
    }
    if( tmp.right(i,next)){
     if(extended(next) == false){ // 還沒擴充套件過
      open.push(next);
     }
    }
   }
  }
  // 將剛才取出的open點放入closed表
  closed.insert ( Pair(tmp.getHashKey(),tmp));
 }
}

bool extended(Node &next)
{
 // 若next在closed中,即已擴充套件過了,返回true
 rcIter = closed.find(next.getHashKey());
 if(rcIter == closed.end()){
  return false;
 }else{
  return true;
 }
}