这是我编写的一个示例,似乎可以工作。为了更高效,当搜索下一个最短距离节点时,您需要实现一个最小堆。
private static int FindMin(int[,] indexWeights, Tuple<int, int> src, Tuple<int, int> dst)
{
List<Node> allNodes = new List<Node>(indexWeights.GetLength(0)*indexWeights.GetLength(1));
Node[,] graph = GenerateGraph(indexWeights, allNodes);
Queue<Node> queue = new Queue<Node>();
Node currentNode = graph[src.Item1, src.Item2];
currentNode.Distance = indexWeights[src.Item1, src.Item2];
queue.Enqueue(currentNode);
while (queue.Count > 0)
{
currentNode = queue.Dequeue();
currentNode.Visited = true;
if (currentNode.XCoord == dst.Item1 && currentNode.YCoord == dst.Item2)
break;
foreach (Node neighbor in currentNode.Neighbors)
{
neighbor.Distance = Math.Min(neighbor.Distance,
currentNode.Distance + indexWeights[neighbor.XCoord, neighbor.YCoord]);
}
Node nonVisitedMinNode = allNodes.Where(a => !a.Visited)
.Aggregate((currMin, currNode) => currMin.Distance < currNode.Distance ? currMin : currNode);
queue.Enqueue(nonVisitedMinNode);
}
return graph[dst.Item1, dst.Item2].Distance;
}
public class Node
{
public Node(int xCoord, int yCoord)
{
XCoord = xCoord;
YCoord = yCoord;
Distance = int.MaxValue;
Visited = false;
Neighbors = new List<Node>();
}
public int XCoord { get; set; }
public int YCoord { get; set; }
public int Distance { get; set; }
public bool Visited { get; set; }
public List<Node> Neighbors { get; set; }
}
public static Node[,] GenerateGraph(int[,] weight, List<Node> allNodes)
{
Node[,] nodes = new Node[weight.GetLength(0),weight.GetLength(1)];
for (int i = 0; i < weight.GetLength(0); i++)
{
for (int j = 0; j < weight.GetLength(1); j++)
{
nodes[i, j] = new Node(i, j);
allNodes.Add(nodes[i, j]);
}
}
for (int i = 0; i < weight.GetLength(0); i++)
{
for (int j = 0; j < weight.GetLength(1); j++)
{
if (0 <= (i - 1))
nodes[i, j].Neighbors.Add(nodes[i - 1, j]);
if (weight.GetLength(0) > (i + 1))
nodes[i, j].Neighbors.Add(nodes[i + 1, j]);
if (0 <= (j - 1))
nodes[i, j].Neighbors.Add(nodes[i, j - 1]);
if (weight.GetLength(1) > (j + 1))
nodes[i, j].Neighbors.Add(nodes[i, j + 1]);
}
}
return nodes;
}
我无法想到一个不笨重的方法来生成图表...也许现在太晚了。无论如何,根据我们在评论中讨论的内容,您可能需要调整currentNode.Distance的初始化。[0,0] 在您的示例中是否为0是因为它是起始索引,还是因为该值开始时为0?如果您提供另一个示例,其中起始索引没有值为0,则更容易理解规则。