广度优先算法代码示例

简介: 广度优先算法代码示例

广度优先算法代码示例:

using System;
using System.Collections.Generic;
public class DijkstraAlgorithm
{
    // Dijkstra算法主要逻辑
    public static void Dijkstra(Dictionary<int, List<Edge>> graph, int startNode, int endNode)
    {
        // 存储节点到起点的距离
        Dictionary<int, int> distances = new Dictionary<int, int>();
        // 存储节点的父节点,用于构建最短路径
        Dictionary<int, int> parents = new Dictionary<int, int>();
        // 优先队列,用于按照节点距离从小到大的顺序处理
        PriorityQueue priorityQueue = new PriorityQueue();
        // 初始化distances和parents字典
        foreach (int node in graph.Keys)
        {
            distances[node] = int.MaxValue; // 将所有节点的距离初始化为无穷大
            parents[node] = -1; // 将所有节点的父节点初始化为-1
        }
        distances[startNode] = 0; // 将起始节点的距离设置为0
        priorityQueue.Enqueue(new Node(startNode, 0)); // 将起始节点加入优先队列
        // 开始执行Dijkstra算法
        while (priorityQueue.Count > 0) // 当优先队列不为空时
        {
            Node currentNode = priorityQueue.Dequeue();
            
            // 如果当前节点的距离值大于distances中对应节点的距离值,说明当前节点已经被处理过,直接跳过
            if (currentNode.Value > distances[currentNode.Vertex])
                continue;
            // 对当前节点的所有相邻边进行遍历
            foreach (Edge edge in graph[currentNode.Vertex])
            {
                // 计算从起始节点经过当前节点到目标节点的新距离
                int newDistance = distances[currentNode.Vertex] + edge.Weight;
                // 如果新距离小于distances中对应节点的距离值
                if (newDistance < distances[edge.Destination])
                {
                    distances[edge.Destination] = newDistance; // 更新目标节点的距离值
                    parents[edge.Destination] = currentNode.Vertex; // 更新目标节点的父节点
                    priorityQueue.Enqueue(new Node(edge.Destination, newDistance)); // 将目标节点加入优先队列
                }
            }
        }
        // 判断是否存在从起点到终点的路径
        if (distances[endNode] == int.MaxValue)
        {
            Console.WriteLine("There is no path from startNode to endNode.");
        }
        else
        {
            // 获取最短路径
            List<int> shortestPath = GetShortestPath(parents, startNode, endNode);
            Console.WriteLine($"Shortest distance from {startNode} to {endNode}: {distances[endNode]}");
            Console.WriteLine("Shortest path: " + string.Join(" -> ", shortestPath));
        }
    }
    // 构建最短路径
    public static List<int> GetShortestPath(Dictionary<int, int> parents, int startNode, int endNode)
    {
        List<int> path = new List<int>();
        int currentNode = endNode;
        while (currentNode != -1)
        {
            path.Insert(0, currentNode); // 将节点插入到路径列表的开头
            currentNode = parents[currentNode]; // 更新当前节点为父节点
        }
        return path;
    }
    public static void Main(string[] args)
    {
        Dictionary<int, List<Edge>> graph = new Dictionary<int, List<Edge>>();
        // 创建图形
        // 每个键表示一个节点,每个值表示与该节点相连的所有边
        graph[0] = new List<Edge>
        {
            new Edge(1, 2),
            new Edge(2, 5),
            new Edge(3, 9)
        };
        graph[1] = new List<Edge>
        {
            new Edge(4, 12)
        };
        graph[2] = new List<Edge>
        {
            new Edge(4, 5),
            new Edge(5, 6)
        };
        graph[3] = new List<Edge>
        {
            new Edge(5, 10)
        };
        graph[4] = new List<Edge>
        {
            new Edge(6, 6)
        };
        graph[5] = new List<Edge>
        {
            new Edge(6, 5),
            new Edge(7, 4)
        };
        graph[6] = new List<Edge>
        {
            new Edge(8, 8)
        };
        graph[7] = new List<Edge>
        {
            new Edge(8, 5),
            new Edge(9, 7)
        };
        graph[8] = new List<Edge>
        {
            new Edge(9, 8)
        };
        graph[9] = new List<Edge>();
        int startNode = 0;
        int endNode = 9;
        // 执行Dijkstra算法
        Dijkstra(graph, startNode, endNode);
    }
}
// 边类,表示节点之间的连接关系
public class Edge
{
    public int Destination { get; } // 目标节点
    public int Weight { get; } // 边的权重
    public Edge(int destination, int weight)
    {
        Destination = destination;
        Weight = weight;
    }
}
// 节点类,包含节点编号和距离值
public class Node
{
    public int Vertex { get; } // 节点编号
    public int Value { get; } // 节点距离值
    public Node(int vertex, int value)
    {
        Vertex = vertex;
        Value = value;
    }
}
// 优先队列类,用于保存节点,并确保按照节点的距离值从小到大排序
public class PriorityQueue
{
    private List<Node> heap; // 存放节点的列表
    public int Count => heap.Count;
    public PriorityQueue()
    {
        heap = new List<Node>();
    }
    // 入队操作,将节点加入优先队列并保持有序
    public void Enqueue(Node item)
    {
        heap.Add(item);
        int currentIndex = heap.Count - 1;
        while (currentIndex > 0)
        {
            int parentIndex = (currentIndex - 1) / 2;
            if (heap[currentIndex].Value >= heap[parentIndex].Value)
                break;
            Swap(currentIndex, parentIndex);
            currentIndex = parentIndex;
        }
    }
    // 出队操作,取出距离值最小的节点
    public Node Dequeue()
    {
        if (Count == 0)
            throw new InvalidOperationException("PriorityQueue is empty.");
        Node item = heap[0];
        heap[0] = heap[Count - 1];
        heap.RemoveAt(Count - 1);
        int currentIndex = 0;
        while (currentIndex < Count)
        {
            int leftChildIndex = 2 * currentIndex + 1;
            int rightChildIndex = 2 * currentIndex + 2;
            if (leftChildIndex >= Count)
                break;
            int smallerChildIndex = leftChildIndex;
            if (rightChildIndex < Count && heap[rightChildIndex].Value < heap[leftChildIndex].Value)
                smallerChildIndex = rightChildIndex;
            if (heap[currentIndex].Value <= heap[smallerChildIndex].Value)
                break;
            Swap(currentIndex, smallerChildIndex);
            currentIndex = smallerChildIndex;
        }
        return item;
    }
    // 交换两个位置的节点
    private void Swap(int index1, int index2)
    {
        Node temp = heap[index1];
        heap[index1] = heap[index2];
        heap[index2] = temp;
    }
}

