C# 一种星型搜索算法

C# 一种星型搜索算法,c#,algorithm,search,puzzle,a-star,C#,Algorithm,Search,Puzzle,A Star,这里我有一个关于a星搜索算法的查询。我正在制作所谓的8块拼图。 这是一个有9个位置(1个是空的)的游戏,你必须按照正确的顺序排列牌,以达到目标位置 我只需要验证我已经正确地编写了算法,这样我就可以在代码的其他地方寻找问题 我个人认为该算法是正确的,因为它能够解决我创建的第一个预设难题,它只需要一次移动即可到达目标位置。然而,它无法解决需要更多动作的难题 我试着用三种不同的方式来解决这个问题,但都带来了同样的问题 尝试1: while (openList.Count() > 0)

这里我有一个关于a星搜索算法的查询。我正在制作所谓的8块拼图。 这是一个有9个位置(1个是空的)的游戏,你必须按照正确的顺序排列牌,以达到目标位置

我只需要验证我已经正确地编写了算法,这样我就可以在代码的其他地方寻找问题

我个人认为该算法是正确的,因为它能够解决我创建的第一个预设难题,它只需要一次移动即可到达目标位置。然而,它无法解决需要更多动作的难题

我试着用三种不同的方式来解决这个问题,但都带来了同样的问题

尝试1:

while (openList.Count() > 0)
        {
            PuzzleNode currentNode;
            var orderedOpenList = openList.OrderBy(PuzzleNode => PuzzleNode.getPathCost());

            currentNode = orderedOpenList.First();
            if (compare(currentNode.getPuzzle(), goalArray) == true)
            {
                //openList.RemoveAt(0); //POLL
                break;
                // otherwise push currentNode onto closedList & remove from openList
            }
            else
            {
                openList.Remove(currentNode);
                closedList.Add(currentNode);
            }

            //generate all the neighbor nodes
            generateSuccessors(currentNode, tempList);

            for (int i = 0; i < tempList.Count(); i++)
            {
                PuzzleNode tempNode = tempList[i];

                //skip the node if it's in the closed list
                if (closedList.Contains(tempNode))
                {
                    continue;
                }//end if

                //We need to ensure that the G we have seen here is the shortest one
                int gScore = currentNode.getG() + 1;

                if (!openList.Contains(tempNode) || gScore < tempNode.getG())
                {
                    tempNode.setParentNode(currentNode);
                    tempNode.setH(tempNode.calcH(currentHueristic, tempNode.getPuzzle(), goalArray));
                    tempNode.setG(gScore);
                    tempNode.updatePathCost();

                    if (!openList.Contains(tempNode))
                    {
                        openList.Add(tempNode);
                    }//end if


                }//end if
            }//end for

        }//end while
while (openList.Count() > 0)
        {
            PuzzleNode currentNode = GetBestNodeFromOpenList(openList);

            openList.Remove(currentNode);
            closedList.Add(currentNode);

            generateSuccessors(currentNode, tempList);

            foreach (PuzzleNode successorNode in tempList)
            {
                if (compare(successorNode.getPuzzle(), goalArray) == true)
                {
                    //goto thebreak;
                    return successorNode;
                }
                successorNode.setG(currentNode.getG() + 1);
                successorNode.setH(successorNode.calcH(currentHueristic, successorNode.getPuzzle(), goalArray));
                successorNode.updatePathCost();


                if (OpenListHasBetterNode(successorNode, openList))
                    continue;

                openList.Add(successorNode);
            }
        }//end while

private static PuzzleNode GetBestNodeFromOpenList(IEnumerable<PuzzleNode> openList)
    {
        return openList.OrderBy(n => n.getPathCost()).First();
    }

private static bool OpenListHasBetterNode(PuzzleNode successor, IEnumerable<PuzzleNode> list)
    {
        return list.FirstOrDefault(n => n.getG().Equals(successor.getG())
                && n.getPathCost() < successor.getPathCost()) != null;
    }
