定位服务于给定半径内的大多数其他城市的城市

时间:2014-03-31 19:35:27

标签: python algorithm

这基本上是我需要解决的问题:

  

您获得覆盖范围r(以英里为单位)并要求找到最少数量的设施,每个设施位于数据集中的128个城市之一,以便每个设施数据集中的128个城市距离某个设施r英里

data=[Cities, Population, Coordinates, Distances]

对于这个问题,我只关注数据中的城市和距离子列表(上图) 城市列表包含128个城市 距离列表包含128个子列表,包含距其自身和其他城市的128个距离

例如,让我们说

Cities= [cityA, cityB, cityC, cityD]

然后

Distances= [[0,25,50,75],[25,0,30,40], [50,30,0,45], [75,40,45,0]]

(这些距离完全弥补) 所以在距离列表中的每个子列表中,距离对应于城市列表中城市的索引,因此子列表中的第一个距离始终是从该城市到第一​​个城市(cityA)的距离,第二个距离是从该城市到第二个城市(cityB)的距离

我已经有了一个如下所示的辅助函数:

def nearbyCities(name, r, data) :
''' Returns a list of cities within distance r of named city
    sorted in alphabetical order.
    Returns an empty list if city name is invalid. '''

cities = data[0]
distances = data[3]

result = []
if name in cities :                # If the city name is valid
    i = cities.index(name)           # Get the index of the named city
    for j in range(len(cities)) :      # For every other city
        if distances[i][j] <= r :      # If within r of named city
            result = result + [cities[j]]  # Add to result
result.sort() 
return result

我需要编写一个名为def locateFacilities(data, r)的函数。 此函数返回的城市列表应按字母顺序排列。 该函数应该实现所描述的贪婪算法:

  

设施位置的贪婪算法:

     
      
  1. 最初所有城市都没有服从
  2.   
  3. 虽然有些城市没有得到服务:选择一个城市c为城市c和城市内所有城市提供服务的城市r   已提供c英里locateFacilities
  4.         

    在函数False中,您可能想要使用   名为服务的附加数据结构,用于保存其中的跟踪   到目前为止,这些设施已经为这些城市提供服务。   服务的数据结构可以简单地是长度的布尔列表   128,初始化为所有i值。位于i中的元素   此列表指示城市i(即位置c中的城市   在列表城市)已服务与否。一旦这样的数据结构   已定义,您可以找到任何给定城市r   尚未投放的城市数量,在c的半径c范围内   (你应该为此写一个函数!)。如果你实现这个,那么   贪婪算法重复定位城市r的设施   c的半径{{1}}内的“未保留”引用次数最多。

         

    我可以用英语解决这个问题但我需要做的事情   我真的在努力弄清楚如何把它放到代码中

2 个答案:

答案 0 :(得分:0)

在不知道确切的数据结构的情况下,它有点难。因此,以下代码段中的getDistance函数非常神奇。

以下代码尚未经过测试,因为我没有数据,但也许它可以为您提供一些想法:

def getDistance (city1, city2):
    #magic happens here
    #maybe return data [3] [city1.dix] [city2.idx]
    return #the distance between cities

class City:
    def __init__ (self, idx, name):
        self.idx = idx
        self.name = name

    def makeNeighbours (self, cities, radius):
        self.neighbours = [city for city in cities
            if city is not self and getDistance (self, city) <= r]

    def removeNeighbour (self, city):
        if city not in self.neighbours: return
        self.neighbours.remove (city)

    def __eq__ (self, other):
        return self.idx == other.idx


def locateFacilities (cities, radius):
    cities = [City (idx, name) for idx, name in enumerate (data [0] ) ]
    for city in cities: city.makeNeighbours (cities, radius)
    facilities = []
    while cities:
        mostNeighbours = sorted (cities, key = lambda c: -len (c.neighbours) ) [0]
        for city in cities:
            city.removeNeighbour (mostNeighbours)
        for city in mostNeighbours.neighbours:
            cities.remove (city)
        cities.remove (mostNeighbours)
        facilities.append (mostNeighbours)
    print ('Place facilities at:')
    for facility in facilities:
        print (facility.name)

答案 1 :(得分:0)

从问题描述中你已经可以编写locateFacilities函数的一部分而不需要太多的思考(当然,有不同的方法来编写代码,但让我们坚持使用的推荐的数据结构分配):

def locateFacilities(data, r):
    n = len(data[0])

    served = [False] * n
    facilities = []
    while not all(served):
        # 1. Find city with most unserved neighbors
        # 2. Place a facility in this city, i.e.:
        #   - Mark city and neighbors as served
        #   - Put city name in list of facilities
        # 3. Repeat

    facilities.sort()
    return facilities

您已经知道如何执行while循环中包含的代码的一部分,但我认为您将更容易找到与城市一起工作的代码。&#39;索引而不是名字。