一、目的
1.熟悉算法设计的基本思想
2.掌握最小生成树算法的思路
二、内容与设计思想

国家电网公司想在全国布局超高压输电网络,联通所有省会城市。为了降低成本,并且达到某些硬性要求,国家电网按照以下五种策略进行规划布局。
(1)要求整个电网的长度最短。
(2)要求在西宁与郑州拉一根直达专线的情况下,使得整个电网长度最短
(3)要求不仅在西宁与郑州之间拉直达专线,还在杭州与长沙之间拉直达专线的情况下,使得整个电网长度最短。
(4)在香港与澳门、澳门与广州不拉直达线路的前提之下,使得整个电网的长度最短。
(5)山东、河南、陕西、甘肃、青海、新疆以及比他们更北的省份称为北方省份,其余省份称为南方省份。如果在南方省份和北方省份之间仅规划一条直通专线,如何使得整个电网的长度最短。
请分别根据这五种情况计算最优情况。
提示:

  1. 如无特殊约定,各个城市之间均可拉专线,其长度是直线长度。
  2. 地球上任意两点之间的距离计算方法可以参照以下文件:https://www.cnblogs.com/ycsfwhh/archive/2010/12/20/1911232.html
    摘录如下:
    地球是一个近乎标准的椭球体,它的赤道半径为6378.140千米,极半径为 6356.755千米,平均半径6371.004千米。如果我们假设地球是一个完美的球体,那么它的半径就是地球的平均半径,记为R。如果以0度经线为基 准,那么根据地球表面任意两点的经纬度就可以计算出这两点间的地表距离(这里忽略地球表面地形对计算带来的误差,仅仅是理论上的估算值)。设第一点A的经 纬度为(LonA, LatA),第二点B的经纬度为(LonB, LatB),按照0度经线的基准,东经取经度的正值(Longitude),西经取经度负值(-Longitude),北纬取90-纬度值(90- Latitude),南纬取90+纬度值(90+Latitude),则经过上述处理过后的两点被计为(MLonA, MLatA)和(MLonB, MLatB)。那么根据三角推导,可以得到计算两点距离的如下公式:

C = sin(MLatA)*sin(MLatB)*cos(MLonA-MLonB) + cos(MLatA)cos(MLatB)
Distance = R
Arccos©*Pi/180

这里,R和Distance单位是相同,如果是采用6371.004千米作为半径,那么Distance就是千米为单位,如果要使用其他单位,比如mile,还需要做单位换算,1千米=0.621371192mile
如果仅对经度作正负的处理,而不对纬度作90-Latitude(假设都是北半球,南半球只有澳洲具有应用意义)的处理,那么公式将是:

C = sin(LatA)*sin(LatB) + cos(LatA)*cos(LatB)cos(MLonA-MLonB)
Distance = R
Arccos©*Pi/180

以上通过简单的三角变换就可以推出。

  1. 全国省会城市的经纬度如下所示。
城市,经度,纬度
沈阳市,123.429092,41.796768
长春市,125.324501,43.886841
哈尔滨市,126.642464,45.756966
北京市,116.405289,39.904987
天津市,117.190186,39.125595
呼和浩特市,111.751990,40.841490
银川市,106.232480,38.486440
太原市,112.549248,37.857014
石家庄市,114.502464,38.045475
济南市,117.000923,36.675808
郑州市,113.665413,34.757977
西安市,108.948021,34.263161
武汉市,114.298569,30.584354
南京市,118.76741,32.041546
合肥市,117.283043,31.861191
上海市,121.472641,31.231707
长沙市,112.982277,28.19409
南昌市,115.892151,28.676493
杭州市,120.15358,30.287458
福州市,119.306236,26.075302
广州市,113.28064,23.125177
台北市,121.5200760,25.0307240
海口市,110.199890,20.044220
南宁市,108.320007,22.82402
重庆市,106.504959,29.533155
昆明市,102.71225,25.040609
贵阳市,106.713478,26.578342
成都市,104.065735,30.659462
兰州市,103.834170,36.061380
西宁市,101.777820,36.617290
拉萨市,91.11450,29.644150
乌鲁木齐市,87.616880,43.826630
香港,114.165460,22.275340
澳门,113.549130,22.198750

三、使用环境

推荐使用C/C++集成编译环境。

四、实验过程

1、编写相关实验代码

