问题原型:
三只水桶条件:1号8升、2号5升、3号3升,并且没有刻度。初始状态为1号桶装满水,目标状态为把水等分为2份。
思路:
建立状态模型:
状态为
struct BulketState
{
int Bulkets[3]; //如{800}{503}等
}
行为有六种(1表示得到水,-1表示倒出水,0表示不动),{1、-1、0}{1、0、-1}{0、-1、1}{0、1、-1}{-1、0、1}{-1、1、0},根据状态对行为进行遍历同时判断行为是否可行,把下一状态存入队列当中,用于判断状态是否重复,有重复时这条分支终止行为。
#pragma once
#include <vector>
#include <algorithm>
#include <iostream>
// 8 3 5
namespace fs
{
class BulketWater
{
public:
struct BulketsState
{
BulketsState()
{
for (int i = 0; i < 3; i++)
{
Bulket[i] = 0;
}
}
int Bulket[3];
bool operator==(const BulketsState& rhs)
{
return (Bulket[0] == rhs.Bulket[0] && Bulket[1] == rhs.Bulket[1] && Bulket[2] == rhs.Bulket[2]);
}
};
typedef std::vector<BulketsState> StateVector;
struct Action
{
int from;
int to;
};
std::vector<Action> m_ActionVector;
StateVector m_StateVector;
char volume[3];
friend std::ostream& operator<<(std::ostream&,const BulketsState&);
BulketWater();
bool IsStateAvailable(const BulketsState&);
bool IsStateExist(const BulketsState&);
void AddState(const BulketsState&);
BulketsState NextState(const BulketsState&, Action&);
void StateLoop(BulketsState,int);
void StateLoop(BulketsState,int,bool);
};
}
#include "stdafx.h"
#include "Bulket.h"
namespace fs
{
std::ostream& operator<<(std::ostream& rhs, const BulketWater::BulketsState& state)
{
return rhs << state.Bulket[0] << state.Bulket[1] << state.Bulket[2];
}
BulketWater::BulketWater()
{
volume[0] = 8;
volume[1] = 3;
volume[2] = 5;
Action action;//初始化行为空间
for (int from = 0; from < 3; from++)
{
for (int to = 0; to < 3; to++)
{
if (from != to)
{
action.from = from;
action.to = to;
m_ActionVector.push_back(action);
}
}
}
}
bool BulketWater::IsStateAvailable(const BulketsState& state)
{
if (state.Bulket[0] <= 8 && state.Bulket[0] >= 0 && state.Bulket[1] <= 3 && state.Bulket[1] >= 0 && state.Bulket[2] <= 5 && state.Bulket[2] >= 0 && (state.Bulket[0] + state.Bulket[1] +state.Bulket[2]) == 8)
{
return true;
}
return false;
}
bool BulketWater::IsStateExist(const BulketsState& state)
{
return std::find(m_StateVector.begin(),m_StateVector.end(),state) != m_StateVector.end();
}
BulketWater::BulketsState BulketWater::NextState(const BulketsState& state, Action& action)
{
if (!IsStateAvailable(state))
{
return BulketsState();
}
BulketsState temp(state);
int dif = volume[action.to] - state.Bulket[action.to];
if ( dif >= temp.Bulket[action.from])
{
temp.Bulket[action.from] = 0;
}
else
{
temp.Bulket[action.from] = state.Bulket[action.from] - (volume[action.to] - state.Bulket[action.to]);
}
temp.Bulket[action.to] = state.Bulket[action.to] + (state.Bulket[action.from] - temp.Bulket[action.from]);
return temp;
}
void BulketWater::StateLoop(BulketsState state,int deep)
{
if (!IsStateAvailable(state) || IsStateExist(state))
{
return;
}
for (int i = 0; i < deep; i++)
{
std::cout << "-";
}
m_StateVector.push_back(state);
std::cout << state << std::endl;
for (int i = 0; i < 6; i++)
{
StateLoop(NextState(state,m_ActionVector.at(i)),deep + 1);
}
}
void BulketWater::StateLoop(BulketsState state,int deep,bool)
{
StateVector tempStateVector;//缓存临时状态
for (int i = 0; i < 6; i++)
{
BulketsState temp = NextState(state,m_ActionVector.at(i));
if (!IsStateAvailable(temp) || IsStateExist(temp))
{
continue;
}
m_StateVector.push_back(temp);
tempStateVector.push_back(temp);
std::cout << state;
for (int i = 0; i < deep + 2; i++)
{
std::cout << "-";
}
std::cout << temp << std::endl;
}
StateVector::iterator iter;
for (iter = tempStateVector.begin(); iter != tempStateVector.end(); iter++)
{
StateLoop(*iter,deep + 2,false);
}
return;
}
}
//重载函数是广度和深度遍历(广度遍历函数有问题,只处理了一个叶节点)
#include "stdafx.h"
#include "Bulket.h"
int _tmain(int argc, _TCHAR* argv[])
{
fs::BulketWater tt;
fs::BulketWater::BulketsState state;
state.Bulket[0] = 8;
state.Bulket[1] = 0;
state.Bulket[2] = 0;
std::cout << state << std::endl;
tt.m_StateVector.push_back(state);
fs::BulketWater::BulketsState nothing;
tt.StateLoop(state,0,0);
int d;
scanf("%d",&d);
return 0;
}
//深度遍历的结果
//有问题的广度遍历的结果,若想得到最短路径,需要用广度遍历