Exemplo n.º 1
0
def gaVRPTW(pop,
            instName,
            unitCost,
            initCost,
            waitCost,
            delayCost,
            indSize,
            popSize,
            cxPb,
            mutPb,
            NGen,
            exportCSV=False,
            customizeData=False):
    if customizeData:
        jsonDataDir = os.path.join('data', 'json_customize')
    else:
        jsonDataDir = os.path.join('data', 'json')
    jsonFile = os.path.join(jsonDataDir, '%s.json' % instName)
    with open(jsonFile) as f:
        instance = load(f)

    # Operator registering
    toolbox.register('evaluate',
                     core.evalVRPTW,
                     instance=instance,
                     unitCost=unitCost,
                     initCost=initCost,
                     waitCost=waitCost,
                     delayCost=delayCost)
    toolbox.register('select', tools.selRoulette)
    toolbox.register('mate', core.cxPartialyMatched)
    toolbox.register('mutate', core.mutInverseIndexes)

    pop = pop
    print pop

    # Results holders for exporting results to CSV file
    csvData = []
    print 'Start of evolution'
    # Evaluate the entire population
    fitnesses = list(toolbox.map(toolbox.evaluate, pop))
    for ind, fit in zip(pop, fitnesses):
        ind.fitness.values = fit
    # Debug, suppress print()
    # print '  Evaluated %d individuals' % len(pop)
    # Begin the evolution
    for g in range(NGen):
        # print '-- Generation %d --' % g
        # Select the next generation individuals
        # Select elite - the best offspring, keep this past crossover/mutate
        elite = tools.selBest(pop, 1)
        # Keep top 10% of all offspring
        # Roulette select the rest 90% of offsprings
        offspring = tools.selBest(pop, int(numpy.ceil(len(pop) * 0.1)))
        offspringRoulette = toolbox.select(
            pop,
            int(numpy.floor(len(pop) * 0.9)) - 1)
        offspring.extend(offspringRoulette)
        # Clone the selected individuals
        offspring = list(toolbox.map(toolbox.clone, offspring))
        # Apply crossover and mutation on the offspring
        for child1, child2 in zip(offspring[::2], offspring[1::2]):
            if random.random() < cxPb:
                toolbox.mate(child1, child2)
                del child1.fitness.values
                del child2.fitness.values
        for mutant in offspring:
            if random.random() < mutPb:
                toolbox.mutate(mutant)
                del mutant.fitness.values
        # Evaluate the individuals with an invalid fitness
        invalidInd = [ind for ind in offspring if not ind.fitness.valid]
        fitnesses = toolbox.map(toolbox.evaluate, invalidInd)
        for ind, fit in zip(invalidInd, fitnesses):
            ind.fitness.values = fit
        # Debug, suppress print()
        # print '  Evaluated %d individuals' % len(invalidInd)
        # The population is entirely replaced by the offspring
        offspring.extend(elite)
        pop[:] = offspring
        # Gather all the fitnesses in one list and print the stats
        fits = [ind.fitness.values[0] for ind in pop]
        length = len(pop)
        mean = sum(fits) / length
        sum2 = sum(x * x for x in fits)
        std = abs(sum2 / length - mean**2)**0.5
        # Debug, suppress print()
        # print '  Min %s' % min(fits)
        # print '  Max %s' % max(fits)
        # print '  Avg %s' % mean
        # print '  Std %s' % std
        # Write data to holders for exporting results to CSV file
        if exportCSV:
            csvRow = {
                'generation': g,
                'evaluated_individuals': len(invalidInd),
                'min_fitness': min(fits),
                'max_fitness': max(fits),
                'avg_fitness': mean,
                'std_fitness': std,
                'avg_cost': 1 / mean,
            }
            csvData.append(csvRow)
    print '-- End of (successful) evolution --'
    bestInd = tools.selBest(pop, 1)[0]
    print 'Best individual: %s' % bestInd
    print 'Fitness: %s' % bestInd.fitness.values[0]
    core.printRoute(core.ind2route(bestInd, instance))
    print 'Total cost: %s' % (1 / bestInd.fitness.values[0])
    if exportCSV:
        csvFilename = '%s_uC%s_iC%s_wC%s_dC%s_iS%s_pS%s_cP%s_mP%s_nG%s.csv' % (
            instName, unitCost, initCost, waitCost, delayCost, indSize,
            popSize, cxPb, mutPb, NGen)
        csvPathname = os.path.join('results', csvFilename)
        print 'Write to file: %s' % csvPathname
        utils.makeDirsForFile(pathname=csvPathname)
        if not utils.exist(pathname=csvPathname, overwrite=True):
            with open(csvPathname, 'w') as f:
                fieldnames = [
                    'generation', 'evaluated_individuals', 'min_fitness',
                    'max_fitness', 'avg_fitness', 'std_fitness', 'avg_cost'
                ]
                writer = DictWriter(f, fieldnames=fieldnames, dialect='excel')
                writer.writeheader()
                for csvRow in csvData:
                    writer.writerow(csvRow)
    return core.ind2route(bestInd, instance)
Exemplo n.º 2
0
toolbox.register('population', tools.initRepeat, list, toolbox.individual)
toolbox.register('select', tools.selRoulette)
toolbox.register('evaluate',
                 evalVRPTW,
                 instance=instance,
                 unitCost=1.0,
                 initCost=0)

optimalRoute = [[21, 31, 19, 17, 13, 7, 26], [12, 1, 16, 30], [27, 24],
                [29, 18, 8, 9, 22, 15, 10, 25, 5, 20],
                [14, 28, 11, 4, 23, 3, 2, 6]]

individual2 = [
    5, 10, 15, 22, 9, 11, 28, 18, 6, 3, 2, 17, 19, 31, 21, 13, 23, 4, 8, 29,
    27, 14, 24, 30, 16, 12, 1, 7, 26, 25, 20
]
route2 = ind2route(individual2, instance)

individual = [
    21, 31, 19, 17, 13, 7, 26, 12, 1, 16, 30, 27, 24, 29, 18, 8, 9, 22, 15, 10,
    25, 5, 20, 14, 28, 11, 4, 23, 3, 2, 6
]
route = ind2route(individual, instance)

utils.visualizeRoutes(instName, instance, optimalRoute)

# Due to the way EvalVRP is written, a vehicle needs to exceed max capacity before
# starting a new vehicle. The optimal route leaves certain vehicles below capacity
# and therefore gives even more optimal (smaller) costs
# The optimal cost of this route in literature is 784
# My evalVRP code reads this route's cost as 1030