예제 #1
0
    def generate(self):
        #先生成地图,记录某些格子里已经放置了多少个点
        for i in range(0, self.areaWidth):
            self.map.append([])  #放行   append() 方法用于在列表末尾添加新的对象。
        for i in range(0, self.areaWidth):
            for j in range(0, self.areaWidth):
                self.map[i].append(0)

        flag = 0
        while flag == 0:
            #恢复一些记录参数start
            self.vertexSet.clear()
            self.edgeSet.clear()
            for i in range(0, self.areaWidth):
                for j in range(0, self.areaWidth):
                    self.map[i][j] = 0

            maxNumberInColumn = int(math.sqrt(self.vertexCount))  #一列最多放置的节点个数
            column = 0  #当前放到第几列
            placedNumber = 0  #当前列已经放了多少个节点
            # 恢复一些记录参数end

            #不均匀网络,放洞(圆心,半径之内无法放点)

            #      Cx=random.randint(0,self.areaWidth)
            #      Cy=random.randint(0,self.areaWidth)
            for i in range(0, self.vertexCount):
                # 先生成点在的格子坐标
                emptyLoc = []  #空余位置
                for y in range(0, self.areaWidth):
                    if self.map[y][column] == 0:
                        #   if math.sqrt(numpy.square(abs(y-Cx))+numpy.square(abs(column-Cy)))>self.r:   #黑洞外
                        emptyLoc.append((y, column))

                #一列最多的放置节点数
                if len(emptyLoc) < maxNumberInColumn:
                    max = len(emptyLoc) / 2
                else:
                    max = maxNumberInColumn

                index = random.randint(0,
                                       len(emptyLoc) -
                                       1)  #产生离散均匀分布的整数,这些整数大于等于low,小于high
                x = emptyLoc[index][1]
                y = emptyLoc[index][0]

                self.map[y][x] = self.map[y][x] + 1

                vertex = Vertex('R' + str(i))
                vertex.setX(x)
                vertex.setY(y)
                self.vertexSet.append(vertex)

                placedNumber = placedNumber + 1
                if placedNumber >= max:
                    column = column + 1  #此时此列不可再放置节点
                    placedNumber = 0

            #寻找所有的点中最左边的那些点的X坐标,以便决定S节点的放置位置
            minx = self.areaWidth - 1
            maxx = 0
            for v in self.vertexSet:
                if v.getX() < minx:
                    minx = v.getX()
                if v.getX() > maxx:
                    maxx = v.getX()
#X轴最左和最右的点集合
            leftVertexSet = []
            rightVertexSet = []
            for v in self.vertexSet:
                if v.getX() == minx:
                    leftVertexSet.append(v)
                if v.getX() == maxx:
                    rightVertexSet.append(v)

            index = random.randint(0, len(leftVertexSet) - 1)  #随机数
            randomY = leftVertexSet[index].getY()
            #此时minx与randomY即为S节点的放置位置
            vertex = Vertex('S')
            vertex.setX(minx)
            vertex.setY(randomY)
            self.vertexSet.append(vertex)  #加入S节点

            index = random.randint(0, len(rightVertexSet) - 1)
            randomY = rightVertexSet[index].getY()
            #此时maxx和randomY即为D节点的放置位置
            vertex = Vertex('D')
            vertex.setX(maxx)
            vertex.setY(randomY)
            self.vertexSet.append(vertex)  # 加入D节点

            #首先确认同一个格子里是否存在多于1个点,如果存在,那么直接重新生成图
            '''flag = 1
            for vi in self.vertexSet:
                for vj in self.vertexSet:
                    if vi.getID() != vj.getID() and vi.getX() == vj.getX() and vi.getY() == vj.getY():
                        flag = 0
                        break
                if flag == 0:
                    break
            if flag == 0:
                continue'''

            #点集已经构造完成,接下来构造边集
            for vi in self.vertexSet:
                for vj in self.vertexSet:
                    if vi.getID() != vj.getID():
                        if abs(vi.getX() - vj.getX()) <= 1 and abs(
                                vi.getY() - vj.getY()) <= 1:
                            #说明vi和vj连通
                            edge = Edge(vi, vj)
                            self.edgeSet.append(edge)

            #接下来利用点集和边集构造图,确认图的有效性
            g = Graph(self.vertexSet, self.edgeSet)
            flag = 1
            for vi in self.vertexSet:
                if vi.getID() != 'D':
                    if g.find_path(vi.getID(), 'D', []) is None:
                        flag = 0  #代表生成的图无效,因为有节点不能联通sink
                        break

            #print('flag: '+str(flag))

            #接下来确定路径个数不能过多,如果过多,图无效
            if flag != 0:
                pathSet = g.find_all_paths('S', 'D', [])
                print('生成路径条数检验: ' + str(len(pathSet)))
                if len(pathSet) > self.vertexCount * 20 or len(
                        pathSet) < self.vertexCount * 5:
                    #if len(pathSet) > self.vertexCount * 10 or len(pathSet) < self.vertexCount :
                    flag = 0  #路径的个数太多或太少,不合适