石油公司的油田往往包括多个油井,在为油田建造输油管道时,每个油井均需与主管道相连,如何确定管道的铺设方案,使得管道的总长度最小,即确定经费最省的建设方案是所要研究的问题。
问题一:针对各油井到主管道距离的各种不同情形,在设计时,需考虑共用管道与非共用管道费用相同与不同的问题
输油管道铺设要想使费用最省,必须是铺设线路最短,所以建立模型时必须保证油井与主管道距离之和最短,所以管道铺设费用最省问题就转化成了求最短线路的问题。
对于问题一,应该从有共用管线和全是非共用管线两个方面入手考虑,而且费用也会随着共用部分的长短而不同。
3.1模型的假设
(1)将油井本身的面积忽略不计,看成是质点,主管道看成是直线。
(2)在管道铺设的线路上,假设没有任何障碍,可以在任意位置铺设管道。
(3)不考虑油井的储油能力。
(4)假设管道费用仅仅与管道长度有关,而不考虑输油量。
3.2
符号说明
A1,A2,A3....An表示第i个油井Ai
S1,S2,S3....Sn表示第i个油井Ai与主管道之间的距离Si
x:油井的横坐标 (假设主管道是由东向西)
y:油井的纵坐标
mx:主管道的横坐标
my:主管道的纵坐标
假设主管道是由东向西,显然,主管道的铺设位置只和各油井位置的y坐标有关,设各个油井的y坐标为:y,主管道的纵坐标坐标为:my,各油井到主管道之间的输油管道长度总和应是:,要使这个值最小,主管道的位置y坐标应是各个油井y坐标的中位数。
证明(反证法):
①油井数目为奇数:假设主管道的最优位置y坐标值为y_val,不是各个油井位置y坐标的中位数y_median,我们可以假设y_val>y_median(不失一般性),y坐标小于y_val的油井数目为m,y坐标大于y_val的油井数目为n,显然有m>n。当我们将主管道位置下移距离x时(假设此时仍满足y_val>=y_median),各油井到主管道之间的输油管道长度总和应增加nx-mx,显然nx-mx<0(m>n),即存在一个比y_val更优的位置使得各油井到主管道之间的输油管道长度总和更小,这与假设矛盾。
②油井数目为偶数:证明情况同奇数情况。不同的是主管道的最优位置y坐标可以是各油井y坐标的两个中位数之间的任一整数。
5.1 递推过程的抽象描述
本设计采用快速排序和中位数来计算输油管道的最短路径。
5.2 主要数据类型与变量
x[ ]:存放油井横坐标的数组
a[ ] 、y[ ]:存放油井纵坐标的数组
5.3 算法或程序模块
void qsort(double a[],int l,int r) 对存放y坐标的数组进行从小到大的排序
void mcount(double a[],int n) 对排序后的y坐标取中位数并计算铺设的总长度
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
//交换a与b两个变量的值
void swap(int&a,int&b)
{
int t=a;
a=b;
b=t;
}
int partition(double a[],int l,int r)
{
int i = l-1,j=r;
int v = a[r];
while(true)
{
while(a[++i]<v);
while(a[--j]>v)
if(j==l)
break;
if(i>=j)break;
swap(a[i],a[j]);
}
swap(a[i],a[r]);
return i;
}
void qsort(double a[],int l,int r)
{
int i;
if(r<=l)
return ;
i=partition(a,l,r);
qsort(a,l,i-1);
qsort(a,i+1,r);
}
void mcount(double a[],int n)
{
double my;//主管道的y坐标
double mlength = 0,k;
int i;
//对油井的y坐标进行排序
qsort(a,0,n-1);
if(n%2!=0)
{
//当个数为奇数时
my=a[n/2];
}
else my = (double)(a[n/2-1]+a[n/2])/2;//个数为偶数
for(i = 0;i<n;i++)
{
mlength += fabs(my - a[i]);
}
cout<<my<<endl;
cout<<mlength<<endl;
}
int main()
{
int n,i,j,sum=0;
double x[100];
double y[100];
cout<<"请输入油井的个数"<<endl;
cin>>n;
for(i=0;i<n;i++)
{
cout<<"请输入油井"<<i+1<<"的坐标"<<endl;
cin>>x[i];
cin>>y[i];
}
mcount(y,n);
for(i=0;i<n;i++)
cout<<y[i]<<" ";
return 0;
}原文:http://blog.csdn.net/qq544529563/article/details/24122837