Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

No funciona :( #11

Open
jmarcellopereira opened this issue Aug 3, 2021 · 1 comment
Open

No funciona :( #11

jmarcellopereira opened this issue Aug 3, 2021 · 1 comment

Comments

@jmarcellopereira
Copy link

jmarcellopereira commented Aug 3, 2021

No funciona :(. Falta el archivo "exnsd16.ukp", sitio inactivo. El código de muestra tampoco funciona. ¿Me pueden ayudar?

import datetime
import random
import sys
import unittest
import genetic

class Resource:
    Name = None
    Value = None
    Weight = None
    Volume = None
    def __init__(self, name, value, weight, volume):
        self.Name = name
        self.Value = value
        self.Weight = weight
        self.Volume = volume


class ItemQuantity:
    Item = None
    Quantity = None
    def __init__(self, item, quantity):
        self.Item = item
        self.Quantity = quantity
    def __eq__(self, other):
        return self.Item == other.Item and self.Quantity == other.Quantity

class Fitness:
    TotalWeight = None
    TotalVolume = None
    TotalValue = None
    
    def __init__(self, totalWeight, totalVolume, totalValue):
        self.TotalWeight = totalWeight
        self.TotalVolume = totalVolume
        self.TotalValue = totalValue
        
    def __gt__(self, other):
        return self.TotalValue > other.TotalValue
    
    def __str__(self):
        return "wt: {0:0.2f} vol: {1:0.2f} value: {2}".format( self.TotalWeight, self.TotalVolume, self.TotalValue)
    
def get_fitness(genes):
    totalWeight = 0
    totalVolume = 0
    totalValue = 0
    
    for iq in genes:
        count = iq.Quantity
        totalWeight += iq.Item.Weight * count
        totalVolume += iq.Item.Volume * count
        totalValue += iq.Item.Value * count
        
    return Fitness(totalWeight, totalVolume, totalValue)

def max_quantity(item, maxWeight, maxVolume):
    return min(int(maxWeight / item.Weight)
        if item.Weight > 0 else sys.maxsize, int(maxVolume / item.Volume)
        if item.Volume > 0 else sys.maxsize)
        
def create(items, maxWeight, maxVolume):
    genes = []
    remainingWeight, remainingVolume = maxWeight, maxVolume
    
    for i in range(random.randrange(1, len(items))):
        newGene = add(genes, items, remainingWeight, remainingVolume)
        if newGene is not None:
            genes.append(newGene)
            remainingWeight -= newGene.Quantity * newGene.Item.Weight
            remainingVolume -= newGene.Quantity * newGene.Item.Volume
            
    return genes


def add(genes, items, maxWeight, maxVolume):
    usedItems = {iq.Item for iq in genes}
    item = random.choice(items)
    
    while item in usedItems:
        item = random.choice(items)

    maxQuantity = max_quantity(item, maxWeight, maxVolume)
    return ItemQuantity(item, maxQuantity) if maxQuantity > 0 else None

def mutate(genes, items, maxWeight, maxVolume, window):
    window.slide()
    fitness = get_fitness(genes)
    remainingWeight = maxWeight - fitness.TotalWeight
    remainingVolume = maxVolume - fitness.TotalVolume

    removing = len(genes) > 1 and random.randint(0, 10) == 0
    if removing:
        index = random.randrange(0, len(genes))
        iq = genes[index]
        item = iq.Item
        remainingWeight += item.Weight * iq.Quantity
        remainingVolume += item.Volume * iq.Quantity
        del genes[index]

    adding = (remainingWeight > 0 or remainingVolume > 0) and (len(genes) == 0 or (len(genes) < len(items) and random.randint(0, 100) == 0))

    if adding:
        newGene = add(genes, items, remainingWeight, remainingVolume)
        if newGene is not None:
            genes.append(newGene)
            return

    index = random.randrange(0, len(genes))
    iq = genes[index]
    item = iq.Item
    remainingWeight += item.Weight * iq.Quantity
    remainingVolume += item.Volume * iq.Quantity

    changeItem = len(genes) < len(items) and random.randint(0, 4) == 0
    if changeItem:
        itemIndex = items.index(iq.Item)
        start = max(1, itemIndex - window.Size)
        stop = min(len(items) - 1, itemIndex + window.Size)
        item = items[random.randint(start, stop)]
    maxQuantity = max_quantity(item, remainingWeight, remainingVolume)
    
    if maxQuantity > 0:
        genes[index] = ItemQuantity(item, maxQuantity
        if window.Size > 1 else random.randint(1, maxQuantity))
    else:
        del genes[index]

def display(candidate, startTime):
    timeDiff = datetime.datetime.now() - startTime
    genes = candidate.Genes[:]
    genes.sort(key=lambda iq: iq.Quantity, reverse=True)

    descriptions = [str(iq.Quantity) + "x" + iq.Item.Name for iq in genes]
    
    if len(descriptions) == 0:
        descriptions.append("Empty")
    print("{}\t{}\t{}".format(', '.join(descriptions), candidate.Fitness, timeDiff))



def fill_knapsack(self, items, maxWeight, maxVolume, optimalFitness):
    startTime = datetime.datetime.now()
    
    def fnDisplay(candidate):
        display(candidate, startTime)
        
    def fnGetFitness(genes):
        return get_fitness(genes)
    
    def fnCreate():
        return create(items, maxWeight, maxVolume)
    
    def fnMutate(genes):
        mutate(genes, items, maxWeight, maxVolume)    
        
    best = genetic.get_best(fnGetFitness, None, optimalFitness, None, fnDisplay, fnMutate, fnCreate, maxAge=50)
    self.assertTrue(not optimalFitness > best.Fitness)
    
def test_cookies(self):
    items = [
        Resource("Flour", 1680, 0.265, .41),
        Resource("Butter", 1440, 0.5, .13),
        Resource("Sugar", 1840, 0.441, .29)
    ]
    
    maxWeight = 10
    maxVolume = 4
    
    optimal = get_fitness(
            [ItemQuantity(items[0], 1),
             ItemQuantity(items[1], 14),
             ItemQuantity(items[2], 6)])
    self.fill_knapsack(items, maxWeight, maxVolume, optimal)

unittest.main()
@handcraftsman
Copy link
Owner

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants