省市县三级联动问题相信大家都耳熟能详了,选择市下拉选项依赖于省,同样的选择县下拉选项依赖于市。把省市县抽象成三个节点A(省),B(市),C(县),它们的关系如下图(1)。假如把这个联动问题复杂化一点如图(2)所示,现在随便改变一个节点的值,其余节点的值会发生什么变化,你还能直接说出来吗?这个问题就是本篇将要介绍的动态联动问题。

阅读目录

  • 动态联动问题分析
  • 问题转化
  • 最短路径算法实现
  • 总结
回到顶部

动态联动问题分析

  动态联动相对于普通的联动体现在关系事先不可知,省市县联动改变什么相应联动什么都是事先知道的,所以代码实现是相对很简单的。前台写三个Select标签,每个Select标签绑定onchange事件实现相应的逻辑。

    <div><select id="selProvince" onchange="changeCity()"><option></option></select><select id="selCity" onchange="changeArea()"><option></option></select><select id="selArea"><option></option></select></div><script>function changeCity() {var Province = $("#selProvince").val();//取数,取出该省对应的市var data = getData(Province);//绑定选择城市下拉选择项
            bindCity(data);//清空县下拉选择项和值
            clearArea();}function changeArea() {var City = $("#selCity").val();//取数,取出该市对应的县var data = getData(City);//绑定选择县下拉选择项
            bindArea(data);}</script>

上面的两个函数代码是类似的,总结一下会发现以下步骤:

 1.获取当前改变项的值(省)

2.找出其直接影响的项(市),从后台获取对应数据,进行绑定。

3.找出其间接影响的项(县),将其下拉选择项清空,值清空

动态联动问题的难点在于第二步第三步,怎么找当前改变项的直接影响节点和间接影响节点。

回到顶部

问题转化

我们用图来描述联动,上图2中改变A节点的值,哪些是直接影响节点和间接影响节点呢。直接节点:B,间接节点C F。这里可能存在一个疑惑点C节点为什也算是间接节点呢,它不是也可以直接由A->C吗。从实际应用来考虑,从A节点到C节点有两条路径A->C,A->B->C。也就是说C是依赖于A,B两个节点的,改变了A的值,我们可以获取到B的下拉选项的值,注意了这个时候用户是没有选择B的值的,也是就说B是空的,所以是算不出来C的下拉选项的值的。不明白的可以从省市县联动来考虑,改变了省是求不出来县的值的,只能求出市。到这里可以给上面说了很多次的直接影响节点和间接影响节点下定义了

直接影响节点:改变节点到该节点不存在中转节点

    间接影响节点:改变节点到该节点存在中转节点

    无影响节点   :改变节点不能到达的节点

定义图的边路径长度为1,上面三种节点的定义可以改为

直接影响节点:最远距离=1

    间接影响节点:最远距离>1

    无影响节点   :最远距离 =无穷大

回到顶部

最短路径算法实现

经过分析我们把动态联动问题转换成了最远路径问题,这个时候解决方案就很明确了,图的最短路径算法(最远路径可以先把路径值变成相反值,再求最短路径)。当然要求最短路径就得要求图是无闭环的,如何判断图存在闭环可以参考我的另一篇文章拓扑排序及其实际应用。

最短路径算法经典的有Dijkstra and Floyd算法,Dijkstra算法适合求单个节点到其它节点的最短路径问题,Floyd算法适合求每个节点到其它节点最短路径问题。

Floyd算法的基本思想如下:从任意节点A到任意节点B的最短路径不外乎2种可能,1是直接从A到B,2是从A经过若干个节点到B,所以,我们假设dist(AB)为节点A到节点B的最短路径的距离,对于每一个节点K,我们检查dist(AK) + dist(KB) < dist(AB)是否成立,如果成立,证明从A到K再到B的路径比A直接到B的路径短,我们便设置 dist(AB) = dist(AK) + dist(KB),这样一来,当我们遍历完所有节点K,dist(AB)中记录的便是A到B的最短路径的距离。

上图的邻接矩阵表示方法:

代码实现