#include<bits/stdc++.h>
using namespace std;#define Infinity 65535
#define ERROR -1
#define Pi 3.14
#define R 6371.004int Index[35];
string Arr[35]={"沈阳","长春","哈尔滨","北京","天津","呼和浩特","银川","太原","石家庄","济南","郑州","西安","武汉","南京","合肥","上海","长沙","南昌","杭州","福州","广州","台北","海口","南宁","重庆","昆明","贵阳","成都","兰州","西宁","拉萨","乌鲁木齐","香港","澳门"};
double S[35][2]={{123.429092,41.796768},{125.324501,43.886841},{126.642464,45.756966},{116.405289,39.904987},{117.190186,39.125595},{111.751990,40.841490}, {106.232480,38.486440},{112.549248,37.857014},{114.502464,38.045475}, {117.000923,36.675808},{113.665413,34.757977}, {108.948021,34.263161}, {114.298569,30.584354}, {118.76741,32.041546}, {117.283043,31.861191}, {121.472641,31.231707}, {112.982277,28.19409}, {115.892151,28.676493}, {120.15358,30.287458}, {119.306236,26.075302}, {113.28064,23.125177}, {121.5200760,25.0307240},{110.199890,20.044220}, {108.320007,22.82402}, {106.504959,29.533155}, {102.71225,25.040609}, {106.713478,26.578342}, {104.065735,30.659462}, {103.834170,36.061380}, {101.777820,36.617290}, {91.11450,29.644150}, {87.616880,43.826630}, {114.165460,22.275340}, {113.549130,22.198750}};typedef struct GNode
{int Nv;int Ne;double G[1000][1000];
//  int Data[1000];
} MGraph;typedef struct ENode
{int V1,V2;double Weight;
} Edge;MGraph* CreateGraph(int VertexNum)
{int V,W;MGraph* Graph;Graph=new MGraph;Graph->Nv=VertexNum;Graph->Ne=0;for (V=0;V<Graph->Nv;V++){for (W=0;W<Graph->Nv;W++){Graph->G[V][W]=Infinity;}}return Graph;
}void InsertEdge(MGraph* Graph,Edge* E)
{Graph->G[E->V1][E->V2]=E->Weight;
}MGraph* BuildGraph(MGraph* Graph,double D[])
{Edge* E;int V;int Nv,Ne,i,j,k;k=0;Nv=34;Ne=1156; Graph=CreateGraph(Nv);Graph->Ne=Ne;for (V=0;V<Nv;V++){Index[V]=V; }if (Graph->Ne!=0){E=new Edge;for (i=0;i<Nv;i++){for (j=0;j<Nv;j++){E->V1=Index[i];E->V2=Index[j];E->Weight=D[k];InsertEdge(Graph,E);k++;}}}return Graph;
}int FindMin(MGraph* Graph,double dist[])
{int MinV,V;double MinDist=Infinity;for (V=0;V<Graph->Nv;V++){if (dist[V]!=0&&dist[V]<MinDist){MinDist=dist[V];MinV=V;}}if (MinDist<Infinity){return MinV;}else{return ERROR;}
}void Print(double a[],int b[],int c[],int k,MGraph* Graph)
{int i,j,t;for (i=0;i<k;i++){cout<<Arr[b[i]]<<"--"<<Arr[c[i]]<<":"<<a[i]<<endl;}
}double Prim(MGraph* Graph,MGraph* MST)
{int k=0;double a[10000];int b[10000],c[10000];double dist[10000],TotalWeight;int parent[10000],V,W;int VCount;Edge* E;for (V=0;V<Graph->Nv;V++){dist[V]=Graph->G[0][V];parent[V]=0;}TotalWeight=0;VCount=0;MST=CreateGraph(Graph->Nv);E=new Edge;dist[0]=0;VCount++;parent[0]=-1;while(1){V=FindMin(Graph,dist);if (V==ERROR){break;}E->V1=parent[V];E->V2=V;E->Weight=dist[V];InsertEdge(MST,E);TotalWeight+=dist[V];dist[V]=0;VCount++;a[k]=E->Weight;b[k]=E->V1;c[k]=E->V2;k++;for (W=0;W<Graph->Nv;W++){if (dist[W]!=0&&Graph->G[V][W]<Infinity){if (Graph->G[V][W]<dist[W]){dist[W]=Graph->G[V][W];parent[W]=V;}}}}if (VCount<Graph->Nv){TotalWeight=ERROR;}Print(a,b,c,k,Graph);return TotalWeight;
}int main()
{MGraph* Graph;MGraph* MST;double Total;int i,j,k;double D[10000];double C;k=0;for (i=0;i<34;i++){for (j=0;j<34;j++){C=sin(S[i][1]*Pi/180)*sin(S[j][1]*Pi/180)+cos(S[i][1]*Pi/180)*cos(S[j][1]*Pi/180)*cos(S[i][0]*Pi/180-S[j][0]*Pi/180);D[k]=R*acos(C);k++;}}Graph=BuildGraph(Graph,D);Total=Prim(Graph,MST);cout<<Total;return 0;
}

2、写出算法的思路。
(2)第二题西宁和郑州拉线,就先让这两个城市之间连一条线,然后从郑州开始使用最小生成树;
(3)在第二题的基础上,设置一个flag=0,遇到杭州或者长沙时,flag+1,当flag=1时,跳过循环直接使杭州与长沙相连,之后再回到循环;
(4)在第一题的基础上,如果两端点是港澳或者广州澳门,那么把它的dist[V]设置为无穷,再利用FindMin函数,其余不变。
(5)把南北城市分开,分别使用Prim算法,再从南北城市之间的距离找到最小值,三者结合即为解。
3、输出各组实验的电网数据表,以及电网总长度,并且通过可视化方式进行呈现。

