C#迪杰斯特拉算法##

网上有许多版本的,自己还是写一个理解点

Dijkstra.cs

public class Dijkstra
{
private List<Node> _nodes;
private List<Edge> _edges; public Dijkstra()
{
_nodes = new List<Node>();
_edges = new List<Edge>();
} public void InitWeights(List<Tuple<string, string, double>> weights)
{
_edges = ConvertToEdge(weights); InitNodes();
} public List<string> Find(string start, string end)
{
var startNode = GetNodeByName(start);
var endNode = GetNodeByName(end); if (startNode == null || endNode == null)
{
return new List<string>();
} var s = _nodes.Where(x => x.Name == start).ToList();
var u = _nodes.Where(x => x.Name != start).ToList(); s.ForEach(x =>
{
x.Weight = 0;
}); u.ForEach(x =>
{
x.Weight = double.PositiveInfinity;
}); while (u.Any())
{
var node = s.Last(); //更新node到x的距离
u.ForEach(x =>
{
var edge = GetEdgeByTwoNode(node, x); if (edge != null)
{
var weights = node.GetAllWeight() + edge.Weight; if (weights < x.Weight)
{
x.Weight = weights;
x.Parent = node;
}
}
}); //找出距离最小的
var minNode = u.OrderBy(x => x.Weight).FirstOrDefault(); s.Add(minNode);
u.Remove(minNode);
} var paths = new Stack<string>(); while (endNode != null)
{
paths.Push(endNode.Name);
endNode = endNode.Parent;
} //如果路劲中包含起点
if (paths.ToList().Contains(start))
{
return paths.ToList();
}
else
{
return new List<string>();
}
} private Edge GetEdgeByTwoNode(Node start, Node end)
{
var edge = _edges.FirstOrDefault(x => x.Start == start.Name && x.End == end.Name); if (edge == null)
{
edge = _edges.FirstOrDefault(x => x.Start == end.Name && x.End == start.Name);
} return edge;
} /// <summary>
/// 将权值转换成边
/// </summary>
/// <returns></returns>
private List<Edge> ConvertToEdge(List<Tuple<string, string, double>> weights)
{
var edges = new List<Edge>(); weights.ForEach(weight =>
{
edges.Add(new Edge()
{
Start = weight.Item1,
End = weight.Item2,
Weight = weight.Item3
});
}); return edges;
} /// <summary>
/// 根据名字获取节点
/// </summary>
/// <param name="nodeName"></param>
/// <returns></returns>
private Node GetNodeByName(string nodeName)
{
return _nodes.FirstOrDefault(x => x.Name == nodeName);
} /// <summary>
/// 初始化点
/// </summary>
private void InitNodes()
{
_edges.ForEach(weight =>
{
if (_nodes.All(x => x.Name != weight.Start))
{
_nodes.Add(new Node()
{
Name = weight.Start
});
} if (_nodes.All(x => x.Name != weight.End))
{
_nodes.Add(new Node()
{
Name = weight.End
});
}
});
}
}

Edge.cs

//表示一条边,从Start到End的权值为多少
internal class Edge
{
public string Start
{
get; set;
} public string End
{
get; set;
} public double Weight
{
get; set;
}
}

Node.cs

internal class Node
{
public string Name
{
get; set;
} public Node Parent
{
get; set;
} /// <summary>
/// 该节点到起点的最短距离
/// </summary>
public double Weight
{
get; set;
} public double GetAllWeight()
{
var allWeight = 0d; var node = this; do
{
allWeight += node.Weight; node = node.Parent; } while (node != null); return allWeight;
}
}

使用如下

static void Main(string[] args)
{
var weights = new List<Tuple<string, string, double>>()
{
new Tuple<string,string,double>("A","B",12),
new Tuple<string,string,double>("A","F",16),
new Tuple<string,string,double>("A","G",14),
new Tuple<string,string,double>("B","F",7),
new Tuple<string,string,double>("B","C",10),
new Tuple<string,string,double>("G","F",9),
new Tuple<string,string,double>("G","E",8),
new Tuple<string,string,double>("F","C",6),
new Tuple<string,string,double>("F","E",2),
new Tuple<string,string,double>("C","D",3),
new Tuple<string,string,double>("C","E",5),
new Tuple<string,string,double>("E","D",4),
}; var dij = new Dijkstra(); dij.InitWeights(weights); var path = dij.Find("D", "G"); path.ForEach(Console.WriteLine);
}

