北京工业大学研究生算法作业(一)——邮局选址

算法思路

本题可以简化成寻找N个城市x,y坐标的中位数dx,dy,解决方法就是利用最经典的分治算法的思路,通过不断递归与快速排序实现。本程序使用Python实现。

Readme

运行环境:
win10 + pycharm + python3.7

运行说明:
7个.dat后缀文件保存了7组地址数据,将.py和.exe和.dat文件放在同一个文件夹中。直接运行postoffice.exe,将显示每组数据的邮局坐标,和所有城市到邮局的距离总和。程序窗口将保持60秒。

数据结构:
定义列表x存储城市的x坐标,定义列表y存储城市y坐标

算法设计:
1、首先获取每个城市的x,y坐标数据,分别将其存入x和y的列表中。
2、对x、y列表分别使用分治算法,选定列表中最后一个元素作为主元。将列表中每个元素与主元比较,利用快速排序,分成比主元小的和比主元大的两组,中间数据为主元。接下来不断递归,直到列表排序完成。
3、分别取x、y列表的中位数dx和dy,(dx,dy)即为邮局地址坐标。

代码

import time

def readfile(path):                       #读取文件函数
    x = []                                #定义列表x用于存放城市的x坐标
    y = []                                #定义列表y用于存放城市的y坐标
    f=open("./"+path)
    N = f.readline()                      #读入N,为该组数据城市个数
    for i in range(int(N)):
        line = f.readline()
        curLine = line.strip().split(" ")
        x.append(curLine[0])
        y.append(curLine[-1])
    return x,y,N

def quicksort(left,right,a):              #快速排序功能函数
    if(left<right):
        p= divide(left,right,a)           #使用分治算法
        quicksort(left,p-1,a)             #递归使用快排,排序主元左侧数据
        quicksort(p+1,right,a)            #递归使用快排,排序主元右侧数据
    return a

def divide(left,right,a):                 #分治算法功能函数
    x = a[right]                          #将最后一个元素定义为主元
    i = left-1                            #i是最后一个小于主元的数的下标
    for j in range(left,right):
        if(a[j]<x):
            i += 1
            temp = a[i]
            a[i] = a[j]
            a[j] = a[i]
    a[right] = a[i+1]
    a[i+1] = x
    return i+1


def MinSum(x,y,N):                       #计算城市与邮局的距离函数
    distance=0                           #初始距离总和为0
    quicksort(0,N-1,x)                   #对城市坐标列表x进行快排
    quicksort(0,N-1,y)                   #对城市坐标列表y进行快排
    dx=x[int(N/2)]                       #取邮局x坐标为列表x中位数
    dy=y[int(N/2)]                       #取邮局y坐标为列表y中位数
    for i in range(N):
        distance += abs(int(x[i])-int(dx))+abs(int(y[i])-int(dy))
    print("邮局坐标位置为:(" + dx+"," + dy +")")
    print("所有居民到邮局距离总和为:",distance)


def main():                              #主函数
    for i in range(7):                   #循环读入七个配置文件数据
        path = "input_assign01_0{}".format(str(i + 1)) + ".dat"
        x, y, N = readfile(path)
        print("第%d组数据" % (i + 1))
        MinSum(x, y, int(N))             #计算距离


if __name__ == "__main__":
    main()
    time.sleep(60)                       #程序睡眠60s
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值