static int M = 6;static void Main(string[] args){int[,] dist = new int[6, 6]{{int.MaxValue,1,1,int.MaxValue,int.MaxValue,int.MaxValue},{int.MaxValue,int.MaxValue,1,int.MaxValue,int.MaxValue,int.MaxValue},{int.MaxValue,int.MaxValue,int.MaxValue,int.MaxValue,int.MaxValue,1},{int.MaxValue,int.MaxValue,1,int.MaxValue,int.MaxValue,int.MaxValue},{int.MaxValue,int.MaxValue,int.MaxValue,int.MaxValue,int.MaxValue,int.MaxValue},{int.MaxValue,int.MaxValue,int.MaxValue,int.MaxValue,int.MaxValue,int.MaxValue}};int[,] g = new int[6, 6];Floyd(dist, g);PrintGraph(g, M);Console.Read();}/// <summary>/// 输出最短路径矩阵/// </summary>/// <param name="g"></param>/// <param name="v"></param>public static void PrintGraph(int[,] g, int v){for (int i = 0; i < v; i++){for (int j = 0; j < v; j++){if (g[i, j] == int.MaxValue)Console.Write("*" + " ");elseConsole.Write(g[i, j] + " ");}Console.WriteLine();}}/// <summary>/// Floyd最短路径算法/// </summary>/// <param name="dist">邻接矩阵</param>/// <param name="D">最短路径</param>public static void Floyd(int[,] dist, int[,] D){//复制一份distfor (int i = 0; i < M; i++){for (int j = 0; j < M; j++){D[i, j] = dist[i, j];}}for (int k = 0; k < M; k++){for (int i = 0; i < M; i++){for (int j = 0; j < M; j++){D[i, j] = Math.Min(D[i, j], (D[i, k] == int.MaxValue || D[k, j] == int.MaxValue) ? int.MaxValue : D[i, k] + D[k, j]);}}}}

其中最外层循环K 表示经过K节点,i,j循环表示从i->j ,合起来的意思就是求min(dist(ij) ,dist(ik) + dist(kj)),可以看到实现很简单,时间复杂性为O(n3)

要求最远路径,只要将路径值变为相反值就行了

  int[,] dest = new int[6, 6];dist = new int[6, 6]{{0,-1,-1,0,0,0},{0,0,-1,0,0,0},{0,0,0,0,0,-1},{0,0,-1,0,0,0},{0,0,0,0,0,0},{0,0,0,0,0,0}};Floyd_OneNode(dist, 0, dest);PrintGraph_OneNode(dest, M, 0);/// <summary>/// Floyd最短路径算法,求指定节点到其它节点距离/// </summary>/// <param name="dist">邻接矩阵</param>/// <param name="index">指定节点在邻接矩阵下标</param>/// <param name="D">最短路径</param>public static void Floyd_OneNode(int[,] dist, int index, int[,] D){//复制一份distfor (int i = 0; i < M; i++){for (int j = 0; j < M; j++){D[i, j] = dist[i, j];}}for (int k = 0; k < M; k++){//i为指定节点int i = index;for (int j = 0; j < M; j++){D[i, j] = Math.Min(D[i, j], (D[i, k] == 0 || D[k, j] ==0) ? 0 : D[i, k] + D[k, j]);}}}

回到顶部

总结

  经过上一篇和这一篇的分析,你会发现联动问题是图论里面的相关知识,涉及到拓扑排序和最短路径算法。实际代码中还会涉及到递归,在这次开发中我感受最深的一点遇到复杂问题,一定要分析和规划清楚找到问题的本质,偏离了问题本质就可能用很复杂的代码实现了。

动态联动问题的经过总结我给出的步骤

1.计算每个节点到主节点的最远距离,(这个其实是图的最短路径的变种)。

2.找出所有最远距离是1的节点,这些节点是需要联动的,而其它最远距离不为无穷大的节点是需要清空的。

3.循环这些距离为1的节点,找这些节点直接依赖的父级节点连同主节点一起收集,传到后台进行解析。

理清楚这几个步骤你也可以实现自己的动态联动功能了!

如果,您认为阅读这篇博客让您有些收获,不妨点击一下右下角的【推荐】按钮。
如果,您希望更容易地发现我的新博客,不妨点击一下绿色通道的【关注我】。

如果,想给予我更多的鼓励,求打

因为,我的写作热情也离不开您的肯定支持。

感谢您的阅读,如果您对我的博客所讲述的内容有兴趣,请继续关注我的后续博客,我是焰尾迭 。

转载于:https://www.cnblogs.com/yanweidie/p/4448671.html