while(openList.Count()>0)
{
当前节点;
var orderedOpenList=openList.OrderBy(puzzNode=>puzzNode.getPathCost());
currentNode=orderedOpenList.First();
if(比较(currentNode.getPuzzle(),goalArray)=true)
{
//openList.RemoveAt(0);//轮询
打破
//否则,将currentNode推到closedList并从openList中删除
}
其他的
{
移除(当前节点);
closedList.Add(当前节点);
}
//生成所有邻居节点
GenerateSuccessor(currentNode,tempList);
for(int i=0;i
尝试2:

while (openList.Count() > 0)
        {
            PuzzleNode currentNode;
            var orderedOpenList = openList.OrderBy(PuzzleNode => PuzzleNode.getPathCost());

            currentNode = orderedOpenList.First();
            if (compare(currentNode.getPuzzle(), goalArray) == true)
            {
                //openList.RemoveAt(0); //POLL
                break;
                // otherwise push currentNode onto closedList & remove from openList
            }
            else
            {
                openList.Remove(currentNode);
                closedList.Add(currentNode);
            }

            //generate all the neighbor nodes
            generateSuccessors(currentNode, tempList);

            for (int i = 0; i < tempList.Count(); i++)
            {
                PuzzleNode tempNode = tempList[i];

                //skip the node if it's in the closed list
                if (closedList.Contains(tempNode))
                {
                    continue;
                }//end if

                //We need to ensure that the G we have seen here is the shortest one
                int gScore = currentNode.getG() + 1;

                if (!openList.Contains(tempNode) || gScore < tempNode.getG())
                {
                    tempNode.setParentNode(currentNode);
                    tempNode.setH(tempNode.calcH(currentHueristic, tempNode.getPuzzle(), goalArray));
                    tempNode.setG(gScore);
                    tempNode.updatePathCost();

                    if (!openList.Contains(tempNode))
                    {
                        openList.Add(tempNode);
                    }//end if


                }//end if
            }//end for

        }//end while
while (openList.Count() > 0)
        {
            PuzzleNode currentNode = GetBestNodeFromOpenList(openList);

            openList.Remove(currentNode);
            closedList.Add(currentNode);

            generateSuccessors(currentNode, tempList);

            foreach (PuzzleNode successorNode in tempList)
            {
                if (compare(successorNode.getPuzzle(), goalArray) == true)
                {
                    //goto thebreak;
                    return successorNode;
                }
                successorNode.setG(currentNode.getG() + 1);
                successorNode.setH(successorNode.calcH(currentHueristic, successorNode.getPuzzle(), goalArray));
                successorNode.updatePathCost();


                if (OpenListHasBetterNode(successorNode, openList))
                    continue;

                openList.Add(successorNode);
            }
        }//end while

private static PuzzleNode GetBestNodeFromOpenList(IEnumerable<PuzzleNode> openList)
    {
        return openList.OrderBy(n => n.getPathCost()).First();
    }

private static bool OpenListHasBetterNode(PuzzleNode successor, IEnumerable<PuzzleNode> list)
    {
        return list.FirstOrDefault(n => n.getG().Equals(successor.getG())
                && n.getPathCost() < successor.getPathCost()) != null;
    }
while(openList.Count()>0)
{
PuzzleNode currentNode=GetBestNodeFromOpenList(openList);
移除(当前节点);
closedList.Add(当前节点);
GenerateSuccessor(currentNode,tempList);
foreach(模板列表中的PuzzleNode successorNode)
{
if(比较(successorNode.getPuzzle(),goalArray)=true)
{
//去休息;
返回成功节点;
}
successorNode.setG(currentNode.getG()+1);
setH(successorNode.calcH(currentHueristic,successorNode.getPuzzle(),goalArray));
successorNode.updatePathCost();
if(OpenListHasBetterNode(successorNode,openList))
继续;
openList.Add(successorNode);
}
}//结束时
私有静态拼图节点GetBestNodeFromOpenList(IEnumerable openList)
{
返回openList.OrderBy(n=>n.getPathCost()).First();
}
私有静态bool OpenListHasBetterNode(拼图节点继承者,IEnumerable列表)
{
return list.FirstOrDefault(n=>n.getG().Equals(succinator.getG())
&&n.getPathCost()<继任者.getPathCost())!=null;
}
尝试2是对我在互联网上找到的一个算法的修改:

然而,我尽力遵循维基百科上的伪代码:

function A*(start,goal)
     closedset := the empty set    // The set of nodes already evaluated.
     openset := {start}    // The set of tentative nodes to be evaluated, initially containing the start node
     came_from := the empty map    // The map of navigated nodes.

     g_score[start] := 0    // Cost from start along best known path.
     // Estimated total cost from start to goal through y.
     f_score[start] := g_score[start] + heuristic_cost_estimate(start, goal)

     while openset is not empty
         current := the node in openset having the lowest f_score[] value
         if current = goal
             return reconstruct_path(came_from, goal)

         remove current from openset
         add current to closedset
         for each neighbor in neighbor_nodes(current)
             tentative_g_score := g_score[current] + dist_between(current,neighbor)
             if neighbor in closedset
                 if tentative_g_score >= g_score[neighbor]
                     continue

             if neighbor not in openset or tentative_g_score < g_score[neighbor] 
                 came_from[neighbor] := current
                 g_score[neighbor] := tentative_g_score
                 f_score[neighbor] := g_score[neighbor] + heuristic_cost_estimate(neighbor, goal)
                 if neighbor not in openset
                     add neighbor to openset
功能A*(开始、目标)
closedset:=空集//已计算的节点集。
openset:={start}//要计算的暂定节点集,最初包含起始节点
来自:=空映射//已导航节点的映射。
g_分数[start]:=0//从开始沿最著名路径计算的成本。
//从开始到目标到y的估计总成本。
f_分数[开始]:=g_分数[开始]+启发式成本估算(开始,目标)
而openset不是空的
当前:=openset中具有最低f_分数[]值的节点
如果当前=目标
返回路径(来自,目标)
从openset中删除当前
将当前值添加到closedset
对于邻居_节点中的每个邻居(当前)
暂定分数:=g分数[当前]+之间的距离(当前,邻居)
如果近邻在closedset中
如果暂定评分>=g评分[邻居]
持续
如果邻居不在openset或暂定的_g_分数
我问你是否能找到一个问题,因为我不明白为什么它只适用于一个谜题。将这些谜题分开,是解决目标状态所需的移动量

我已经调试了几个小时,但我看不到它,我也看不到我的代码中还有什么地方可能有问题。所以我想我只是问,你觉得这对吗

任何问题请务必提问,我会尽可能提供更多信息!
提前谢谢你

注意:我使用的是CustomPriorityQueue类(由itowlson编写)