• SPH算法(求最小代价树)


    一、sph算法简介


    1.最小代价树算法

    SPH算法也叫做MPH( minimum path heuristic)算法, 用于构造时延约束最算法小代价组播树. 该算法中每 个目的结点通过与当前组播树有最小代价的路径加入组播树,直到所有的目的节点全的进入树。
    最小代价树算法中最经典的算法有 3 个: KMB 算法、ADH 算法、 MPH 算法.

    • KMB 算法是由 Kou 等人提出的求解 Steiner 组播树算法, 其复杂度为 O(mn2);
    • ADH ( average distance heuristic)算法复杂度为 O( n3);
    • MPH 算法复杂度为 O( mn2).

    2.MPH算法过程

    到目前为 止,从降低组播生成树的代价方面考虑,MPH 仍是 一个非常优秀 的求解 Steiner 树问题 的启发式 算法. MPH 算法基本思想如下:

      1. 初始化组播树 T,开始时只包括源结点 s;
      1. 从余下的目的结点中选取到树 T 具有最小 代价路径的目的结点,将该结点及其最小代价路径 加入树 T ;
      1. 重复 2) ,直到所有目的结点加入组播树 T

    3.SPH算法过程

    具体包括如下几个 步骤:

    • 1)运用 Dijkstra算法,以点集S(初值为源点first)计算到所有结点的最小代价路径 ;
    • 2)选出目的节点中间的代价最小的minNodes;
    • 3)将到点minNodes的路径上的全部节点压进点集S;
    • 4)重复1)、2)、3)直到所有的目标点集进入点集S;

    其中Dijkstra算法是一个常用的解单源最短路径的常用算法。其基本思想是,设置一个顶点集合H,并不断贪心的选择来扩充这个集合。此算法网上描述很多,不进行赘述。
    本次,完成Dijkstra后同时记录下最短路径的值及最短路径经过的节点,数据结构也只是用了比较low的表去实现。
    第二步中间选取最小的minNodes时,下一步的优化方向是采用最小优先级对列的数据结构,及堆算法pop_heap,push_back,pop_back等等。

    二、代码实现

    sph算法代码GitHub链接
    数据集链接

    核心代码:

    for (;;)
    	{
    		if (t > 0)
    		{
    			t = T;
    			mind = 99999999;
    			//所有点到目标点的距离
    			for (int i = 1; i <= DD; i++)
    			{
    				if (s[i] == 1)
    				{
    					Dijkstra(i);
    					//利用新的dist的数据对fdis的数据进行更新
    					for (int j = 1; j <= DD; j++)
    					{
    						if (dist[j] < fdis[j] && dist[j] != 0 && s[j] != 1)
    						{
    							fdis[j] = dist[j];
    							for (int k = 0; k <= DD; k++)
    							{
    								fload[j][k] = load[j][k];
    								if (fload[j][k] == 0)
    									break;
    							}
    						}
    					}
    				}
    			}
    			fdis[first] = 0;
    			//找出最小的点(目标点中)
    			for (int i = 1; i <= DD; i++)
    			{
    				for (int j = 0; j < T; j++)
    				{
    					if (mind > fdis[i] && i == goal[j] && goal2[i] != 1)//这点距离小,在目标点中间,且未进入点集s
    					{
    						mind = fdis[i];
    						minv = i;
    					}
    				}
    			}
    			//找出的点加入点集s
    			goal2[minv] = 1;
    			for (int i = 0; i <= DD; i++)
    			{
    				if (fload[minv][i] > 0)
    					s[fload[minv][i]] = 1;
    				else
    					break;
    			}
    			for (int i = 1; i <= DD; i++)
    			{
    				if (1 == goal2[i])
    					t--;
    			}
    		}
    		else
    			break;
    	}
    

    贴几个跑完的数据。

    • 数据1:
      first:2
      目标点1、2、3、4、5、6、7、8、9、10
      点集图:

    路径图:(别吐槽。。。matlab用的烂,有空补不是手绘的。。。)

    程序结果截图:

    • 数据2:
      first:1
      目标点1、2、3、4、5、6、7、8、9、10
      点集图:

    路径图:

    程序结果截图:

    -数据3:
    点集图:

    路径图:

    emmmmm........就是这样,学习中大佬们指教。

  • 相关阅读:
    B01-java学习-阶段2-面向对象
    A11-java学习-二维数组-面向对象概念-类的编写-测试类的编写-创建对象-使用对象-递归
    09-java学习-数组-冒泡排序-选择排序-数组工具类编写-查找-扩容
    08-java学习-数组-增强for循环-数组与方法-main函数参数
    07-java学习-方法重载-idea集成开发工具学习-项目-模块-包
    执行SQL语句---SELECT
    执行SQL语句---INSERT/UPDATE/DELETE
    undefined reference to `mysql_init'解决办法
    ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)
    网络编程(三)---数据报套接字
  • 原文地址:https://www.cnblogs.com/nnmaitian/p/7768929.html
Copyright © 2020-2023  润新知