示例#1
0
 def makechromosome(self):
     pages = solver_tools.Pagination(capacity)
     tiles = solver_tools.Batch(refTiles)
     firstFit(pages, tiles.getShuffledClone())
     result = [pages.pageIndexOfTile(tile) for tile in tiles]
     Individual.maxPageCount = max(
         max(result) + 1, Individual.maxPageCount)
     return result
示例#2
0
def run(testSet):
    pages = solver_tools.Pagination(testSet["capacity"], name)
    tiles = solver_tools.Batch(testSet["tiles"])
    for tile in tiles:
        for page in pages:
            if tile.canFitIn(page):
                page.add(tile)
                break
        else:
            pages.newPage(tile)
    return pages
示例#3
0
def run(testSet, maxPageCount=None, knownPaginations=[], **kargs):
    class Individual(genetic.Individual):

        optimization = "MINIMIZE"
        separator = ','
        maxPageCount = 0

        def makechromosome(self):
            pages = solver_tools.Pagination(capacity)
            tiles = solver_tools.Batch(refTiles)
            firstFit(pages, tiles.getShuffledClone())
            result = [pages.pageIndexOfTile(tile) for tile in tiles]
            Individual.maxPageCount = max(
                max(result) + 1, Individual.maxPageCount)
            return result

        def evaluate(self, optimum=None):
            symbolsOnPages = [[] for _ in xrange(Individual.maxPageCount)]
            for (tileIndex, pageIndex) in enumerate(self.chromosome):
                symbolsOnPages[pageIndex].extend(refTiles[tileIndex])
            page_costs = [len(set(symbols)) for symbols in symbolsOnPages]
            if max(page_costs) > capacity:
                self.score = invalidPenalty + sum(
                    max(0, n - capacity) for n in page_costs)
            else:
                for i in xrange(Individual.maxPageCount - 1, -1, -1):
                    if page_costs[i]:
                        self.score = page_costs[i] + i * capacity
                        break

        def mutate(self, gene):
            self.chromosome[gene] = random.randrange(Individual.maxPageCount)

    # tiles = solver_tools.Batch(testSet["tiles"])
    capacity = testSet["capacity"]
    refTiles = solver_tools.Batch(testSet["tiles"])
    Individual.length = len(refTiles)
    invalidPenalty = capacity * testSet["tileCount"]
    # if knownPaginations:
    #     maxPageCount = min(len(knownPagination) for knownPagination in knownPaginations if knownPagination.isValid())

    # for (knownPaginationIndex,knownPagination) in enumerate(knownPaginations):
    #     if knownPagination.isValid() and len(knownPagination) == maxPageCount:
    #         for (tileIndex,tile) in enumerate(tiles):
    #             env.population[knownPaginationIndex].chromosome[tileIndex] = knownPagination.pageIndexOfTile(tile)
    env = genetic.Environment(Individual, **kargs)
    env.run()

    pages = solver_tools.Pagination(testSet["capacity"], name)
    for _ in range(max(env.best.chromosome) + 1):
        pages.newPage()
    for (tileIndex, pageIndex) in enumerate(env.best.chromosome):
        pages[pageIndex].add(refTiles[tileIndex])
    return pages
示例#4
0
def run(testSet):
    pages = solver_tools.Pagination(testSet["capacity"], name)
    tiles = solver_tools.Batch(testSet["tiles"])
    for tile in tiles:
        candidates = [page for page in pages if tile.canFitIn(page)]
        if candidates:
            (minWeightedCost, bestPage) = min(
                (tile.weightedCostIn(page), page) for page in candidates)
            if minWeightedCost < len(tile):
                bestPage.add(tile)
            else:
                pages.newPage(tile)
        else:
            pages.newPage(tile)
    return pages
示例#5
0
 def makechromosome(self):
     pages = solver_tools.Pagination(capacity)
     tiles = solver_tools.Batch(refTiles)
     firstFit(pages, tiles.getShuffledClone())
     self.length = len(pages)
     return pages
示例#6
0
def run(testSet, **kargs):
    def mate(p1, left1, right1, p2, left2, right2):
        pages = solver_tools.Pagination(capacity)
        medianTiles = set(tile for i in xrange(left2, right2)
                          for tile in p2.chromosome[i])
        for i in xrange(0, left1):
            tilesToPlace = p1.chromosome[i].tileSet.difference(medianTiles)
            if tilesToPlace:
                pages.newPage(tilesToPlace)
        for i in xrange(left2, right2):
            pages.newPage(p2.chromosome[i])
        for i in xrange(right1, p1.length):
            tilesToPlace = p1.chromosome[i].tileSet.difference(medianTiles)
            if tilesToPlace:
                pages.newPage(tilesToPlace)
        pool = list(
            refTiles.difference(tile for page in pages for tile in page))
        pool.sort(key=lambda tile: tile.size, reverse=True)
        firstFit(pages, pool)
        child = Individual(pages)
        child.length = len(pages)
        return child

    class Individual(genetic.Individual):

        optimization = "MAXIMIZE"
        separator = ','

        def makechromosome(self):
            pages = solver_tools.Pagination(capacity)
            tiles = solver_tools.Batch(refTiles)
            firstFit(pages, tiles.getShuffledClone())
            self.length = len(pages)
            return pages

        def evaluate(self, optimum=None):
            # print self.length,
            self.score = sum((page.weight / maxPageWeight)**2
                             for page in self.chromosome) / self.length
            # NB. This should be equivalent to the faster formula:
            # self.score = sum(page.weight*page.weight for page in self.chromosome)/self.length/maxPageWeight/maxPageWeight
            # print self.score

        def mutate(self, gene):
            tiles = self.chromosome.pop(gene)
            firstFit(self.chromosome, tiles)
            self.length = len(self.chromosome)

        def crossover(self, other):
            if self is other or self.length < 3 or other.length < 3:
                return (self, other)
            left1 = random.randrange(1, self.length - 1)
            right1 = random.randrange(left1 + 1, self.length)
            left2 = random.randrange(1, other.length - 1)
            right2 = random.randrange(left2 + 1, other.length)
            return mate(self, left1, right1, other, left2,
                        right2), mate(other, left2, right2, self, left1,
                                      right1)

        def copy(self):
            twinPagination = solver_tools.Pagination(capacity)
            for page in self.chromosome:
                twinPagination.newPage(page)
            twin = Individual(twinPagination)
            twin.length = self.length
            twin.score = self.score
            # print "twin", twin.score
            return twin

    capacity = testSet["capacity"]
    refTiles = solver_tools.Batch(testSet["tiles"])
    maxPageWeight = float(
        sum(sorted(refTiles.weightBySymbol.values(), reverse=True)[:capacity]))
    pages = solver_tools.Pagination(capacity, name)
    env = genetic.Environment(Individual, **kargs)
    min_size_at_start = min(len(x.chromosome) for x in env.population)
    refTiles = set(tile for tile in refTiles)
    env.run()
    for page in env.best.chromosome:
        pages.newPage(page)
    return pages