一、目的
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. graphlab中SFrame用法
  2. linux 新建用户配置文件 /etc/login.defs 简介
  3. 6、spring拦截器
  4. WIN32 多线程吃字母练习
  5. nagios(系统监控)
  6. 《C++ Primer》1.52节练习
  7. angular js 默认选中_AngularJS Select(选择框)
  8. 【华为云技术分享】全WEB化开发体验,开发者新利器华为云CloudIDE即将揭秘
  9. nodejs应用在linux服务器中的部署
  10. 对软件未来走向的看法
  11. 7个优秀的境外程序员博客
  12. java 修饰符全解
  13. flash mx拖拽实例_Flash MX 2004 Professional的百叶窗过渡效果
  14. Android 矢量图动画(完结篇)
  15. CMD命令制定打印机,打印测试页
  16. 为什么团建这么招人恨
  17. 运维自动化之salt
  18. 被雷总“随手拍”的超级月亮惊呆了...
  19. 什么是虚拟机,有什么用?
  20. Python笔记6 面向对象

热门文章

  1. 【视频制作】我们的相册【第1期】
  2. 喜讯!云创大数据跻身新三板创新层!
  3. sharepoint2010同步AD数据包MOSS MA not found
  4. 分享88个ASP聊天室,总有一款适合您
  5. PowerPoint2010自动保存多个版本
  6. Acrobat Pro DC 教程:如何使用密码保护 PDF 文件?
  7. 计算机毕业论文设计动画,计算机动画
  8. 01 【打新债】打新可转债
  9. 布林通道参数用20还是26_boll参数20还是26好?布林线与macd一招鲜。
  10. 热门游戏遭病毒团伙利用,中招者电脑被远程操控