input: Write a python function to perform an optimization using a simple evolutionary algorithm.
  assert len(perform_optimization(20, 100)) == 20
  assert all(isinstance(x, int) for x in perform_optimization(10, 50))
  assert perform_optimization(30, 200) != perform_optimization(30, 200)
output: import random
  
  def perform_optimization(population_size, generations):
      def fitness(individual):
          return sum(individual)
      
      def generate_individual():
          return [random.randint(0, 1) for _ in range(10)]
      
      def mutate(individual):
          idx = random.randint(0, len(individual) - 1)
          individual[idx] = 1 - individual[idx]
          return individual
      
      def crossover(parent1, parent2):
          idx = random.randint(1, len(parent1) - 2)
          return parent1[:idx] + parent2[idx:]
      
      population = [generate_individual() for _ in range(population_size)]
      
      for _ in range(generations):
          population = sorted(population, key=fitness, reverse=True)
          new_population = population[:population_size // 2]
          
          while len(new_population) < population_size:
              if random.random() < 0.7:
                  parent1, parent2 = random.sample(new_population, 2)
                  offspring = crossover(parent1, parent2)
              else:
                  parent1 = random.choice(new_population)
                  offspring = mutate(parent1)
              new_population.append(offspring)
          
          population = new_population
      
      return [sum(ind) for ind in population]