ZBLOG

用c#语言写一段完整代码解决A*算法实现八数码问题

下面是一个使用C#语言实现A*算法解决八数码问题的示例代码:

  1. using System;
  2. using System.Collections.Generic;
  3. class Node
  4. {
  5. public int[] state;
  6. public int cost;
  7. public int heuristic;
  8. public int depth;
  9. public Node parent;
  10. public Node(int[] s, int c, int h, int d, Node p)
  11. {
  12. state = s;
  13. cost = c;
  14. heuristic = h;
  15. depth = d;
  16. parent = p;
  17. }
  18. }
  19. class EightPuzzleSolver
  20. {
  21. private static readonly int[] goalState = { 1, 2, 3, 4, 5, 6, 7, 8, 0 };
  22. // 计算当前状态与目标状态的曼哈顿距离
  23. private static int CalculateManhattanDistance(int[] currentState)
  24. {
  25. int distance = 0;
  26. for (int i = 0; i < currentState.Length; i++)
  27. {
  28. if (currentState[i] != goalState[i])
  29. {
  30. distance += Math.Abs((currentState[i] % 3) - (goalState[i] % 3)) +
  31. Math.Abs((currentState[i] / 3) - (goalState[i] / 3));
  32. }
  33. }
  34. return distance;
  35. }
  36. // 检查是否为合法状态
  37. private static bool IsValidState(int[] state)
  38. {
  39. // 八数码问题中,空白位置用0表示
  40. // 检查数组中是否包含重复元素(除了空白位置)
  41. HashSet<int> set = new HashSet<int>(state);
  42. if (set.Count != state.Length || set.Contains(0))
  43. {
  44. return false;
  45. }
  46. return true;
  47. }
  48. // 查找数组中指定元素的索引
  49. private static int FindIndex(int[] array, int value)
  50. {
  51. for (int i = 0; i < array.Length; i++)
  52. {
  53. if (array[i] == value)
  54. {
  55. return i;
  56. }
  57. }
  58. return -1;
  59. }
  60. // 获取空白位置可以移动的方向
  61. private static List<int> GetValidMoves(int blankIndex)
  62. {
  63. List<int> validMoves = new List<int>();
  64. if (blankIndex >= 3) // 可以向上移动
  65. validMoves.Add(blankIndex - 3);
  66. if (blankIndex % 3 != 0) // 可以向左移动
  67. validMoves.Add(blankIndex - 1);
  68. if ((blankIndex + 1) % 3 != 0) // 可以向右移动
  69. validMoves.Add(blankIndex + 1);
  70. if (blankIndex < 6) // 可以向下移动
  71. validMoves.Add(blankIndex + 3);
  72. return validMoves;
  73. }
  74. public static void SolvePuzzle(int[] initialState)
  75. {
  76. if (!IsValidState(initialState))
  77. {
  78. Console.WriteLine("无效的初始状态");
  79. return;
  80. }
  81. PriorityQueue<Node> openList = new PriorityQueue<Node>();
  82. Node initialNode = new Node(initialState, 0, CalculateManhattanDistance(initialState), 0, null);
  83. openList.Enqueue(initialNode, initialNode.cost + initialNode.heuristic);
  84. HashSet<string> visitedStates = new HashSet<string>();
  85. while (!openList.IsEmpty())
  86. {
  87. Node current = openList.Dequeue();
  88. visitedStates.Add(string.Join(",", current.state));
  89. if (current.state.Equals(goalState))
  90. {
  91. Console.WriteLine("找到解决方案!");
  92. // 输出解决路径
  93. List<Node> path = new List<Node>();
  94. Node node = current;
  95. while (node != null)
  96. {
  97. path.Insert(0, node);
  98. node = node.parent;
  99. }
  100. foreach (Node n in path)
  101. {
  102. PrintPuzzle(n.state);
  103. Console.WriteLine();
  104. Console.WriteLine("移动成本: " + n.cost);
  105. Console.WriteLine("启发式值: " + n.heuristic);
  106. Console.WriteLine("----------------------");
  107. }
  108. return;
  109. }
  110. int blankIndex = FindIndex(current.state, 0);
  111. List<int> validMoves = GetValidMoves(blankIndex);
  112. foreach (int move in validMoves)
  113. {
  114. int[] newState = (int[])current.state.Clone();
  115. // 交换空白位置与移动方向上的数字
  116. int temp = newState[move];
  117. newState[move] = 0;
  118. newState[blankIndex] = temp;
  119. if (!visitedStates.Contains(string.Join(",", newState)))
  120. {
  121. Node newNode = new Node(newState, current.cost + 1,
  122. CalculateManhattanDistance(newState),
  123. current.depth + 1,
  124. current);
  125. openList.Enqueue(newNode, newNode.cost + newNode.heuristic);
  126. visitedStates.Add(string.Join(",", newState));
  127. }
  128. }
  129. }
  130. Console.WriteLine("无法找到解决方案");
  131. }
  132. private static void PrintPuzzle(int[] state)
  133. {
  134. for (int i = 0; i < state.Length; i++)
  135. {
  136. if (state[i] == 0)
  137. Console.Write("_ ");
  138. else
  139. Console.Write(state[i] + " ");
  140. if ((i + 1) % 3 == 0)
  141. Console.WriteLine();
  142. }
  143. }
  144. static void Main(string[] args)
  145. {
  146. int[] initialState = { 1, 2, 3, 4, 5, 6, 8, 7, 0 };
  147. SolvePuzzle(initialState);
  148. }
  149. }

该代码实现了一个八数码问题的求解器,使用A*算法和曼哈顿距离作为启发式函数进行搜索。你可以根据需要自行调整初始状态,并运行该代码以获取解决方案。


内容由零声教学AI助手提供,问题来源于学员提问

本站部分文章来源于网络,版权归原作者所有,如有侵权请联系站长删除。
转载请注明出处:https://golang.0voice.com/?id=10034

分享:
扫描分享到社交APP
上一篇
下一篇
发表列表
游客 游客
此处应有掌声~
评论列表

还没有评论,快来说点什么吧~

联系我们

在线咨询: 点击这里给我发消息

微信号:3007537140

上班时间: 10:30-22:30

关注我们
x

注册

已经有帐号?