算法设计练习作业,邮局选址问题,将自己写的分享,有问题请指正,希望共同学习。

关于邮局选址问题的理论知识就不赘述了,网上有讲解的。

#include <iostream>
#include <fstream>
#include <math.h>
using namespace std;
/*
*邮局选址问题,带权中位数
*输入的坐标不能相同,即x或y各自是n个不同的数,该程序为不同的整型数
*输入在文件input中,第一行为居民点个数,剩下行为(x,y,w)对,用空格分割
*输出文件为output,包括邮局坐标,带权的最短距离和
*/
int partition(int a[],float w[],int p,int r);
int partition2(int a[],float w[],int p,int r,int z);
void quicksort(int a[],float w[],int p,int r);
int select(int a[],float w[],int p,int r,int k);
int cut(int a[],float w[],int p,int r,int z) ;
int t=0;//外部变量,保存上一次划分得到的下标
int main()
{
fstream input,output;//输入输出流
int count=0;//居民点个数
int xk,yk;//所求的邮局坐标
float sum=0.0;//带权最短距离和
input.open("input_assign01_01.dat");
if(!input)
{
cout<<"error:unable to open input file!"<<endl;
return -1;
}
input>>count;
int *ax=new int[count];
int *ay=new int[count];//居民点x,y坐标数组
float *awx=new float[count];//居民点权值数组,对应下标为同一居民点
float *awy=new float[count];
for(int i=0;i<count;i++)
{
input>>ax[i]>>ay[i]>>awx[i];
awy[i]=awx[i];
}
xk=select(ax,awx,0,count-1,(count+1)/2);//计算xk,yk
yk=select(ay,awy,0,count-1,(count+1)/2);
for(i=0;i<count;i++)
{
sum+=awx[i]*abs(ax[i]-xk)+awy[i]*abs(ay[i]-yk);//求带权最短距离
}
output.open("output.txt");
output<<"邮局的坐标为:"<<endl;
output<<"("<<xk<<","<<yk<<")"<<endl;
output<<"最短距离为:"<<endl;
output<<sum;
input.close();
output.close();
delete []ax;
delete []ay;
delete []awx;
delete []awy;
return 0;
}
/*
*快速排序算法
*a为带排序数组,w为其权值数组,p为开始下标,r为结束下标
*功能是将a数组排序
*/
void quicksort(int a[],float w[],int p,int r)
{
if (p<r)
{int q=partition(a,w,p,r);
quicksort(a,w,p,q-1);
quicksort(a,w,q+1,r);
}
}
/*
*划分算法
*a为待划分数组,w为其权值数组,p为开始下标,r为结束下标,返回值为中心元下标
*功能是将数组进行划分,其中心元为数组最末端元素,划分后,比中心元小的元素在左边
*比中心元大的元素在右边,中心元在中间
*/
int partition(int a[],float w[],int p,int r)
{
int x=a[r];
int i=p-1;
for(int j=p;j<r;j++)
{
if(a[j]<=x)
{
i++;
swap(a[i],a[j]);
swap(w[i],w[j]);
}
}
swap(a[i+1],a[r]);
swap(w[i+1],w[r]);
return i+1;
}
/*
*划分算法
*a为待划分数组,w为其权值数组,p为开始下标,r为结束下标,z为中心元,返回值为中心元下标
*功能是将数组进行划分,中心元为指定元素z,划分后,比z小的元素在左边
*比z大的元素在右边,z在中间
*/
int partition2(int a[],float w[],int p,int r,int z)
{
int t=0;//记录a中等于z的元素的下标,便于将这个元素交换到中间
int i=p-1;
for(int j=p;j<=r;j++)
{
if(a[j]<=z)
{
i++;
if(a[j]==z)
{
t=i;
}
swap(a[i],a[j]);
swap(w[i],w[j]);
}
}
swap(a[i],a[t]);
swap(w[i],w[t]);
return i;
}
/*
*选择算法
*a为待选择的数组,w为其权值数组,p为开始下标,r为结束下标,k为待选择数组元素个数的中间值,返回值为带权中位数
*功能是选择带权中位数,先用中位数的中位数方法,求出n个不同的元素的中位数xk
*然后计算小于xk的元素的权值和wl,大于xk的元素的权值和wr
*如果wl<0.5 and wr<=0.5,则xk即为所求
*如果wl>=0.5,则对xk左边的数组元素递归调用select函数,否则对xk右边的数组元素递归调用select函数
*/
int select(int a[],float w[],int p,int r,int k)
{
float wl=0.0,wr=0.0;//中位数的权值和wl,wr
if (r-p<5)
{
quicksort(a,w,p,r);
//  return a[p+k-1];
for(int m=p;m<p+k-1;m++)
{
wl+=w[m];//比x小的元素的权值和
}
for(m=p+k;m<=r;m++)
{
wr+=w[m];//比x大的元素的权值和
}
if(wl<0.5 && wr<=0.5)
return a[p+k-1];//符合带权中位数的条件返回
else if(wl>=0.5)
{
w[p+k-1]+=wr;//处理x的左端
return select(a,w,p,p+k-1,(k+1)/2);
}
else
{
w[p-k+1]+=wl;//处理x的右端
return select(a,w,p+k-1,r,(r-p-k+3)/2);
}
}
for (int i=0;i<(r-p+1)/5;i++)//分组排序,将中位数交换到数组前端
{
quicksort(a,w,p+5*i,p+5*i+4);
swap(a[p+5*i+2],a[p+i]);
swap(w[p+5*i+2],w[p+i]);
}
int x=select(a,w,p,p+(r-p+1)/5-1,(((r-p+1)/5)+1)/2);//中位数的中位数
i=partition2(a,w,p,r,x);//计算x前半区元素个数
int j=i-p+1;
for(int m=t;m<i;m++)
{
wl+=w[m];//比x小的元素的权值和
}
for(m=i+1;m<=r;m++)
{
wr+=w[m];//比x大的元素的权值和
}
if(wl<0.5 && wr<=0.5)
return a[i];//符合带权中位数的条件返回
else if(wl>=0.5)
{
w[i]+=wr;//处理x的左端
t=i;
return select(a,w,p,i,(j+1)/2);
}
else
{
w[i]+=wl;//处理x的右端
t=i;
return select(a,w,i,r,(r-i+1+1)/2);
}
}

