Skip to content
assi
  • AI Chat
  • Code
  • Report
  • Spinner
    import random
    import numpy as np
    from typing import List
    class Item:
        def __init__(self, weight, value):
            self.weight = weight
            self.value = value
    CROSSOVER_RATE = 0.53
    MUTATION_RATE = 0.013
    REPLACE_RATE = 0.15
    items=[]
    class Individual:
        def __init__(self, bits: List[int]):
    
            self.bits = bits
        
        def __str__(self):
            return repr(self.bits)
    
        def __hash__(self):
            return hash(str(self.bits))
        
        def fitness(self) -> float:
            total_value = sum([
                bit * item.value
                for item, bit in zip(items, self.bits)
            ])
    
            total_weight = sum([
                bit * item.weight
                for item, bit in zip(items, self.bits)
            ])
    
            if total_weight <= CAPACITY:
                return total_value
            
            return 0
    
    
    
    
    
    def generate_initial_population(count=6) -> List[Individual]:
        population = set()
    
        # generate initial population having `count` individuals
        while len(population) != count:
            # pick random bits one for each item and 
            # create an individual 
            bits = [
                random.choice([0, 1])
                for _ in items
            ]
            population.add(Individual(bits))
    
        return list(population)
    
    
    def selection(population: List[Individual]) -> List[Individual]:
        props=[]
        parents = []
        total_fit=0
        for i in range (len(population)):
            total_fit=total_fit+population[i].fitness()
        for i in range(len(population)):
            fitpr=population[i]/total_fit
            props.append(fitpr)
            proparr = np.array(props)
        count=0
        while count!=(len(population)//2):
            parent1=np.random.choice(population,p=proparr,replace=False)
            parent2=np.random.choice(population,p=proparr,replace=False)
            if[parent1,parent2]not in parents:
                parents.append([parent1,parent2])
                count=count+1
        
        return parents
    
    
    def crossover(parents: List[Individual]) -> List[Individual]:
        r=random.randint(1,number_of_items)
        child1=parents[0].bits[:r]+parents[1].bits[r:]
        child2=parents[0].bits[r:]+parents[1].bits[:r]
        return [Individual(child1), Individual(child2)]
    
    
    def mutate(individuals: List[Individual]) -> List[Individual]:
        r=random.randint(1,number_of_items)
        if r<MUTATION_RATE:
            individuals.bits[r]=~individuals.bits[r]
           
    
    
    def next_generation(population: List[Individual]) -> List[Individual]:
        next_gen = []
        while len(next_gen) < len(population):
            children = []
    
            # we run selection and get parents
            parents = selection(population)
    
            # reproduction
            if random.random() < REPLACE_RATE:
                children = parents
            else:
                # crossover
                if random.random() < CROSSOVER_RATE:
                    children = crossover(parents)
                
                # mutation
                if random.random() < MUTATION_RATE:
                    mutate(children)
    
            next_gen.extend(children)
    
        return next_gen[:len(population)]
    
    
    def print_generation(population: List[Individual]):
        for individual in population:
            print(individual.bits, individual.fitness())
        print()
        print("Average fitness", sum([x.fitness() for x in population])/len(population))
        print("-" * 32)
    
    
    def average_fitness(population: List[Individual]) -> float:
        return sum([i.fitness() for i in population]) / len(population)
    
    
    def solve_knapsack() -> Individual:
        population = generate_initial_population()
    
        avg_fitnesses = []
    
        for _ in range(200):
            avg_fitnesses.append(average_fitness(population))
            population = next_generation(population)
    
        population = sorted(population, key=lambda i: i.fitness(), reverse=True)
        return population[0]
    
    
    if __name__ == '__main__':
        TEST_CASE=int(input('enter number of test cases'))
        for i in range(TEST_CASE):
           number_of_items=int(input('enter number of items'))
           CAPACITY = int(input('enter the capacity'))
           for i in range(number_of_items) :
              x,y=map(int, input().split())
              items.append(Item(x,y))
           solution = solve_knapsack()
           print(solution, solution.fitness())