二维邮局选址问题-带权中位数
算法设计练习作业,邮局选址问题,将自己写的分享,有问题请指正,希望共同学习。
关于邮局选址问题的理论知识就不赘述了,网上有讲解的。
#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);
}
}
二维邮局选址问题-带权中位数相关推荐
- 邮局选址问题-带权中位数
一.运行环境: Win7.MyEclipse.JDK8 二.运行过程说明: 数据文件格式:第一行是居民数量n的取值,第2~n+1行是每家的位置及权重. 输入格式:输入测试数据集文件编号,范围:1~6. ...
- 学校选址_洛谷U3451_带权中位数
题目描述 在一条大路一旁有许多栋楼,每栋楼里有许多小学生(哈哈哈一波小学生来袭!).但是这条路上没有小学!!!!所以唯恐世界不乱的牛A打算在路上(汽车什么的都不敢来这个小学生云集的地方咯,所以不用担心 ...
- 中位数及带权中位数问题(转)
先从一到简单的题看起: 士兵站队问题 在一个划分成网格的操场上,n个士兵散乱地站在网格点上.网格点由整数坐标(x,y)表示.士兵们可以沿网格边上.下.左.右移动一步,但在同一时刻任一网格点上只能有一名 ...
- 中位数及带权中位数问题
信息学竞赛总是时不时与数学产生微妙的关系,中位数及带权中位数问题有时常常成为解题的关键,今日有时间,所以梳理一下. 先从一到简单的题看起: 士兵站队问题 在一个划分成网格的操场上,n个士兵散乱地站在网 ...
- 带权中位数-算法导论第三版第九章思考题9-2
带权中位数-算法导论第三版第九章思考题9-2 b 时间复杂度O(nlgn) float find_median_with_weights_b(float *array,int length) {qui ...
- 求带权中位数的Select算法
2019独角兽企业重金招聘Python工程师标准>>> 求带权中位数的Select算法 设有一个数组a,元素类型为T,T的定义如下: struct T { int x: // 位置 ...
- asp.net 后台生成二维码及生成带logo的二维码
asp.net 后台生成二维码及生成带logo的二维码,此处将生成二维码和带Logo的二维码写在一起的,需要自己区分一下. 直接上代码 using System; using System.Colle ...
- Tp5生成带头像二维码海报(带文字描述,居中调整)
Tp5生成带头像二维码海报(带文字描述,居中调整) 三张海报中随机生成一张展现 /*** 获取随机海报* Author: yanjie <823986855@qq.com>* Date: ...
- YL杯超级篮球赛_纪中1325_带权中位数
Description 一年一度的高一YL杯超级篮球赛开赛了.当然,所谓超级,意思是参赛人数可能多余5人.小三对这项篮球非常感兴趣,所以一场都没有落下.每个中午都准时守侯在篮球场看比赛.经过一个星期的 ...
最新文章
- 【Prometheus】Exporter详解
- java上传ftp数据丢失_Java:将文件上传到FTP问题(数据包丢失) - java
- 产品研究分析--王者荣耀的那些套路
- mongo数据库 备份 还原
- cdoj 1150 排名表 拓扑排序
- 通用分页查询存储过程
- windows下使用命令行将employees.sql导入mysql
- STM32工作笔记0053---STM32串口寄存器库函数配置方法+串口通信实例
- 解决Vscode编辑器不能打开多标签页问题
- 输出结果为16的python表达式_第一周作业(rayco)
- 工作回忆总结(第二年)
- python手机版教程视频_Python教学app下载
- Linux安装dos环境,Ubuntu安装dos2unix工具
- 运动会比赛计分系统c语言课程设计,c语言课程设计运动会比赛计分系统(含任务书).doc...
- App Store Connect 如何删除应用App
- Hive——多行转一行及一行转多行
- 游戏引擎笔记(三)天空盒和水面
- 2022-2027年中国仓储物流机器人行业发展前景及投资战略咨询报告
- clientX,clientY,screenX,screenY,offsetX,offsetY 区别测试
- 高通QPST Download使用方法