算法导论11--最小生成树电网长度问题相关推荐

  1. 假设一动态集合S用一个长度为m的直接寻址表T来表示。请给出一个查找S中最大元素的过程。(算法导论第十一章11.1-1)

    假设一动态集合S用一个长度为m的直接寻址表T来表示.请给出一个查找S中最大元素的过程.你所给的过程在最坏情况下的运行时间是多少. (算法导论第十一章11.1-1) #include "Key ...

  2. 位向量(bit vector)(算法导论第十一章11.1-2)

    位向量(bit vector) 位向量(bit vector)是一个仅包含0和1的数组.长度为m的位向量所占空间要比包含m个指针的数组少得多.说明如何用一个位向量来表示一个包含不同元素(无卫星数据)的 ...

  3. 算法导论之图的最小生成树

    引出最小生成树,是提到电子线路设计时,要把数个元件的引脚连接在一起,使其电位相同.使n个引脚互相连通,可以使用n-1条连接线,每条连接线连接两个引脚.寻求连接线最少的方案,是最小生成树的应用.将电子线 ...

  4. 算法导论第三版第十一章11.1-4

    算法导论第三版第十一章11.1-4 我们希望在一个非常大的数组上,通过利用直接寻址的方式来实现一个字典.开始时,该数组中可能包含一些无用信息,但要堆整个数组进行初始化时不太实际的,因为该数组的规模太大 ...

  5. 找出第二小元素(算法导论第三版9.1-1题)

    找出第二小元素(算法导论第三版9.1-1题) 时间复杂度Θ(n) 比较次数n+⌈lgn⌉−2次 思路:将元素每次分成2部分,第一部分和第二部分元素成对比较.最终获得最小的元素,记录那些和最小元素比较后 ...

  6. 算法导论 思考题1-1

    算法导论-思考题1-1 1-1(运行时间的比较)假设求解问题的算法需要 f(n)f(n)f(n)微秒(microseconds),对下表中每个函数f(n)f(n)f(n)和时间ttt可以确定在时间tt ...

  7. 算法导论9.1-1找第二小的元素

    文章目录 算法导论9.1-1 1.证明:在最坏情况下,找到n个元素中第二小的元素需要 n+ceil(lgn)-2 次比较.(提示:可以同时找到最小元素) 1.证明 n-1 2.证明 ceil(lg) ...

  8. 算法导论Java实现-随机化数组的两种方式(5.3章节)

    package lhz.algorithm.chapter.five; /** * 随机数组两种实现,<算法导论>第五章第三节 * 本文地址:http://mushiqianmeng.bl ...

  9. Python语言程序设计之urllib.request抓取页面,网易公开课之《麻省理工学院公开课:算法导论》

    Python语言用urllib.request模块抓取页面非常简单,再将抓取的页面内容用re模块解析,找出自己想要的东西.下面就就此方法来抓取网易公开课之<麻省理工学院公开课:算法导论>, ...

最新文章

  1. java内部类的定义原则
  2. C++友元与输出运算符重载
  3. java 堆转储快照_Java堆转储:您可以完成任务吗?
  4. c++ 优先队列_C/C++数据结构:队列结构最全解析!带你零基础入门队列结构
  5. Typescript实现单例之父类调用子类
  6. java enummap_Java EnumMap values()方法与示例
  7. 静态RAM(2K * 8位)6116介绍(抄自原理图)
  8. android studio mac svn插件,Mac下Android Studio升级SVN1.8(使用1.8format来checkout项目)
  9. 高中 信息科技 计算机网络 课件,初中信息技术课件第一课--认识计算机网络.ppt...
  10. 儿童近视率攀升,什么原因容易导致近视呢?
  11. 【高等数学笔记】二元函数连续、可微、偏导数存在、偏导数连续、任意方向导数存在的关系
  12. 什么是SDK? SDK是什么意思?
  13. 转账、汇款到账时间及手续费标准(招行和工行)
  14. vuetify 学习第一天之v-data-table_表格组件
  15. docker容器内pip install 显示 warning
  16. oracle报错ora-00054,ora-00054资源正忙的解决办法-Oracle
  17. 四步轻松实现用Visio画UML类图
  18. 商业数据分析【七】数理统计与SPSS统计
  19. 有趣的23000----整理(12)P词根
  20. 可口可乐公司2019年第三季度延续强劲増势,净收入增长8%

热门文章

  1. 大功率可调谐半导体激光器总结(二)
  2. 软件测试工程师的技能树
  3. 圣诞节快乐 | 圣诞特效来了!!
  4. 别让“来电显示费”变成“呼吸税”
  5. leaflet和leaflet.pm的使用
  6. 如何在Android上运行python
  7. Python获取安卓屏幕截图的几种方法
  8. 编程语言的几点感悟——语言的类别
  9. 谁是U盘的真正发明者?
  10. python身份证图片倾斜矫正_python实现证件图片倾斜矫正