【发布时间】:2015-10-12 18:50:07
【问题描述】:
所以我被分配了以下任务:假设 5x5 版本的游戏中的所有灯都已打开,请使用 UCS / A* / BFS / Greedy best first search 编写一个找到解决方案的算法。
我首先意识到 UCS 是不必要的,因为从一个状态移动到另一个状态的成本是 1(按下一个可以翻转自身和相邻状态的按钮)。所以我所做的就是写 BFS。事实证明,它的工作时间太长并填满了一个队列,即使我在完成父节点时注意删除父节点,以免内存溢出。它会工作大约 5-6 分钟,然后因为内存而崩溃。 接下来,我所做的是编写 DFS(尽管没有提到它是一种可能性),它确实在 123 秒内找到了解决方案,深度为 15(我使用了深度优先限制,因为我知道深度有解决方案15).
我现在想知道的是我错过了什么吗?是否有一些好的启发式方法可以尝试使用 A* 搜索来解决这个问题?当涉及到启发式算法时,我一无所获,因为在这个问题中找到一个似乎并不容易。
非常感谢。期待大家的帮助
这是我的源代码(我认为它很容易理解):
struct state
{
bool board[25];
bool clicked[25];
int cost;
int h;
struct state* from;
};
int visited[1<<25];
int dx[5] = {0, 5, -5};
int MAX_DEPTH = 1<<30;
bool found=false;
struct state* MakeStartState()
{
struct state* noviCvor = new struct state();
for(int i = 0; i < 25; i++) noviCvor->board[i] = false, noviCvor->clicked[i] = false;
noviCvor->cost = 0;
//h=...
noviCvor->from = NULL;
return noviCvor;
};
struct state* MakeNextState(struct state* temp, int press_pos)
{
struct state* noviCvor = new struct state();
for(int i = 0; i < 25; i++) noviCvor->board[i] = temp->board[i], noviCvor->clicked[i] = temp->clicked[i];
noviCvor->clicked[press_pos] = true;
noviCvor->cost = temp->cost + 1;
//h=...
noviCvor->from = temp;
int temp_pos;
for(int k = 0; k < 3; k++)
{
temp_pos = press_pos + dx[k];
if(temp_pos >= 0 && temp_pos < 25)
{
noviCvor->board[temp_pos] = !noviCvor->board[temp_pos];
}
}
if( ((press_pos+1) % 5 != 0) && (press_pos+1) < 25 )
noviCvor->board[press_pos+1] = !noviCvor->board[press_pos+1];
if( (press_pos % 5 != 0) && (press_pos-1) >= 0 )
noviCvor->board[press_pos-1] = !noviCvor->board[press_pos-1];
return noviCvor;
};
bool CheckFinalState(struct state* temp)
{
for(int i = 0; i < 25; i++)
{
if(!temp->board[i]) return false;
}
return true;
}
int bijection_mapping(struct state* temp)
{
int temp_pow = 1;
int mapping = 0;
for(int i = 0; i < 25; i++)
{
if(temp->board[i])
mapping+=temp_pow;
temp_pow*=2;
}
return mapping;
}
void BFS()
{
queue<struct state*> Q;
struct state* start = MakeStartState();
Q.push(start);
struct state* temp;
visited[ bijection_mapping(start) ] = 1;
while(!Q.empty())
{
temp = Q.front();
Q.pop();
visited[ bijection_mapping(temp) ] = 2;
for(int i = 0; i < 25; i++)
{
if(!temp->clicked[i])
{
struct state* next = MakeNextState(temp, i);
int mapa = bijection_mapping(next);
if(visited[ mapa ] == 0)
{
if(CheckFinalState(next))
{
printf("NADJENO RESENJE\n");
exit(0);
}
visited[ mapa ] = 1;
Q.push(next);
}
}
}
delete temp;
}
}
附言。由于我不再使用地图(切换到数组)来访问状态,我的 DFS 解决方案从 123 秒提高到 54 秒,但 BFS 仍然崩溃。
【问题讨论】:
标签: artificial-intelligence dijkstra depth-first-search a-star