输油管道问 题.pptVIP

  1. 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
  2. 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  3. 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
  4. 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
  5. 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们
  6. 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
  7. 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
某石油公司计划建造一条由东向西的主输油管道。该管道要穿过一个有n口油井的油田。从每口油井都要有一条输油管道沿最短路经(或南或北)与主管道相连。如果给定n口油井的位置,即它们的x坐标(东西向)和y坐标(南北向),应如何确定主管道的最优位置,即使各油井到主管道之间的输油管道长度总和最小的位置?证明可在线性时间内确定主管道的最优位置。 如果只有一口井,显然是越近越好 如果有两口井,那么有以下三种情况: 1.两口井都在主管道北边,那么这个时候的两个连接管道的长度和肯定大于两口井的Y坐标之差 2.两口井都在主管道南边,和情况1是一样的 3.两口井,一个在主管道南边,一个在主管道北边,那么两个连接管道的长度和就等于两口井的Y坐标之差 显然情况三是所要的最短管道的设计情况 就是当主管道在两口井之间的任意位置时,连接管道长度之和等于两口井的Y坐标之差,是最短的长度 将这个结论推广,当有n口井的时候 n是偶数 只要这n口井分布在主管道的两边,一边n/2个,那么就是距离之和最小的 n是奇数 只要将这n个井中,Y坐标最中间的(也就是Y是中值的那个)井不算,其余的偶数个井分布在主管道的两侧,这个时候移动主管道,那么这n个连接管道长度之和就决定于那个没有算的井了,因为其余的井的距离之和是固定了的,这个时候只要主管道最接近那个点就好了 算法实现: 1.通过划分算法对所有油井y坐标进行排序 2.通过随机选择方法RandomizedSelect得到中位数 3.连接管道长度之和等于各油井的Y坐标到中位数的绝对差之和 程序分析: Patition(划分)函数的作用:将一串数据由小到大进行排序,最后返回划分时所用基数的位置 int Partition(int y[LEN], int p, int r) {//将x的元素交换到左边区域 //将x的元素交换到右边区域 int i = p, j = r+1; int x = y[p]; while(true) { while(y[++i]xir); while(y[--j]x); if(i=j) break; Swap(y[i],y[j]); } y[p] = y[j]; y[j] = x; return j; //返回划分后基数的位置 } RandomizedPartition(随机划分)函数的:在所有坐标中随机选择一个,并以此作为基数进行划分,最后返回该基数的位置 int RandomizedPartition(int y[LEN], int p, int r) { int i = Random(p,r);//产生随机数 Swap(y[i],y[p]);//交换基数和第一个数 return Partition(y,p,r);//返回划分后基数的位置 } RandomizedSelect(随机选择)函数:找到排序后数据的中位数 int RandomizedSelect(int y[LEN], int p, int r, int k) { if(p==r) return y[p]; //如果基数在中间则返回基数的值 int i = RandomizedPartition(y,p,r);//将数组y[p:r]划分成两个子数组y[p:i]、y[i+1:r],使y[p:i]中每个元素不大于y[i+1:r]中每个元素 int j = i-p+1;//计算子数组y[p:i]中元素个数j if(k=j) return RandomizedSelect(y,p,i,k);//如果j=k,则第k小元素落 在子数组y[p:i]中,否则落在y[i+1:r]中 else return RandomizedSelect(y,i+1,r,k-j); } 此函数就是当基数处在油井的中间时返回该值 void main() //计算输油管道最小长度总和 { int n; //油井数 int sum = 0;//管道长度总和 int y[LEN];//油井y坐标 int dy; //油井y坐标中位数 printf(请输入油井数n= \n); scanf(%d,n); //读取油井数 printf(请输入油井数坐标\n); for(int i=0;in;i++) { scanf(“%d”,y[i]); //x坐标在此题中无用,

文档评论(0)

beoes + 关注
实名认证
文档贡献者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档