【问题标题】:locating city that serves the most other cities within a given radius定位在给定半径内为大多数其他城市提供服务的城市
【发布时间】:2014-03-31 19:35:26
【问题描述】:

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

给您一个覆盖半径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]]

(这些距离是完全弥补的) 所以在 Distances 列表中的每个子列表中,距离对应于 Cities 列表中城市的索引,因此子列表中的第一个距离始终是该城市到第一​​个城市(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. 虽然有些城市未提供服务:选择一个城市 c 为未提供服务最多的城市标记城市 c 和其中的所有城市 rc 的服务里程

在函数 locateFacilities 中,您可能想要使用 称为服务的附加数据结构,用于跟踪哪个 迄今为止,这些设施已经为城市提供服务。 提供的数据结构可以简单地是一个布尔长度列表 128,初始化为所有False值。位置i中的元素 此列表指示城市i(即i 所在位置的城市) 在列表城市中)是否已提供服务。一旦有了这样的数据结构 已定义,然后您可以找到任何给定城市crc 范围内的尚未服务的城市数量 (你应该为此编写一个函数!)。如果你实现这个, 贪心算法重复定位一个城市c的设施 c 的半径 r 内的“未服务”引用数最大。

我可以用英语在脑海中想出我需要做的事情,但是 我真的很想弄清楚如何将其放入代码中

【问题讨论】:

  • 您能发布(或链接)一些示例数据吗?
  • 这类似于(但不一样)聚类分析。有一些不错的启发式算法可以解决这些类型的问题。幼稚的解决方案需要很长时间才能找到最佳解决方案。
  • @IceArdor 虽然这是真的,但 OP 的任务定义了要使用的算法(尽管它可能是无用的)。
  • 对我来说听起来很像最小集覆盖问题。每个设施覆盖一组城市,您正在寻找覆盖所有城市所需的最少设施数量,对吧?
  • @Anony-Mousse 在我读到它的时候,他不是在寻找最小的解决方案,而是在寻找作业中指定的算法给出的解决方案。

标签: python algorithm


【解决方案1】:

如果不知道确切的数据结构,这有点困难。因此下面 sn-p 中的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)

【讨论】:

    【解决方案2】:

    从问题描述中,您已经可以编写 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 循环中的部分代码,但我认为您会发现使用城市索引而不是名称更容易。

    【讨论】:

      猜你喜欢
      • 2017-03-31
      • 2010-10-13
      • 2011-12-11
      • 2014-03-04
      • 1970-01-01
      • 2012-04-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多