简体   繁体   English

迭代深化深度优先搜索启发式解决“3 Missionary and Cannibal”挑战

[英]Iterative deepening depth-first search heuristics to solve “3 Missionary And Cannibal” challenge

I implemented it using iterative deepening depth-first search algorithm.我使用迭代深化深度优先搜索算法实现了它。 My state is represented by a 3-element vector <A,B,C> where A represents the side of the boat (0/1), B and C represents the number of cannibals and missionary on the left hand side of the bank.我的状态由一个 3 元素向量 <A,B,C> 表示,其中 A 代表船的一侧 (0/1),B 和 C 代表银行左侧的食人者和传教士的数量。 I tried to solve this problem, searching on different sources but I could not find the error.我试图解决这个问题,搜索不同的来源,但我找不到错误。


#include <bits/stdc++.h>

using namespace std;
/*
SOLUTION TO 3 CANNIBAL and 3 MISSIONARIES PROBLEM 
USING ITERATIVE DEEPENING DEPTH FIRST SEARCH
https://en.wikipedia.org/wiki/Missionaries_and_cannibals_problem
*/

//state initial state (0,3,3) Side Of the Boat 0->Right/1 /Cannibal/Missionary on right hand side
vector<pair<int, pair<int, int>>> newStatesSet(pair<int, pair<int, int>> state)
{
    //generating all possible states from a given initial state
    vector<pair<int, pair<int, int>>> newStatesSet;
    int C = state.second.first, M = state.second.second;

    if (state.first == 0)
    {
        if (C >= 1)
            newStatesSet.push_back(make_pair(1, make_pair(C - 1, M)));
        if (M >= 1)
            newStatesSet.push_back(make_pair(1, make_pair(C, M - 1)));
        if (C >= 2)
            newStatesSet.push_back(make_pair(1, make_pair(C - 2, M)));
        if (C >= 1 && M >= 1)
            newStatesSet.push_back(make_pair(1, make_pair(C - 1, M - 1)));
        if (M >= 2)
            newStatesSet.push_back(make_pair(1, make_pair(C, M - 2)));
    }
    else
    {
        C = 3 - C;
        M = 3 - M;

        if (C >= 1)
            newStatesSet.push_back(make_pair(0, make_pair(3 - C + 1, 3 - M)));
        if (M >= 1)
            newStatesSet.push_back(make_pair(0, make_pair(3 - C, 3 - M + 1)));
        if (C >= 2)
            newStatesSet.push_back(make_pair(0, make_pair(3 - C + 2, 3 - M)));
        if (C >= 1 && M >= 1)
            newStatesSet.push_back(make_pair(0, make_pair(3 - C + 1, 3 - M + 1)));
        if (M >= 2)
            newStatesSet.push_back(make_pair(0, make_pair(3 - C, 3 - M + 2)));
    }
    return newStatesSet;
}

bool validState(pair<int, pair<int, int>> state)
{
    int C = state.second.first, M = state.second.second;
    if (C > M && M != 0)
        return false;
    C = 3 - C, M = 3 - M;
    if (C > M && M != 0)
        return false;
    return true;
}

//source node , goal node , depth , answer if found is stored here
bool depthLimitedSearch(pair<int, pair<int, int>> source, pair<int, pair<int, int>> goal, int depth, vector<pair<int, pair<int, int>>> &ans)
{

    if (source == goal)
        return true;

    if (depth <= 0)
        return false;

    vector<pair<int, pair<int, int>>> leafs = newStatesSet(source);
    for (int i = 0; i < leafs.size(); i++)
        if (validState(leafs[i]))
        {
            if (depthLimitedSearch(leafs[i], goal, depth - 1, ans))
            {
                ans.push_back(leafs[i]);
                return true;
            }
        }
}

string form(int stateNos, string character)
{
    string rep = "";
    for (int i = 1; i <= 3; i++)
        if (stateNos >= i)
            rep.append(character);
        else
            rep.append(" ");
    return rep;
}

void displayState(pair<int, pair<int, int>> state)
{
    string rep = "";
    rep.append(form(state.second.first, "C"));
    rep.append(form(state.second.second, "M"));
    for (int i = 1; i <= 6; i++)
    {
        if (state.first == 0 && i == 2)
            rep.append("B");
        else if (state.first == 1 && i == 5)
            rep.append("B");
        else
            rep.append(" ");
    }
    rep.append(form(3 - state.second.first, "C"));
    rep.append(form(3 - state.second.second, "M"));
    cout << rep << endl;
}

void iterativeDeepeningSearch(pair<int, pair<int, int>> source, pair<int, pair<int, int>> goal)
{

    vector<pair<int, pair<int, int>>> ans;
    for (int i = 1; i <= 25; i++)
    {
        vector<pair<int, pair<int, int>>> vec;
        depthLimitedSearch(source, goal, i, vec);
        if (vec.size() > 0)
        {
            ans = vec;
            break;
        }
    }
    cout << "C and M represents cannibals and Missionaries \n respectively and B represents the location of boat\n";
    displayState(source);
    for (int i = ans.size() - 1; i >= 0; i--)
        displayState(ans[i]);
}

int main()
{
    pair<int, pair<int, int>> source = make_pair(0, make_pair(3, 3));
    pair<int, pair<int, int>> goal = make_pair(1, make_pair(0, 0));
    iterativeDeepeningSearch(source, goal);
}

My output:我的输出:

CCCMMM B
CC MMM    B C

What the result should be:结果应该是:

CCCMMM B          
C  MMM    B CC    
CC MMM B    C     
   MMM    B CCC   
C  MMM B    CC    
C  M      B CC MM 
CC MM  B    C  M  
CC        B C  MMM
CCC    B       MMM
C         B CC MMM
CC     B    C  MMM
          B CCCMMM

I searched on different sources, it was not what I needed.我搜索了不同的来源,这不是我需要的。 It's the first time I've worked with vectors and pairs这是我第一次使用向量和对

At the end of the "depthLimitedSearch" function, insert "return false"在“depthLimitedSearch”函数的末尾,插入“return false”

bool depthLimitedSearch(pair<int, pair<int, int>> source, pair<int, pair<int, int>> goal, int depth, vector<pair<int, pair<int, int>>>& ans)
        {
            if (source == goal)
                return true;

            if (depth <= 0)
                return false;

            vector<pair<int, pair<int, int>>> leafs = newStatesSet(source);
            for (int i = 0; i < leafs.size(); i++)
                if (validState(leafs[i]))
                {
                    if (depthLimitedSearch(leafs[i], goal, depth - 1, ans))
                    {
                        ans.push_back(leafs[i]);
                        return true;
                    }
                }

            return false;
        }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM