コード例 #1
0
    def __init__(self, size, n):
        self.__map = list()

        for y in range(0, size):
            row = list()
            for x in range(0, size):
                temp = dict(connected=list())
                row.append(temp)
            self.__map.append(row)

        self.__dset = DSet(size * size)
        self.__size = size
        self.__edges = []
        self.__first = (-1, -1)
        self.generate(n)
        self.__edgeList = self.makeEdgeList()
コード例 #2
0
ファイル: mapColoring.py プロジェクト: seadraa/CS440-AI
    def __init__(self, size, n):
        self.__map = list()

        for y in range(0, size):
            row = list()
            for x in range(0, size):
                temp = dict(connected=list())
                row.append(temp)
            self.__map.append(row)

        self.__dset = DSet(size * size)
        self.__size = size
        self.__edges = []
        self.__first = (-1, -1)
        self.generate(n)
        self.__edgeList = self.makeEdgeList()
コード例 #3
0
ファイル: mapColoring.py プロジェクト: seadraa/CS440-AI
class Map:

    def __init__(self, size, n):
        self.__map = list()

        for y in range(0, size):
            row = list()
            for x in range(0, size):
                temp = dict(connected=list())
                row.append(temp)
            self.__map.append(row)

        self.__dset = DSet(size * size)
        self.__size = size
        self.__edges = []
        self.__first = (-1, -1)
        self.generate(n)
        self.__edgeList = self.makeEdgeList()

    def getInitialPoint(self):
        return self.__first

    def getEdges(self, point):
        return self.__edgeList[str(point)]

    def generate(self, _n):
        self.__first = first = self.__getPoint()
        self.n = n = _n
        vertices = Set()

        while (n):
            second = self.__findClosestPoint(first)

            if not second in vertices:
                n -= 1
                vertices.add(second)

            if not second == (-1,-1):
                self.__dset.union(first[1] * self.__size + first[0], second[1] * self.__size + second[0])

                self.__map[first[0]][first[1]]['connected'].append(second)
                self.__map[second[0]][second[1]]['connected'].append(first)

                self.__edges.append((first, second))
                first = second
            else:
                break

    def printJSON(self, filename):
        for row in self.__map:
            for elem in row:
                print elem,
            print ""

        for segment in self.__edges:
            print str(segment[0]) + "->" + str(segment[1])

        with open(filename, 'w') as f:
            graph = list()
            output = {}

            output['size'] = self.__size
            for row in self.__map:
                for elem in row:
                    graph.append(elem)

            output['graph'] = graph
            output['edges'] = self.makeEdgeList()

            f.write(json.dumps(output))

            pp = pprint.PrettyPrinter(indent=4)
            pp.pprint(output)

        graphPNG = []
        offset = 20
        for y in range(0, self.__size * offset):
            temp = []
            for x in range(0, self.__size * offset):
                temp.append(255)
            graphPNG.append(temp)

        edgeList = self.makeEdgeList()

        for vertex, edges in edgeList.iteritems():
            points = vertex.strip('(,)')
            points = points.split(' ')
            points[0] = points[0][0:1]

            for y in range(int(points[0]) * offset + 5, offset * (int(points[0]) + 1) - 5):
                for x in range(int(points[1]) * offset + 5, offset * (int(points[1]) + 1) - 5):
                    graphPNG[x][y] = 0

            for edge in edges:
                print points
                points[0] = int(points[0])
                points[1] = int(points[1])
                points[0] = points[0] * offset + offset/10
                points[1] = points[1] * offset + offset/10

                temp = [''] * 2
                temp[0] = edge[0] * offset + offset/10
                temp[1] = edge[1] * offset + offset/10

                edge = temp

                denom = (edge[0] - points[0])

                if (denom == 0):
                    slopeX = 0
                else:
                    slopeX = (edge[1] - points[1])/(edge[0] - points[0])

                print points,
                print ' destination ',
                print temp
                if (slopeX == 0):
                    slopeY = 1
                else:
                    slopeY = 1/slopeX
                currX = points[0]
                currY = points[1]

                while (not int(currX) == edge[0] and not int(currY) == edge[1]):
                    currX += slopeX
                    currY += slopeY

                    # print str(currX) + ', ' + str(currY) + ' destination is ' + str(temp) + ' and slope is ' + str(slopeX)
                    graphPNG[int(currX)][int(currY)] = 0

                png.from_array(graphPNG, 'L').save(filename.strip('.json') + '.png')

            return

    def makeEdgeList(self):
        edgeList = {}
        for edge in self.__edges:
            if not str(edge[0]) in edgeList:
                edgeList[str(edge[0])] = list()
            edgeList[str(edge[0])].append(edge[1])

            if not str(edge[1]) in edgeList:
                edgeList[str(edge[1])] = list()
            edgeList[str(edge[1])].append(edge[0])

        return edgeList

    def getCoordinate(self, coord):
        return coord[1] * self.__size + coord[0]

    def __findClosestPoint(self, first):
        nextPoint = Queue()
        nextPoint.put(first)
        visited = Set()

        while not nextPoint.empty():
            temp = nextPoint.get()

            # If already visited then you don't want to visit it again
            if temp in visited:
                continue

            visited.add(temp)

            if not temp == first:
                # If not connected and doesn't intersect
                if (not self.connected(first, temp) and
                    not self.doesIntersect(first, temp)):
                    return temp

            if temp[0] - 1 >= 0 and temp[1] - 1 >= 0:
                nextPoint.put((temp[0] - 1, temp[1] - 1))
            if temp[0] - 1 >= 0 and temp[1] + 1 < self.__size:
                nextPoint.put((temp[0] - 1, temp[1] + 1))
            if temp[0] + 1 < self.__size and temp[1] - 1 >= 0:
                nextPoint.put((temp[0] + 1, temp[1] - 1))
            if temp[0] + 1 < self.__size and temp[1] + 1 < self.__size:
                nextPoint.put((temp[0] + 1, temp[1] + 1))
            if temp[1] + 1 < self.__size:
                nextPoint.put((temp[0], temp[1] + 1))
            if temp[0] + 1 < self.__size:
                nextPoint.put((temp[0] + 1, temp[1]))
            if temp[1] - 1 >= 0:
                nextPoint.put((temp[0], temp[1] - 1))
            if temp[0] - 1 >= 0:
                nextPoint.put((temp[0] - 1, temp[1]))

        return (-1,-1)

    # Returns true if first or second is in the respective connected list
    # False if its not in either one
    def connected(self, first, second):
        return (first in self.__map[second[0]][second[1]]['connected'] or
                second in self.__map[first[0]][first[1]]['connected'])

    def __getPoint(self):
        x = random.randint(0, self.__size - 1)
        y = random.randint(0, self.__size - 1)

        return (x, y)

    # From http://paulbourke.net/geometry/pointlineplane/
    def doesIntersect(self, start, end):
        mua = 0.0
        mub = 0.0

        denom = 0.0
        numera = 0.0
        numerb = 0.0

        x1 = start[0]
        y1 = start[1]

        x2 = end[0]
        y2 = end[1]

        EPS = 0.0
        intersect = False

        for edge in self.__edges:
            x3 = edge[0][0]
            y3 = edge[0][1]

            x4 = edge[1][0]
            y4 = edge[1][0]

            denom = (y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1)
            numera = (x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3)
            numerb = (x2 - x1) * (y1 - y3) - (y2 - y1) * (x1 - x3)

            if (abs(numera) <= EPS and
                abs(numerb) <= EPS and
                abs(denom) <= EPS):
                return True

            if (abs(denom) <= EPS):
                continue
            else:
                mua = numera/denom
                mub = numerb/denom

                if (mua < 0 or mua > 1 or mub < 0 or mub > 1):
                    continue
            return False

        return intersect
コード例 #4
0
class Map:
    def __init__(self, size, n):
        self.__map = list()

        for y in range(0, size):
            row = list()
            for x in range(0, size):
                temp = dict(connected=list())
                row.append(temp)
            self.__map.append(row)

        self.__dset = DSet(size * size)
        self.__size = size
        self.__edges = []
        self.__first = (-1, -1)
        self.generate(n)
        self.__edgeList = self.makeEdgeList()

    def getInitialPoint(self):
        return self.__first

    def getEdges(self, point):
        return self.__edgeList[str(point)]

    def generate(self, _n):
        self.__first = first = self.__getPoint()
        self.n = n = _n
        vertices = Set()

        while (n):
            second = self.__findClosestPoint(first)

            if not second in vertices:
                n -= 1
                vertices.add(second)

            if not second == (-1, -1):
                self.__dset.union(first[1] * self.__size + first[0],
                                  second[1] * self.__size + second[0])

                self.__map[first[0]][first[1]]['connected'].append(second)
                self.__map[second[0]][second[1]]['connected'].append(first)

                self.__edges.append((first, second))
                first = second
            else:
                break

    def printJSON(self, filename):
        for row in self.__map:
            for elem in row:
                print elem,
            print ""

        for segment in self.__edges:
            print str(segment[0]) + "->" + str(segment[1])

        with open(filename, 'w') as f:
            graph = list()
            output = {}

            output['size'] = self.__size
            for row in self.__map:
                for elem in row:
                    graph.append(elem)

            output['graph'] = graph
            output['edges'] = self.makeEdgeList()

            f.write(json.dumps(output))

            pp = pprint.PrettyPrinter(indent=4)
            pp.pprint(output)

        graphPNG = []
        offset = 20
        for y in range(0, self.__size * offset):
            temp = []
            for x in range(0, self.__size * offset):
                temp.append(255)
            graphPNG.append(temp)

        edgeList = self.makeEdgeList()

        for vertex, edges in edgeList.iteritems():
            points = vertex.strip('(,)')
            points = points.split(' ')
            points[0] = points[0][0:1]

            for y in range(
                    int(points[0]) * offset + 5,
                    offset * (int(points[0]) + 1) - 5):
                for x in range(
                        int(points[1]) * offset + 5,
                        offset * (int(points[1]) + 1) - 5):
                    graphPNG[x][y] = 0

            for edge in edges:
                print points
                points[0] = int(points[0])
                points[1] = int(points[1])
                points[0] = points[0] * offset + offset / 10
                points[1] = points[1] * offset + offset / 10

                temp = [''] * 2
                temp[0] = edge[0] * offset + offset / 10
                temp[1] = edge[1] * offset + offset / 10

                edge = temp

                denom = (edge[0] - points[0])

                if (denom == 0):
                    slopeX = 0
                else:
                    slopeX = (edge[1] - points[1]) / (edge[0] - points[0])

                print points,
                print ' destination ',
                print temp
                if (slopeX == 0):
                    slopeY = 1
                else:
                    slopeY = 1 / slopeX
                currX = points[0]
                currY = points[1]

                while (not int(currX) == edge[0]
                       and not int(currY) == edge[1]):
                    currX += slopeX
                    currY += slopeY

                    # print str(currX) + ', ' + str(currY) + ' destination is ' + str(temp) + ' and slope is ' + str(slopeX)
                    graphPNG[int(currX)][int(currY)] = 0

                png.from_array(graphPNG,
                               'L').save(filename.strip('.json') + '.png')

            return

    def makeEdgeList(self):
        edgeList = {}
        for edge in self.__edges:
            if not str(edge[0]) in edgeList:
                edgeList[str(edge[0])] = list()
            edgeList[str(edge[0])].append(edge[1])

            if not str(edge[1]) in edgeList:
                edgeList[str(edge[1])] = list()
            edgeList[str(edge[1])].append(edge[0])

        return edgeList

    def getCoordinate(self, coord):
        return coord[1] * self.__size + coord[0]

    def __findClosestPoint(self, first):
        nextPoint = Queue()
        nextPoint.put(first)
        visited = Set()

        while not nextPoint.empty():
            temp = nextPoint.get()

            # If already visited then you don't want to visit it again
            if temp in visited:
                continue

            visited.add(temp)

            if not temp == first:
                # If not connected and doesn't intersect
                if (not self.connected(first, temp)
                        and not self.doesIntersect(first, temp)):
                    return temp

            if temp[0] - 1 >= 0 and temp[1] - 1 >= 0:
                nextPoint.put((temp[0] - 1, temp[1] - 1))
            if temp[0] - 1 >= 0 and temp[1] + 1 < self.__size:
                nextPoint.put((temp[0] - 1, temp[1] + 1))
            if temp[0] + 1 < self.__size and temp[1] - 1 >= 0:
                nextPoint.put((temp[0] + 1, temp[1] - 1))
            if temp[0] + 1 < self.__size and temp[1] + 1 < self.__size:
                nextPoint.put((temp[0] + 1, temp[1] + 1))
            if temp[1] + 1 < self.__size:
                nextPoint.put((temp[0], temp[1] + 1))
            if temp[0] + 1 < self.__size:
                nextPoint.put((temp[0] + 1, temp[1]))
            if temp[1] - 1 >= 0:
                nextPoint.put((temp[0], temp[1] - 1))
            if temp[0] - 1 >= 0:
                nextPoint.put((temp[0] - 1, temp[1]))

        return (-1, -1)

    # Returns true if first or second is in the respective connected list
    # False if its not in either one
    def connected(self, first, second):
        return (first in self.__map[second[0]][second[1]]['connected']
                or second in self.__map[first[0]][first[1]]['connected'])

    def __getPoint(self):
        x = random.randint(0, self.__size - 1)
        y = random.randint(0, self.__size - 1)

        return (x, y)

    # From http://paulbourke.net/geometry/pointlineplane/
    def doesIntersect(self, start, end):
        mua = 0.0
        mub = 0.0

        denom = 0.0
        numera = 0.0
        numerb = 0.0

        x1 = start[0]
        y1 = start[1]

        x2 = end[0]
        y2 = end[1]

        EPS = 0.0
        intersect = False

        for edge in self.__edges:
            x3 = edge[0][0]
            y3 = edge[0][1]

            x4 = edge[1][0]
            y4 = edge[1][0]

            denom = (y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1)
            numera = (x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3)
            numerb = (x2 - x1) * (y1 - y3) - (y2 - y1) * (x1 - x3)

            if (abs(numera) <= EPS and abs(numerb) <= EPS
                    and abs(denom) <= EPS):
                return True

            if (abs(denom) <= EPS):
                continue
            else:
                mua = numera / denom
                mub = numerb / denom

                if (mua < 0 or mua > 1 or mub < 0 or mub > 1):
                    continue
            return False

        return intersect