I started learning AI recently. In AI, searches should be avoided and everything in AI is a search problem.
One of the easiest problem where we could use general AI search techniques is the water jug problem which states:
You are given two jugs, a 4-gallon one and a 3-gallon one. Neither has any measuring markers on it. There is a tap that can be used to fill the jugs with water. How can you get exactly 2 gallons of water into the 4-gallon jug?
I solved it using the BFS technique:
#include <bits/stdc++.h>
using namespace std;
vector <pair<int,int> > newStatesSet(pair<int,int> state){
//generating all possible states from a given initial state
vector<pair<int,int> > newStates;
if(state.first==0 && state.second==0){
newStates.push_back(make_pair(3,0));
newStates.push_back(make_pair(0,4));
newStates.push_back(make_pair(3,4));
}
if(state.first!=0 && state.second==0){
newStates.push_back(make_pair(state.first,4));
newStates.push_back(make_pair(0,state.first));
if(state.first<3){
newStates.push_back(make_pair(3,0));
newStates.push_back(make_pair(3,4));
}
}
if(state.first==0 && state.second!=0){
int transferQuantity;
if(state.second>3)
transferQuantity=3;
else
transferQuantity=state.second;
newStates.push_back(make_pair(transferQuantity,state.second-transferQuantity));
newStates.push_back(make_pair(3,state.second));
}
if(state.first!=0 && state.second!=0){
newStates.push_back(make_pair(0,state.second));
newStates.push_back(make_pair(state.first,0));
if(state.second<4){
int transferQuantity1=state.second+state.first;
int transferQuantity2;
if(transferQuantity1>4){
transferQuantity2=transferQuantity1-4;
transferQuantity1=4;
}
else
transferQuantity2=0;
newStates.push_back(make_pair(transferQuantity2,transferQuantity1));
}
if(state.first<3){
int transferQuantity1=state.second+state.first;
int transferQuantity2;
if(transferQuantity1>3){
transferQuantity2=transferQuantity1-3;
transferQuantity1=3;
}
else
transferQuantity2=0;
newStates.push_back(make_pair(transferQuantity1,transferQuantity2));
}
}
return newStates;
}
bool checkGoal(pair<int,int> x,int sum){
if(x.second==sum)
return true;
return false;
}
void reverseTraversal(map <pair<int,int>,pair<int,int> > parent,pair<int,int> initialState,pair<int,int> goalState){
if(initialState != goalState){
reverseTraversal(parent,parent[initialState],goalState);
}
cout<<"("<<initialState.first<<","<<initialState.second<<")"<<endl;
}
int main()
{
//capacity (3,4)
//open list
queue <pair<int,int> > Q;
pair <int,int> parNode;
//contains all the states
map < pair<int,int> ,int > occured;
//contains parent
map < pair<int,int>,pair<int,int> > parent;
Q.push(make_pair(0,0));
while(Q.empty()!=true){
parNode=Q.front();
Q.pop();
if(checkGoal(parNode,2))
break;
occured[parNode]++;
vector <pair<int,int> > leafs = newStatesSet(parNode);
for(int i=0;i<leafs.size();i++){
if(occured[leafs[i]]==0){
Q.push(leafs[i]);
parent[leafs[i]]=parNode;
}
}
}
reverseTraversal(parent,parNode,make_pair(0,0));
}
What do you think is wrong with this code, and how can it be improved? What corner case have I overlooked, if any? How can I make it less complicated?
Improvements based on suggestion can be found here