我是怎么使用最短路径算法解决动态联动问题的相关推荐

  1. 应用单源最短路径算法解决套利交易问题

    目录 导言 基本定义与延伸 基本概念与定义 概念延伸 最短路径算法 Bellman-Ford算法 问题简述 问题分析 问题求解 第一题 第二题 总结 导言 最短路径问题是图论领域中的核心问题之一,也是 ...

  2. k-近邻算法 解决 动态字体反爬

    记录k-近邻算法 解决猫眼电影的字体反爬. 此博客仅为我业余记录文章所用,发布到此,仅供网友阅读参考,如有侵权,请通知我,我会删掉. 文章有一些点没有说的很细.因为我相信能看到这篇文章的你,不通过我的 ...

  3. 单源路径分支界限java_java单源最短路径算法

    . .. .. . 单源最短路径的 Dijkstra 算法: 问题描述: 给定一... 并 应用贪心法求解单源最短路径问题.环境要求对于环境没有特别要求.对于算法实现,可以自由选择 C, C++, J ...

  4. 图的应用---最短路径问题 用迪杰斯特拉算法解决 《地铁换乘问题》

    图的应用-最短路径问题 用迪杰斯特拉算法解决 <地铁换乘问题> 代码是在我学习的过程中完成的,也许会有问题,希望大家批评指正. 题目: 描述:已知2条地铁线路,其中A为环线,B为东西向线路 ...

  5. 集货运输优化:数学建模步骤,Python实现蚁群算法(解决最短路径问题), 蚁群算法解决旅行商问题(最优路径问题),节约里程算法

    目录 数学建模步骤 Python实现蚁群算法(解决最短路径问题) 蚁群算法解决旅行商问题(最优路径问题) 节约里程算法

  6. 四大算法解决最短路径问题(Dijkstra+Bellman-ford+SPFA+Floyd)

    什么是最短路径问题? 简单来讲,就是用于计算一个节点到其他所有节点的最短路径. 单源最短路算法:已知起点,求到达其他点的最短路径. 常用算法:Dijkstra算法.Bellman-ford算法.SPF ...

  7. 迪杰斯特拉(Dijkstra)算法解决最短路径问题

    Dijkstra 算法介绍 迪杰斯特拉算法(Dijkstra)是由荷兰计算机科学家狄克斯特拉于1959年提出的,因此又叫狄克斯特拉算法.迪杰斯特拉(Dijkstra)算法是最经典的最短路径算法之一,用 ...

  8. 最短路径算法(一) Dijkstra算法(贪心算法)

    Dijkstra算法是由荷兰计算机科学家狄克斯特拉(Dijkstra)于1959 年提出的,因此又叫狄克斯特拉算法.是从一个顶点到其余各顶点的最短路径算法,解决的是有向图中最短路径问题. 其基本原理是 ...

  9. 图的四种最短路径算法

    本文总结了图的几种最短路径算法的实现:深度或广度优先搜索算法,弗洛伊德算法,迪杰斯特拉算法,Bellman-Ford算法 1),深度或广度优先搜索算法(解决单源最短路径) 从起始结点开始访问所有的深度 ...

最新文章

  1. Android与Js交互时,屏幕不适配问题
  2. 【翻译】.NET 5 Preview8发布
  3. 内存泄漏分析_调查内存泄漏第2部分–分析问题
  4. c++11 你需要知道这些就够了
  5. [css] CSS3有哪些新增的特性?
  6. 全球顶尖科学杂志:阿里AI语音技术超越谷歌,可读懂人类潜藏意图
  7. 人工智能还能登上微博热搜?热搜关键词你得看看!
  8. 高中分班考试如何计算机,新高一生如何应对分班考?
  9. SQLite数据库导出Excel教程
  10. 代数拓扑笔记(1) —— 胞腔复形
  11. JQuery文件上传插件Uploadify
  12. matlab 小波变换程序,matlab 小波变换
  13. CAD等高线转地形高程散点
  14. DB2数据库基本概念
  15. java并发编程——并发编程的挑战
  16. 《看板实战》读书笔记 XMIND版本
  17. 闪存,ROM,Nor Flash,NAND Flash
  18. Apache HTTP Servcer-Apache服务器下载与Windows系统下安装
  19. 以太坊外无Defi?EOS:我有
  20. aws,bitnami建站过程

热门文章

  1. POJ1465 Multiple——Bfs+余数判重——Pku1465
  2. Kali Linux常用服务配置教程安装及配置DHCP服务
  3. SQLite添加列的限制
  4. Beaglebone Black开发板安装驱动
  5. C#开发Unity游戏教程之游戏对象的行为逻辑方法
  6. 明明白白学C#0.1.2 什么是编程语言
  7. 继承redis spring_实例讲解Springboot以Repository方式整合Redis
  8. java pathinfo,nginx下支持PATH_INFO的方法实例详解
  9. 电气simulink常用模块_16种常用模块电路分析,电气工程师的必备
  10. 基于EEG的癫痫自动检测: 综述与展望