这学期算法设计的作业题,第一次写博客,水平略渣,主要供自己学习使用~
部分内容来自网络,如有不合适的地方请联系我~
邮局选址问题
系统环境:Windows7旗舰版,64位。
编程语言:C++
编程环境:VC++ 6.0
五组数据文件包括
input_assign01_01.txt
input_assign01_02.txt
input_assign01_03.txt
input_assign01_04.txt
input_assign01_05.txt
程序从数据文件中读取五组测试数据,结果直接输出。
运行示例:
输入input_assign01_01.txt :
1
1 2
输出:
第1组测试数据
所有居民点到邮局的距离总和最小值:0
在一个按照东西和南北方向划分成规整街区的城市里,n个居民点散乱地分布在不同的街区中。用X坐标表示东西向,用Y坐标表示南北向。各居民点的位置可以由坐标(X,Y)表示。要求:为建邮局选址,使得n个居民点到邮局之距离的总和最小。
提示:带权中位数(分治算法)
城市中中任意2点(X1,Y1)和(X2,Y2)之间的距离可以用数值|X1-X2|+|Y1-Y2|得到,所以我们可以将任意2点的距离可以看作为X坐标上的距离|X1-X2|和Y坐标的距离|Y1-Y2|之和。所以可以将这个2维的问题拆分为2个一维然后将它们合并就可以解决。
由提示可知用中位数和分治算法求解,想到用快速排序将所有的X排序,再求X的中位数,Y与X类似。最后将X ,Y坐标所求的距离和相加即是最优解。
伪代码描述:
int Partition(int a[], int low, int high) //快速排序
{
int x = a[high];//将输入数组的最后一个数作为主元,用它来对数组进行划分
int i = low - 1;//i是最后一个小于主元的数的下标
for (int j = low; j < high; j++)//遍历下标由low到high-1的数
{
if (a[j] < x)//如果数小于主元的话就将i向前挪动一个位置,并且交换j和i所分别指向的数
{
int temp;
i++;
交换;
}
}
//经历上面的循环之后下标为从low到i(包括i)的数就均为小于x的数了,现在将主元和i+1位置上面的数进行交换
a[high] = a[i + 1];
a[i + 1] = x;
return i + 1;
}
void QuickSort(int a[], int low, int high) //分治思想
{
if (low < high)
{
int q = Partition(a, low, high);
对左边快速排序;
对右边快速排序;
}
}
输入 文件 |
input_assign01_01.txt
|
input_assign01_02.txt
|
input_assign01_03.txt
|
input_assign01_04.txt
|
input_assign01_05.txt
|
内容 |
1 1 2
|
2 1 2 2 2
|
3 1 2 2 2 1 3
|
4 1 2 2 2 1 3 3 -2
|
5 1 2 2 2 1 3 3 -2 3 3
|
#include
#include
#include
#include
using namespace std;
int n; //定义居民点数量
int x[1000];//x坐标
int y[1000];//y坐标
void input(string fn) //输入函数
{
ifstream fin(fn.c_str()); //打开第 i 个文件
fin>>n; //读取居民点数
for(int i=0;i>x[i]>>y[i]; //读取一个值,就写入到x[]和y[]中,读取居民点坐标
}
fin.close(); //读取完成之后关闭文件
}
int Partition(int a[], int low, int high) //快速排序
{
int x = a[high];//将输入数组的最后一个数作为主元,用它来对数组进行划分
int i = low - 1;//i是最后一个小于主元的数的下标
for (int j = low; j < high; j++)//遍历下标由low到high-1的数
{
if (a[j] < x)//如果数小于主元的话就将i向前挪动一个位置,并且交换j和i所分别指向的数
{
int temp;
i++;
temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}
//经历上面的循环之后下标为从low到i(包括i)的数就均为小于x的数了,现在将主元和i+1位置上面的数进行交换
a[high] = a[i + 1];
a[i + 1] = x;
return i + 1;
}
void QuickSort(int a[], int low, int high) //分治思想
{
if (low < high)
{
int q = Partition(a, low, high);
QuickSort(a, low, q - 1);
QuickSort(a, q + 1, high);
}
}
void getDistance(int *x,int *y,int n) //求最短距离
{
int dx;//x坐标中位数
int dy;//y坐标中位数
int Distance=0; //n个居民点到邮局距离之和
QuickSort(x,0,n-1);
QuickSort(y,0,n-1);
dx=x[n/2]; //求X坐标中位数
dy=y[n/2]; //求Y坐标中位数
for(int i=0;i