您的位置:首页 > 其它

中位数应用:输油管道问题--快速排序、改进、变种

2016-05-18 19:07 267 查看
问题描述:某石油公司计划建造一条由东向西的主输油管道。该管道要穿过一个有n口油井的油田。从每口油井都要有一条输油管道沿最短路经(或南或北)与主管道相连。示意如下所示。如果给定n口油井的位置, 即它们的x坐标(东西向)和y坐标(南北向), 应如何确定主管道的最优位置, 即使各油井到主管道之间的输油管道长度总和最小的位置?



问题分析:问题可以抽象为给定n个点坐标,如何确定一条平行于x轴的直线,使得所有的点到直线的距离和最短。进一步简化为只提取n个点的纵坐标,保存进数组中,目标是确定直线的纵坐标使得距离和最短。

解决方案:给定点的个数可能为奇数或偶数,两种情况对直线的位置确定影响不同。

对于偶数点情况:当直线在a2-a3之间的时候,距离和D=(a3-a2)+(a4-a1),当直线在别的位置比如a1-a2时,距离和D=(a3-a2)+(a4-a1)+d,其中d为偏移量。我们会发现只有直线位置属于[a2,a3]时,距离和才会最小,而且在[a2,a3]任意位置,距离和都是固定的。所以没有必要将直线取值在a2和a3的正中间,取a2和a3能有相同的效果,相当于a2和a3中间位置取整,这就说明找到n个点的中位数即可。



对于奇数点情况:和偶数点相同,也是找中位数。直线位于a2时,距离和D=a3-a1,当直线偏离a2,位于a1-a2间时,距离和D=a3-a1+d,d为a2偏移量。也能说明只有直线位于中位数位置时,距离和最短,是我们要找的位置。



详细细节:对于输入的数据,提取纵坐标保存到数组中,然后排序,找到中位数。众多排序算法中,快排平均性能最优,故先选择快排,然后提取中位数。

实现代码:

#include<iostream>
#include<vector>
#define len 10
using namespace std;
void quickSort(int[] , int, int);
int main(){
vector<int> list;
//读入n个油井纵坐标的位置
list.push_back(5);
list.push_back(9);
list.push_back(2);
list.push_back(9);
//cout << "容器大小为: " << list.size() << endl;
int array[len] = {};
//将向量转换为数组,主要考虑到传参时,数组是指针。
for (int i = 0; i < list.size(); i++)
array[i] = list.at(i);
quickSort(array, 0, list.size()-1);
//cout<<list.at(1)<<endl;
//list.at(1) = 4;
for (int i = 0; i < list.size(); i++)
cout << array[i] << endl;
cout<<"输油管道放置位置坐标:y=" << array[list.size() / 2-1]<<endl;

}
void quickSort(int a[], int left, int right)
{
if (left<right)
{
int i = left;
int j = right;
int x = a[i];

while (i<j)
{
while (i<j&&a[j]>x)
j--;
if (i<j){
a[i] = a[j];
i++;
}
while (i<j&&a[i]<x)
i++;
if (i<j){
a[j] = a[i];
j--;
}
}
a[i] = x;
quickSort(a, left, i - 1);
quickSort(a, i + 1, right);
}
}
结果:
油井纵坐标:2
油井纵坐标:5
油井纵坐标:9
油井纵坐标:9
输油管道放置位置坐标:y=5


快速排序的改进:随机选择算法。

在选择基数位的时候,不是每次都选择第一个数,而是以随机的方式产生表示任意位置的随机数来作为基数。从概率角度,这种做法不会达到最坏的时间复杂度O(n2)。

输油管道问题变种

管道不一定水平,可以任意方向旋转

本质上相当于坐标轴旋转确定新的坐标。新的油井纵坐标为y=y0cos(a)+x0sin(a)。原理和水平放置相同。通过遍历a度数(度数a取值范围0-180),每遍历一个度数就执行中位数查找,确定距离和Di,然后在所有的D中找最小的。

油井有权重

若考虑每个油井即使和管道距离相同,但每个油井代价不同。此时该如何建立管道保证总代价最小。问题会转换为带权中位数问题

拓展:邮局选址问题

输油管道问题是一维的邮局选址问题。(待补充)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息