C#,图论与图算法,有向图单源最短路径的贝尔曼·福特(Bellman Ford)算法与源代码

C#,图论与图算法,有向图单源最短路径的贝尔曼·福特(Bellman Ford)算法与源代码_第1张图片

Richard Bellman

C#,图论与图算法,有向图单源最短路径的贝尔曼·福特(Bellman Ford)算法与源代码_第2张图片

  Lester Ford

一、贝尔曼·福特(Bellman Ford)算法概要

贝尔曼·福特(Bellman Ford)算法是一种用于计算带权有向图中单源最短路径(SSSP:Single-Source Shortest Path)的算法。该算法由 Richard Bellman 和 Lester Ford 分别发表于 1958 年和 1956 年,而实际上 Edward F. Moore 也在 1957 年发布了相同的算法,因此,此算法也常被称为 Bellman-Ford-Moore 算法。

Bellman-Ford 算法和 Dijkstra 算法同为解决单源最短路径的算法。对于带权有向图 G = (V, E),Dijkstra 算法要求图 G 中边的权值均为非负,而 Bellman-Ford 算法能适应一般的情况(即存在负权边的情况)。一个实现的很好的 Dijkstra 算法比 Bellman-Ford 算法的运行时间要低。

C#,图论与图算法,有向图单源最短路径的贝尔曼·福特(Bellman Ford)算法与源代码_第3张图片

 Edward F. Moore

二、Bellman-Ford 算法流程


(1)创建源顶点 v 到图中所有顶点的距离的集合 distSet,为图中的所有顶点指定一个距离值,初始均为 Infinite,源顶点距离为 0;
(2)计算最短路径,执行 V - 1 次遍历;
(3)对于图中的每条边:如果起点 u 的距离 d 加上边的权值 w 小于终点 v 的距离 d,则更新终点 v 的距离值 d;
(4)检测图中是否有负权边形成了环,遍历图中的所有边,计算 u 至 v 的距离,如果对于 v 存在更小的距离,则说明存在环;
 

源程序:

using System;
using System.Text;
using System.Collections;
using System.Collections.Generic;

namespace Legalsoft.Truffer.Algorithm
{
	public class GraphEdge
	{
		public int Source { get; set; } = 0;
		public int Destination { get; set; } = 0;
		public int Weight { get; set; } = 0;
		public GraphEdge()
		{
			Source = 0;
			Destination = 0;
			Weight = 0;
		}
		public GraphEdge(int s, int d, int w)
		{
			Source = s;
			Destination = d;
			Weight = w;
		}
	}

	public partial class Graph
	{
		public int Vertex_Number { get; set; } = 0;
		public int Edge_Number { get; set; } = 0;
		public GraphEdge[] Edges { get; set; } = null;

		public Graph(int v, int e)
		{
			Vertex_Number = v;
			Edge_Number = e;
			Edges = new GraphEdge[e];
			for (int i = 0; i < e; i++)
			{
				Edges[i] = new GraphEdge();
			}
		}

		/// 
		/// 按三元数组的构造函数
		/// 三元数组为: {source,destination,weight}
		/// 
		/// 
		public Graph(int[,] array)
		{
			List vn = new List();
			Edge_Number = array.GetLength(0);
			Edges = new GraphEdge[Edge_Number];
			for (int i = 0; i < Edge_Number; i++)
			{
				Edges[i] = new GraphEdge(array[i, 0], array[i, 1], array[i, 2]);
				if (!vn.Contains(array[i, 0])) vn.Add(array[i, 0]);
				if (!vn.Contains(array[i, 1])) vn.Add(array[i, 1]);
			}
			Vertex_Number = vn.Count;
		}

		public void Bellman_Ford(int src)
		{
			int[] dist = new int[Vertex_Number];

			for (int i = 0; i < Vertex_Number; i++)
			{
				dist[i] = int.MaxValue;
			}
			dist[src] = 0;

			for (int i = 1; i < Vertex_Number; i++)
			{
				for (int j = 0; j < Edge_Number; j++)
				{
					int u = Edges[j].Source;
					int v = Edges[j].Destination;
					int weight = Edges[j].Weight;
					if (dist[u] != int.MaxValue && (dist[u] + weight) < dist[v])
					{
						dist[v] = dist[u] + weight;
					}
				}
			}

			for (int j = 0; j < Edge_Number; j++)
			{
				int u = Edges[j].Source;
				int v = Edges[j].Destination;
				int weight = Edges[j].Weight;
				if (dist[u] != int.MaxValue && (dist[u] + weight) < dist[v])
				{
					return;
				}
			}
		}

		public static string Traversal(int[] dist, int src)
		{
			StringBuilder sb = new StringBuilder();
			sb.AppendLine("Vertex Distances from Source (" + src + ") is:
"); for (int i = 0; i < dist.Length; i++) { sb.AppendLine("Distance(" + i + "): " + dist[i] + "
"); } return sb.ToString(); } } }

————————————————————

POWER BY TRUFFER.CN

你可能感兴趣的:(C#算法演义,Algorithm,Recipes,算法,图论,最短路径算法,Bellman,Ford)