微软过桥问题的C++实现
来源:互联网 发布:xt800是什么软件 编辑:程序博客网 时间:2024/04/19 14:38
#include <vector>
#include <iostream>
#include <queue>
#include <stack>
using namespace std;
class Bridge_Crossing
{
public:
Bridge_Crossing(vector<int> &c);
void generate_solution();
private:
class Node;
vector<Node>states; //一个状态向量。每一个状态保存一项,共2^(n+1)项
vector<int>costs;//每个人过河所需要的时间。
int person_num;
void output();
struct State
{
int state;//状态值。如全在左岸则为0000(binary),过河后该位置1
int direction;//方向,若在左岸为0,右岸为1
State()
{
state=direction=0;
}
State &operator= (const State &s)
{
state=s.state;
direction=s.direction;
}
int hashcode()//计算hash值,即在states向量中的index
{
return state*2+direction;
}
};
struct Node
{
int value;//到该状态所需时间
int previous;//前一状态的index
Node()
{
value=previous=0;
}
};
};
Bridge_Crossing:: Bridge_Crossing(vector<int>&c)
{
costs=c;
person_num = costs.size();
states=vector<Node>((1<<(person_num+1)));
}
void Bridge_Crossing::generate_solution()
{
queue<State>q;
q.push(State());//初始压栈(0000 0)
while(!q.empty())
{
State s = q.front();
q.pop();
if(s.direction==0) // 过河去,送两人
{
for(int i=0;i<person_num-1;++i)
{
int flag = 1<<i;
if((s.state&flag)==0) //第i个人仍在左岸
{
for(int j=i+1;j<person_num;++j)
{
int f2 = 1<<j;
if((s.state&f2)==0)//第j个人仍在左岸
{
State t;
t.state = s.state|flag|f2;//i,j两人过河。
t.direction=1;
int index = t.hashcode();
Node n;
n.previous = s.hashcode();
n.value = states[n.previous].value+max(costs[i],costs[j]);
if(states[index].value==0||n.value<states[index].value)
//若以前未到此结点,或这次的值比原来的值更优
{
states[index]=n;
}
if(index!=states.size()-1)
//全部到达则无需再入队列
q.push(t);
}
}
}
}
}
else
{
for(int i=0;i<person_num;++i)
{
int flag = 1<<i;
if((s.state&flag)!=0)
{
State t;
t.state = s.state&(~flag);
t.direction=0;
int index = t.hashcode();
Node n;
n.previous = s.hashcode();
n.value = states[n.previous].value+costs[i];
if(states[index].value==0||n.value<states[index].value)
{
states[index]=n;
}
if(index!=states.size()-1)
q.push(t);
}
}
}
}
output();
}
void Bridge_Crossing::output()
{
int p = states.size()-1;
stack<int>s;
while(p!=0)
{
s.push(p);
p=states[p].previous;
}
int state = 0;
int direction = 0;
while(!s.empty())
{
int t = s.top();
s.pop();
int difference= state^t;
difference>>=1;// 删除最右边一个表示方面的位
int flag=1;
for(int i=0;i<person_num;++i)
{
if((difference&flag)!=0)
cout<<i+1<<"号 ";
flag<<=1;
}
cout<<(direction==0?"过河":"返回")<<" 共"<<states[t].value<<"秒"<<endl;
direction^=1;
state=t;
}
}
int main()
{
vector<int> v(4) ;
v[0]=1;
v[1]=2;
v[2]=5;
v[3]=10;
Bridge_Crossing b(v);
b.generate_solution();
}
#include <iostream>
#include <queue>
#include <stack>
using namespace std;
class Bridge_Crossing
{
public:
Bridge_Crossing(vector<int> &c);
void generate_solution();
private:
class Node;
vector<Node>states; //一个状态向量。每一个状态保存一项,共2^(n+1)项
vector<int>costs;//每个人过河所需要的时间。
int person_num;
void output();
struct State
{
int state;//状态值。如全在左岸则为0000(binary),过河后该位置1
int direction;//方向,若在左岸为0,右岸为1
State()
{
state=direction=0;
}
State &operator= (const State &s)
{
state=s.state;
direction=s.direction;
}
int hashcode()//计算hash值,即在states向量中的index
{
return state*2+direction;
}
};
struct Node
{
int value;//到该状态所需时间
int previous;//前一状态的index
Node()
{
value=previous=0;
}
};
};
Bridge_Crossing:: Bridge_Crossing(vector<int>&c)
{
costs=c;
person_num = costs.size();
states=vector<Node>((1<<(person_num+1)));
}
void Bridge_Crossing::generate_solution()
{
queue<State>q;
q.push(State());//初始压栈(0000 0)
while(!q.empty())
{
State s = q.front();
q.pop();
if(s.direction==0) // 过河去,送两人
{
for(int i=0;i<person_num-1;++i)
{
int flag = 1<<i;
if((s.state&flag)==0) //第i个人仍在左岸
{
for(int j=i+1;j<person_num;++j)
{
int f2 = 1<<j;
if((s.state&f2)==0)//第j个人仍在左岸
{
State t;
t.state = s.state|flag|f2;//i,j两人过河。
t.direction=1;
int index = t.hashcode();
Node n;
n.previous = s.hashcode();
n.value = states[n.previous].value+max(costs[i],costs[j]);
if(states[index].value==0||n.value<states[index].value)
//若以前未到此结点,或这次的值比原来的值更优
{
states[index]=n;
}
if(index!=states.size()-1)
//全部到达则无需再入队列
q.push(t);
}
}
}
}
}
else
{
for(int i=0;i<person_num;++i)
{
int flag = 1<<i;
if((s.state&flag)!=0)
{
State t;
t.state = s.state&(~flag);
t.direction=0;
int index = t.hashcode();
Node n;
n.previous = s.hashcode();
n.value = states[n.previous].value+costs[i];
if(states[index].value==0||n.value<states[index].value)
{
states[index]=n;
}
if(index!=states.size()-1)
q.push(t);
}
}
}
}
output();
}
void Bridge_Crossing::output()
{
int p = states.size()-1;
stack<int>s;
while(p!=0)
{
s.push(p);
p=states[p].previous;
}
int state = 0;
int direction = 0;
while(!s.empty())
{
int t = s.top();
s.pop();
int difference= state^t;
difference>>=1;// 删除最右边一个表示方面的位
int flag=1;
for(int i=0;i<person_num;++i)
{
if((difference&flag)!=0)
cout<<i+1<<"号 ";
flag<<=1;
}
cout<<(direction==0?"过河":"返回")<<" 共"<<states[t].value<<"秒"<<endl;
direction^=1;
state=t;
}
}
int main()
{
vector<int> v(4) ;
v[0]=1;
v[1]=2;
v[2]=5;
v[3]=10;
Bridge_Crossing b(v);
b.generate_solution();
}
- 微软过桥问题的C++实现
- 关于微软面试题:"四人过桥"问题的思考——“n人过桥”问题的演进(Java实现)
- 关于微软面试题:"四人过桥"问题的思考——“n人过桥”问题的演进(Java实现)
- 微软过桥问题的图论解法
- 微软过桥问题的图论解法
- 微软过桥问题的图论解法
- 微软过桥问题的图论解法
- 微软过桥问题的图论解法
- 微软过桥问题的图论解法
- 微软过桥问题的图论解法
- 微软过桥问题的图论解法
- 微软过桥问题的图论解法
- 微软过桥问题的图论解法
- 微软过桥问题的图论解法
- 微软过桥问题的图论解法
- 微软过桥问题的图论解法
- 微软过桥问题的图论解法
- 微软过桥问题
- WebConfigurationManager相关
- C开发CGI以及sqlite数据库http://www.liniu.cn/post/c-cgi-sqlite.html
- 浏览器Javascript性能测试网址
- jsp EL表达式结合JSTL标准标签实现分页
- 《汇编语言》读书笔记(6)——解决子程序与主程序使用的寄存器的冲突
- 微软过桥问题的C++实现
- Linux/Windows双系统重装XP后GRUB的修复
- error PRJ0019的一个解决心得
- ***大学校园信息化系统(URP)总结
- 单机中国象棋(Java版)
- 在SQLServer中调用外部扩展存储过程
- Css属性值计算
- 媒体对华为不公,国人应该清醒 [转]枯荷雨声
- VS2005的程序文件分发问题及解决