查重型别
|
对应的容器
|
NoCheckDup
|
list |
OrderCheckDup
|
multi_index_container |
HashCheckDup
|
multi_index_container |
// Filename: BFS_DFS_v2.hpp
#ifndef _BFS_DFS_HPP
#define _BFS_DFS_HPP
#include
#include
#include
#include
#include
#include
using std::list;
using std::vector;
using boost::multi_index::multi_index_container;
using boost::multi_index::indexed_by;
using boost::multi_index::sequenced;
using boost::multi_index::ordered_unique;
using boost::multi_index::hashed_unique;
using boost::multi_index::identity;
struct NoCheckDup {};
struct OrderCheckDup {};
struct HashCheckDup {};
struct BFS {};
struct DFS {};
// 状态空间树搜索模板
// State:问题状态类,提供nextStep()和isTarget()成员函数
// SearchType:可选择BFS或DFS,缺省为BFS
// CheckDup:状态查重算法,可选择NoCheckDup,HashCheckDup,OrderCheckDup
template < class State, class SearchType = BFS, class CheckDup = NoCheckDup >
class StateSpaceTreeSearch
{
// 当SearchType不为BFS和DFS时,出错
template
struct SearchInserter
{
};
// BFS算法对应的新结点插入策略
template
struct SearchInserter
{
public:
SearchInserter(Cont& c) : c_(c) {}
typedef typename Cont::iterator iterator;
typedef typename Cont::value_type value_type;
void operator()(iterator it, const value_type& v) {
c_.push_back(v); //新结点插入到列表的末端,即未搜索的结点后
}
private:
Cont& c_;
};
// DFS算法对应的新结点插入策略
template
struct SearchInserter
{
public:
SearchInserter(Cont& c) : c_(c) {}
typedef typename Cont::iterator iterator;
typedef typename Cont::value_type value_type;
void operator()(iterator it, const value_type& v) {
c_.insert(++it, v); //新结点插入到未搜索的结点前
}
private:
Cont& c_;
};
// 当CheckDup不为下面偏特化的三者之一时,出错
template
struct Container
{
};
// NoCheckDup策略采用list为容器
template
struct Container
{
typedef list Cont;
};
// OrderCheckDup策略采用multi_index_container为容器,有一个order唯一索引
template
struct Container
{
typedef multi_index_container< S,
indexed_by< sequenced<>, ordered_unique< identity > >
> Cont;
};
// HashCheckDup策略采用multi_index_container为容器,有一个hash唯一索引
template
struct Container
{
struct HashFcn
{
size_t operator()(const S& s) const { return s.hash(); }
};
typedef multi_index_container< S,
indexed_by< sequenced<>, hashed_unique< identity, HashFcn > >
> Cont;
};
public:
typedef typename Container
typedef typename Cont::iterator iterator;
typedef SearchInserter
template
int operator()(const State& initState, Func afterFindSolution) const
// initState : 初始化状态,类State应提供成员函数nextStep()和isTarget(),
// nextStep()用vector
// isTarget()用于判断当前状态是否符合要求的答案;
// afterFindSolution : 仿函式,在找到一个有效答案后调用之,它接受一个
// const State&,并返回一个bool值,true表示停止搜索,
// false表示继续搜索
// return : 找到的答案数量
{
Cont states;
Inserter inserter(states);
states.push_back(initState);
iterator head = states.begin(); //指向下个搜索的结点
vector
int n = 0; //记录找到的解答数量
bool stop = false;
while (!stop && head != states.end())
{
State s = *head; //搜索一个结点
nextStates.clear();
s.nextStep(nextStates); //从搜索点生成下一层结点
for (typename vector
i != nextStates.end(); ++i)
{
if (i->isTarget())
{ // 找到一个目标状态
++n;
if (stop = afterFindSolution(*i)) //处理结果并决定是否停止
{
break;
}
} else { // 不是目标状态,插入树中,树所使用的容器类会自动查重
inserter(head, *i);
}
}
++head; //指针移到下一个元素
}
return n;
}
};
#endif
相对应的新的推箱子程序如下:
// soko.cpp -- 推箱子主程序
#include
#include "BFS_DFS_v2.hpp"
#include "SokoState_v1.h"
using namespace std;
bool printAnswer(const SokoState& s)
{
s.printAnswer(cout);
cout << endl;
return true;
}
int main()
{
SokoState initState;
cin >> initState;
cout << initState;
StateSpaceTreeSearch
int n = sokoSearch(initState, printAnswer);
if (n == 0)
{
cout << "No answer." << endl;
}
return 0;
}