用C++编程,使用深度优先算法解决农夫过河问题
时间: 2024-05-10 11:18:17 浏览: 73
农夫过河问题是一个经典的搜索问题,可以使用深度优先算法进行求解。以下是使用C++编程语言实现的示例代码:
```c++
#include <iostream>
#include <stack>
#include <unordered_set>
using namespace std;
// 定义状态结构体
struct State {
int farmer; // 农夫所在的岸边,0表示左岸,1表示右岸
int wolf; // 狼所在的岸边,0表示左岸,1表示右岸
int goat; // 羊所在的岸边,0表示左岸,1表示右岸
int cabbage; // 卷心菜所在的岸边,0表示左岸,1表示右岸
bool operator==(const State& other) const {
return farmer == other.farmer && wolf == other.wolf &&
goat == other.goat && cabbage == other.cabbage;
}
};
// 定义哈希函数
struct HashFunc {
size_t operator()(const State& state) const {
return state.farmer * 8 + state.wolf * 4 + state.goat * 2 +
state.cabbage * 1;
}
};
// 判断当前状态是否合法
bool is_valid(const State& state) {
if (state.wolf == state.goat && state.farmer != state.wolf) {
return false; // 狼吃羊
}
if (state.goat == state.cabbage && state.farmer != state.goat) {
return false; // 羊吃卷心菜
}
return true;
}
// 判断当前状态是否为目标状态
bool is_goal(const State& state) {
return state.farmer == 1 && state.wolf == 1 &&
state.goat == 1 && state.cabbage == 1;
}
// 打印状态
void print_state(const State& state) {
cout << "Farmer: " << (state.farmer == 0 ? "Left" : "Right") << endl;
cout << "Wolf: " << (state.wolf == 0 ? "Left" : "Right") << endl;
cout << "Goat: " << (state.goat == 0 ? "Left" : "Right") << endl;
cout << "Cabbage: " << (state.cabbage == 0 ? "Left" : "Right") << endl;
}
// 深度优先搜索
bool dfs(State state, stack<State>& path, unordered_set<State, HashFunc>& visited) {
if (!is_valid(state)) {
return false;
}
if (is_goal(state)) {
path.push(state);
return true;
}
visited.insert(state);
bool found = false;
State next_state;
// 农夫带狼过河
if (state.farmer == state.wolf) {
next_state = {1 - state.farmer, 1 - state.wolf, state.goat, state.cabbage};
if (visited.find(next_state) == visited.end()) {
found = dfs(next_state, path, visited);
}
}
// 农夫带羊过河
if (!found && state.farmer == state.goat) {
next_state = {1 - state.farmer, state.wolf, 1 - state.goat, state.cabbage};
if (visited.find(next_state) == visited.end()) {
found = dfs(next_state, path, visited);
}
}
// 农夫带卷心菜过河
if (!found && state.farmer == state.cabbage) {
next_state = {1 - state.farmer, state.wolf, state.goat, 1 - state.cabbage};
if (visited.find(next_state) == visited.end()) {
found = dfs(next_state, path, visited);
}
}
// 农夫单独过河
if (!found) {
next_state = {1 - state.farmer, state.wolf, state.goat, state.cabbage};
if (visited.find(next_state) == visited.end()) {
found = dfs(next_state, path, visited);
}
}
if (found) {
path.push(state);
}
return found;
}
int main() {
State initial_state = {0, 0, 0, 0};
stack<State> path;
unordered_set<State, HashFunc> visited;
if (dfs(initial_state, path, visited)) {
while (!path.empty()) {
print_state(path.top());
path.pop();
}
} else {
cout << "No solution found." << endl;
}
return 0;
}
```
在上面的实现中,我们使用了一个 `State` 结构体来表示每个状态,其中 `farmer`、`wolf`、`goat` 和 `cabbage` 分别表示农夫、狼、羊和卷心菜所在的岸边。我们还定义了一个哈希函数 `HashFunc`,用于将状态映射到一个整数上,方便存储和查找。
在 `dfs` 函数中,我们首先判断当前状态是否合法,如果不合法就返回 `false`。然后判断当前状态是否为目标状态,如果是就返回 `true`,并将当前状态压入路径栈中。否则,我们尝试四种不同的过河方式,递归地搜索下去,直到找到目标状态或者无解为止。
最后,在 `main` 函数中,我们调用 `dfs` 函数进行搜索,如果找到了解就依次打印路径栈中的状态,否则输出提示信息。
阅读全文