二维邮局选址问题-带权中位数相关推荐

  1. 邮局选址问题-带权中位数

    一.运行环境: Win7.MyEclipse.JDK8 二.运行过程说明: 数据文件格式:第一行是居民数量n的取值,第2~n+1行是每家的位置及权重. 输入格式:输入测试数据集文件编号,范围:1~6. ...

  2. 学校选址_洛谷U3451_带权中位数

    题目描述 在一条大路一旁有许多栋楼,每栋楼里有许多小学生(哈哈哈一波小学生来袭!).但是这条路上没有小学!!!!所以唯恐世界不乱的牛A打算在路上(汽车什么的都不敢来这个小学生云集的地方咯,所以不用担心 ...

  3. 中位数及带权中位数问题(转)

    先从一到简单的题看起: 士兵站队问题 在一个划分成网格的操场上,n个士兵散乱地站在网格点上.网格点由整数坐标(x,y)表示.士兵们可以沿网格边上.下.左.右移动一步,但在同一时刻任一网格点上只能有一名 ...

  4. 中位数及带权中位数问题

    信息学竞赛总是时不时与数学产生微妙的关系,中位数及带权中位数问题有时常常成为解题的关键,今日有时间,所以梳理一下. 先从一到简单的题看起: 士兵站队问题 在一个划分成网格的操场上,n个士兵散乱地站在网 ...

  5. 带权中位数-算法导论第三版第九章思考题9-2

    带权中位数-算法导论第三版第九章思考题9-2 b 时间复杂度O(nlgn) float find_median_with_weights_b(float *array,int length) {qui ...

  6. 求带权中位数的Select算法

    2019独角兽企业重金招聘Python工程师标准>>> 求带权中位数的Select算法 设有一个数组a,元素类型为T,T的定义如下: struct T { int x: // 位置 ...

  7. asp.net 后台生成二维码及生成带logo的二维码

    asp.net 后台生成二维码及生成带logo的二维码,此处将生成二维码和带Logo的二维码写在一起的,需要自己区分一下. 直接上代码 using System; using System.Colle ...

  8. Tp5生成带头像二维码海报(带文字描述,居中调整)

    Tp5生成带头像二维码海报(带文字描述,居中调整) 三张海报中随机生成一张展现 /*** 获取随机海报* Author: yanjie <823986855@qq.com>* Date: ...

  9. YL杯超级篮球赛_纪中1325_带权中位数

    Description 一年一度的高一YL杯超级篮球赛开赛了.当然,所谓超级,意思是参赛人数可能多余5人.小三对这项篮球非常感兴趣,所以一场都没有落下.每个中午都准时守侯在篮球场看比赛.经过一个星期的 ...

最新文章

  1. 【Prometheus】Exporter详解
  2. java上传ftp数据丢失_Java:将文件上传到FTP问题(数据包丢失) - java
  3. 产品研究分析--王者荣耀的那些套路
  4. mongo数据库 备份 还原
  5. cdoj 1150 排名表 拓扑排序
  6. 通用分页查询存储过程
  7. windows下使用命令行将employees.sql导入mysql
  8. STM32工作笔记0053---STM32串口寄存器库函数配置方法+串口通信实例
  9. 解决Vscode编辑器不能打开多标签页问题
  10. 输出结果为16的python表达式_第一周作业(rayco)
  11. 工作回忆总结(第二年)
  12. python手机版教程视频_Python教学app下载
  13. Linux安装dos环境,Ubuntu安装dos2unix工具
  14. 运动会比赛计分系统c语言课程设计,c语言课程设计运动会比赛计分系统(含任务书).doc...
  15. App Store Connect 如何删除应用App
  16. Hive——多行转一行及一行转多行
  17. 游戏引擎笔记(三)天空盒和水面
  18. 2022-2027年中国仓储物流机器人行业发展前景及投资战略咨询报告
  19. clientX,clientY,screenX,screenY,offsetX,offsetY 区别测试
  20. 高通QPST Download使用方法

热门文章

  1. android集成环信客服云_2019.6.12
  2. bootstrap 按钮颜色 class=“btn btn-success“
  3. 如何将多个excel合并成一个
  4. wps下载的简历无法删除空白页
  5. 端午小礼品:30 本技术书
  6. 移植st官方usb-hid程序出现babble detected错误
  7. 微软云服务器AZ如何扩大磁盘
  8. 掌握Android图像显示原理(中)
  9. 道阻且长,行则将至;行而不辍,未来可期。
  10. 道阻且长,行则将至,行而不辍,未来可期