C#迪杰斯特拉算法的更多相关文章

  1. C++迪杰斯特拉算法求最短路径

    一:算法历史 迪杰斯特拉算法是由荷兰计算机科学家狄克斯特拉于1959 年提出的,因此又叫狄克斯特拉算法.是从一个顶点到其余各顶点的最短路径算法,解决的是有向图中最短路径问题.迪杰斯特拉算法主要特点是以 ...

  2. 【算法杂谈】LJX的迪杰斯特拉算法报告

    迪杰斯特拉(di jie qi)算法 这里有一张图: 假设要求从1号节点到5号节点的最短路.那么根据迪杰斯特拉算法的思想,我们先看: 节点1,从节点1出发的一共有3条路,分别是1-6.1-3.1-2. ...

  3. C# 迪杰斯特拉算法 Dijkstra

    什么也不想说,现在直接上封装的方法: using System; using System.Collections.Concurrent; using System.Collections.Gener ...

  4. 迪杰斯特拉算法——PAT 1003

    本文主要是将我对于我对于迪杰斯特拉算法的理解写出来,同时通过例题来希望能够加深对于算法的理解,其中有错误的地方希望大家指正. 迪杰斯特拉算法 我将这个算法理解成一个局部到整体的算法,这个方法确实越研究 ...

  5. dijkstra算法(迪杰斯特拉算法)

    dijkstra算法(迪杰斯特拉算法) 用途:有向图最短路径问题 定义:迪杰斯特拉算法是典型的算法,一般的表述通常有两种方式,这里均采用永久和临时标号的方式,该算法要求图中不存在负权边 用永久和临时标 ...

  6. 迪杰斯特拉算法c语言实现

    /*http://1wangxiaobo@163.com 数据结构C语言版 迪杰斯特拉算法  P189 http://1wangxiaobo@163.com 编译环境:Dev-C++ 4.9.9.2  ...

  7. HDU6166-Senior Pan-Dijkstra迪杰斯特拉算法(添加超源点,超汇点)+二进制划分集合-2017多校Team09

    学长好久之前讲的,本来好久好久之前就要写题解的,一直都没写,懒死_(:з」∠)_ Senior Pan Time Limit: 12000/6000 MS (Java/Others)    Memor ...

  8. Dijkstra【迪杰斯特拉算法】

    有关最短路径的最后一个算法——Dijkstra 迪杰斯特拉算法是由荷兰计算机科学家迪杰斯特拉于1959 年提出的,因此又叫迪杰斯特拉算法.是从一个顶点到其余各顶点的最短路径算法,解决的是有权图中最短路 ...

  9. 算法与数据结构(六) 迪杰斯特拉算法的最短路径(Swift版)

    上篇博客我们详细的介绍了两种经典的最小生成树的算法,本篇博客我们就来详细的讲一下最短路径的经典算法----迪杰斯特拉算法.首先我们先聊一下什么是最短路径,这个还是比较好理解的.比如我要从北京到济南,而 ...

随机推荐

  1. 消息队列——RabbitMQ学习笔记

    消息队列--RabbitMQ学习笔记 1. 写在前面 昨天简单学习了一个消息队列项目--RabbitMQ,今天趁热打铁,将学到的东西记录下来. 学习的资料主要是官网给出的6个基本的消息发送/接收模型, ...

  2. MySQL高级知识- MySQL的架构介绍

    [TOC] 1.MySQL 简介 概述 MySQL是一个关系型数据库管理系统,由瑞典MySQL AB公司开发,目前属于Oracle公司. MySQL是一种关联数据库管理系统,将数据保存在不同的表中,而 ...

  3. 【社工】NodeJS 应用仓库钓鱼

    前言 城堡总是从内部攻破的.再强大的系统,也得通过人来控制.如果将入侵直接从人这个环节发起,那么再坚固的防线,也都成为摆设. 下面分享一个例子,利用应用仓库,渗透到开发人员的系统中. 应用仓库 应用仓 ...

  4. “四核”驱动的“三维”导航 -- 淘宝新UI(需求分析篇)

    前言 孔子说:"软件是对客观世界的抽象". 首先声明,这里的"三维导航"和地图没一毛钱关系,"四核驱动"和硬件也没关系,而是为了复杂的应用而 ...

  5. Kooboo CMS技术文档之五:站点配置管理

    站点关系 管理站点间的关系,站点可以有子站点,子站点继承父站点的部分配置数据,同时子站点还可以根据需要,本地化由父站点继承而来的数据.通过继承和本地化,可以让子站点在用最小的改动代价,来完成一个与父站 ...

  6. JS判断鼠标进入容器方向的方法和分析window.open新窗口被拦截的问题

    1.鼠标进入容器方向的判定 判断鼠标从哪个方向进入元素容器是一个经常碰到的问题,如何来判断呢?首先想到的是:获取鼠标的位置,然后经过一大堆的if..else逻辑来确定.这样的做法比较繁琐,下面介绍两种 ...

  7. Hawk 6. 高级话题:子流程系统

    子流程的定义 当流程设计的越来越复杂,越来越长时,就难以进行管理了.因此,采用模块化的设计才会更加合理.本节我们介绍子流程的原理和使用. 所谓子流程,就是能先构造出一个流程,然后被其他流程调用.被调用 ...

  8. Spring(三)__aop编程

    aop( aspect oriented programming ) 面向切面编程,是对所有对象或者是一类对象编程 几个重要的概念: 1.切面(aspect):要实现的交叉功能,是系统模块化的一个切面 ...

  9. 在 SharePoint Server 2016 本地环境中设置 OneDrive for Business

    建议补丁 建议在sharepoint2016打上KB3127940补丁,补丁下载地址 https://support.microsoft.com/zh-cn/kb/3127940 当然不打,也可以用O ...

  10. hbase协处理器编码实例

    Observer协处理器通常在一个特定的事件(诸如Get或Put)之前或之后发生,相当于RDBMS中的触发器.Endpoint协处理器则类似于RDBMS中的存储过程,因为它可以让你在RegionSer ...