注释很详细!

相关文章
|
6天前
|
存储 算法 大数据
Python算法高手的必修课:深入理解分治法、贪心算法、动态规划,让你的代码更智能!
【7月更文挑战第9天】在Python算法学习中,分治法(如归并排序)将大问题分解为小部分递归解决;贪心算法(如货币找零)在每步选择局部最优解尝试达到全局最优;动态规划(如斐波那契数列)通过存储子问题解避免重复计算,解决重叠子问题。掌握这三种方法能提升代码效率,解决复杂问题。
|
9天前
|
算法 JavaScript
JS 【详解】树的遍历(含深度优先遍历和广度优先遍历的算法实现)
JS 【详解】树的遍历(含深度优先遍历和广度优先遍历的算法实现)
13 0
JS 【详解】树的遍历(含深度优先遍历和广度优先遍历的算法实现)
|
13天前
|
算法 PHP
【php经典算法】冒泡排序,冒泡排序原理,冒泡排序执行逻辑,执行过程,执行结果 代码
【php经典算法】冒泡排序,冒泡排序原理,冒泡排序执行逻辑,执行过程,执行结果 代码
12 1
|
20天前
|
机器学习/深度学习 算法 数据挖掘
Python机器学习10大经典算法的讲解和示例
为了展示10个经典的机器学习算法的最简例子,我将为每个算法编写一个小的示例代码。这些算法将包括线性回归、逻辑回归、K-最近邻(KNN)、支持向量机(SVM)、决策树、随机森林、朴素贝叶斯、K-均值聚类、主成分分析(PCA)、和梯度提升(Gradient Boosting)。我将使用常见的机器学习库,如 scikit-learn,numpy 和 pandas 来实现这些算法。
|
20天前
|
人工智能 算法 Java
java中经典算法代码整理
java中经典算法代码整理
20 0
|
1天前
|
算法 数据安全/隐私保护
基于GA遗传优化算法的Okumura-Hata信道参数估计算法matlab仿真
在MATLAB 2022a中应用遗传算法进行无线通信优化,无水印仿真展示了算法性能。遗传算法源于Holland的理论,用于全局优化,常见于参数估计,如Okumura-Hata模型的传播损耗参数。该模型适用于150 MHz至1500 MHz的频段。算法流程包括选择、交叉、变异等步骤。MATLAB代码执行迭代,计算目标值,更新种群,并计算均方根误差(RMSE)以评估拟合质量。最终结果比较了优化前后的RMSE并显示了SNR估计值。
15 7
|
3天前
|
算法 数据挖掘
MATLAB数据分析、从算法到实现
MATLAB数据分析、从算法到实现
|
10天前
|
机器学习/深度学习 算法 调度
Matlab|基于改进鲸鱼优化算法的微网系统能量优化管理matlab-源码
基于改进鲸鱼优化算法的微网系统能量管理源码实现,结合LSTM预测可再生能源和负荷,优化微网运行成本与固定成本。方法应用于冷热电联供微网,结果显示经济成本平均降低4.03%,提高经济效益。代码包括数据分段、LSTM网络定义及训练,最终展示了一系列运行结果图表。
|
10天前
|
算法
基于Dijkstra算法的最优行驶路线搜索matlab仿真,以实际城市复杂路线为例进行测试
使用MATLAB2022a实现的Dijkstra算法在城市地图上搜索最优行驶路线的仿真。用户通过鼠标点击设定起点和终点,算法规划路径并显示长度。测试显示,尽管在某些复杂情况下计算路径可能与实际有偏差,但多数场景下Dijkstra算法能找到接近最短路径。核心代码包括图的显示、用户交互及Dijkstra算法实现。算法基于图论,不断更新未访问节点的最短路径。测试结果证明其在简单路线及多数复杂城市路况下表现良好,但在交通拥堵等特殊情况下需结合其他数据提升准确性。
|
15天前
|
算法 安全 数据库
基于结点电压法的配电网状态估计算法matlab仿真
**摘要** 该程序实现了基于结点电压法的配电网状态估计算法,旨在提升数据的准确性和可靠性。在MATLAB2022a中运行,显示了状态估计过程中的电压和相位估计值,以及误差随迭代变化的图表。算法通过迭代计算雅可比矩阵,结合基尔霍夫定律解决线性方程组,估算网络节点电压。状态估计过程中应用了高斯-牛顿或莱文贝格-马夸尔特法,处理量测数据并考虑约束条件,以提高估计精度。程序结果以图形形式展示电压幅值和角度估计的比较,以及估计误差的演变,体现了算法在处理配电网状态估计问题的有效性。