【问题标题】:spatial partitioning algorithms for 1D dataset?一维数据集的空间分区算法?
【发布时间】:2017-02-18 10:17:24
【问题描述】:

这是 Grid,以 10,000 个方格表示地理区域,其中每个方格为 55225 平方米。

数据集的每平方交通量从 100 到 1000。

例如:

正方形 1 - 100,

正方形 2 - 500

.

.

10,000 - 800 平方

现在,我想以这样的方式划分这个区域,每个分区可能有不同的区域但会承载相似的流量,分区之间的流量标准偏差应该是最小的。对空间分区算法有什么建议吗?

【问题讨论】:

  • 为了通知您的程序,您必须做出一些决定。想到的first question 是是否定义了分区数? second question 是否对组有任何几何限制,即它们必须是连续的,还是任何特定的形状都是理想的? third question 是关于如何足够好?提供理想答案的算法(可能是贪婪算法)和提供最佳答案的算法(可能是穷举或“蛮力”方法)的运行时间通常存在巨大差异。
  • kpie 感谢您的回复。请找到我对问题的回答:需要大约 500 到 600 个分区的数量。它们必须是连续的,但它们的大小可以不同..因为这个分区是用于电信网络它可以是圆形或六边形。在这种情况下,可以说如果我们有 500 个分区,那么所有这些分区都应该承载相似的流量。即这 10000 个方格的总流量均匀分布在 500 个分区中。
  • 所以你不只是有一个网格,你有一个 100 x 100 的正方形网格?
  • 是的,没错
  • 如果您发送一些示例数据,我可以调试和测试我的解决方案,我使用贪心算法在 python 中编写它。另外我注意到您在意大利,所以您可能不使用 Venmo...您可以在这里找到我的所有个人信息krewn.github.io,我们可以使用最适合您的任何付款方式。

标签: cluster-analysis data-mining partitioning dbscan bigdata


【解决方案1】:

为了通知您的程序,您必须做出一些决定。想到的first question 是是否定义了分区数? second question 是否对组有任何几何限制,即它们必须是连续的,还是任何特定的形状都是理想的? third question 是关于如何足够好?提供理想答案的算法(可能是贪婪算法)和提供最佳答案的算法(可能是穷举或“蛮力”方法)的运行时间通常存在巨大差异。通过对具有相同体积的任意 2 个扇区进行分组,您将获得最小标准偏差,因为您的组每个都将具有 0 标准偏差。不管怎样,这听起来很像一个扩展的bin packing problem,你应该从那里开始你的文献综述。

您需要按顺序打包您的垃圾箱...

在这里,我为我的圈子选择了偏向于最高流量的中心点,然后从那里填充它们。

class trafficNode:
    def __init__(self,v,i):
        self.cluster = None
        self.value = v
        self.index = i
        self.occupied = False
    def occupy(self):
        self.occupied=True

def tryAdd(xList,mList,irow,icol):
    try:
        if not(mList[irow][icol] in xList and !mList[irow][icol].occupied):
            xlist.append(mList[irow][icol])
    except IndexError:
        chill = None
    return(xlist)

class cluster:
    def __init__(self):
        self.nodes = []
    def getTotal(self):
        total = 0
        for k in self.nodes:
            total += k.value
        return(total)
    def addNode(self,n):
        self.nodes.append(n)
    def getNeighbors(self,m,r = 0):
        neighbors = []
        for k in self.nodes:
            i = k.index()
            for k2 in range(0,4):
                if k2==0:
                    neighbors = tryAdd(neighbors,m,i[0]+0,i[1]+1)
                elif k2==1:
                    neighbors = tryAdd(neighbors,m,i[0]+1,i[1]+0)
                elif k2==2:
                    neighbors = tryAdd(neighbors,m,i[0]+0,i[1]-1)
                elif k2==3:
                    neighbors = tryAdd(neighbors,m,i[0]-1,i[1]+0)
                if r != 0:
                    if k2==0:
                        neighbors = tryAdd(neighbors,m,i[0]+1,i[1]+1)
                    elif k2==1:
                        neighbors = tryAdd(neighbors,m,i[0]+1,i[1]-1)
                    elif k2==2:
                        neighbors = tryAdd(neighbors,m,i[0]-1,i[1]+1)
                    elif k2==3:
                        neighbors = tryAdd(neighbors,m,i[0]-1,i[1]-1)
        return(neighbors)
    def seed(self,m,irow,icol):
        self.nodes.append(m[irow][icol])
        m[irow][icol].occupy()
    def propogate(self,m,target):
        total = 0
        for k in self.nodes:
            total += k.value
        s = 1
        while total<target:
            s = 1 if !s else 0
            lastTotal=Total
            n = self.getNeighbors(m,s)
            if len(n==0):
                break;
            else:
                if(abs(target-(total+sum([k.value for k in n])))<abs(target-total)):
                    for k in n:
                        self.nodes.append(k)
                        m[k.index[0]][k.index[1]].occupy()
                else:
                    break;
    def contains(self,i):
        ret = False
        for k in self.nodes 
            if k.index == i
                ret = False
                break;
        return(ret)

def parseData(d,s): # Where d is the source datafile and s is the number of units per row.
    ret = []
    f = open(d,"r")
    text = f.read()
    lines = f.split("\n")
    n = 0
    r = 0
    temp = []
    for k in lines:
        v = k.split(" - ")[1]
        n+=1
        temp.append(trafficNode(v,(r,n)))
        if n == s:
            n = 0
            r += 1
            ret.append(temp)
            temp = []
    return(ret)

def mapTotal(m):
    return sum([sum([k2.value for k2 in k]) for k in m])

def pTotal(m,n):
    return(mapTotal/n)

import sys

infile = sys.argv[1]
ncols = sys.argv[2]
ntowers = sys.argv[3]
m = parseData(infile,ncols)
s = pTotal(m,ntowers)

spots = [k.index for k in m if !k.occupied]
clusters = []
while len(spots > 0):
    spotVals = [m[k[0]][k[1]].value for k in spots]
    nextSpotIndex = spots[spotVals.index(max(spotVals))]
    clusters.append(cluster)
    clusters[n].seed(self,m,nextSpotIndex[0],nextSpotIndex[1])
    clusters[n].propogate(m,s)
    spots = [k.index for k in m if !k.occupied]

也就是说我还没有测试过……你的数据是作为那个图像还是另一个文件来的?

【讨论】:

  • 实际上,我尝试了装箱方法,使用这种方法几乎可以解决我的问题。我将(100 X 100 矩阵)中的交通量作为第一次拟合算法的输入,该算法将从矩阵中逐行读取输入并形成 bin 但大多数情况下我会得到直线或矩形作为 bin 形状但在我的情况下,理想的箱形是方形/圆形或六边形。此外,垃圾箱应该容纳连续的正方形,但是通过这种方法,我没有得到连续的垃圾箱/集群。关于它的任何输入如何处理这个?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-20
  • 2016-10-24
  • 2011-12-24
  • 1970-01-01
  • 2020-02-20
相关资源
最近更新 更多