9

I have a problem using sorted() method. I am using this method inside a loop to sort a list which I am upgrading in every step of the loop. The first iteration works but the second an beyond doesn't and give me the next error:

ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all() 

Here is my code:

import numpy as np
import random as rd
import math

Poblacion = 10
pressure = int(0.3*Poblacion)
mutation_chance = 0.08

Modelo = np.array([[0.60,0.40,0.90],[0.26,0.20,0.02],[0.80,0.00,0.05]])

x = np.array([[1.0,2.0,3.0],[0.70,0.50,0.90],[0.10,0.40,0.20]])
y = np.array([[4.10,0.72,2.30],[1.43,0.30,1.01],[0.40,0.11,0.18]])

def crearIndividuo():
    return[np.random.random((3, 3))]

def crearPoblacion(): 
    return [crearIndividuo() for i in range(Poblacion)]

def calcularFitness(individual): 
    error = 0
    i=0
    for j in x:
        error += np.array(individual).dot(j)-y[i]
        i += 1
        error = np.linalg.norm(error,ord=1) 
        fitness = math.exp(-error)
    return fitness

def selection_and_reproduction(population):
    puntuados = [ (calcularFitness(i), i) for i in population] 
    puntuados = [i[1] for i in sorted(puntuados)] 
    population = puntuados

    selected =  puntuados[(len(puntuados)-pressure):] 

    j=0
    while (j < int(len(population)-pressure)):
        padre = rd.sample(selected, 2)

        population[j] = 0.5*(np.array(padre[0]) + np.array(padre[1]))
        j += 1
        population[j] = 1.5*np.array(padre[0]) - 0.5*np.array(padre[1])
        j += 1
        population[j] = -0.5*np.array(padre[0]) + 1.5*np.array(padre[1])
        j += 1
    return population

population = crearPoblacion()

for l in range(3):
    population = selection_and_reproduction(population)

print("final population: ", population)

The error occurs in the line:

puntuados = [i[1] for i in sorted(puntuados)] 

I can't figure out what I m doing wrong (I am not an expert in python). Can anyone help me?

Thanks in advance.

Patrick Haugh
  • 59,226
  • 13
  • 88
  • 96
Ivanovitch
  • 358
  • 1
  • 2
  • 10
  • It seems like `puntuados` is a list of tuples. Refer [this SO question](https://stackoverflow.com/questions/3121979/how-to-sort-list-tuple-of-lists-tuples) to see how to use `sorted` correctly. – Stuti Rastogi Feb 18 '18 at 22:21
  • This error is raised when a boolean array is used in a context that requires a simple True/False value. Here it appears to be the comparison required for sorting. A test like `x – hpaulj Feb 18 '18 at 22:52
  • Notice that the sidebar shows many SO questions about the same error message. Pay special attention to how `puntuados` changes from one iteration to the next. What was it like when it worked, and was different when it didn't. – hpaulj Feb 18 '18 at 23:11
  • @hpaulj I used "type(puntuados)" and its give me "" in both iterations. I also checked the type and len of pupolation (it give me a list and len=10 in both iterations). Also sometimes the code can complete the second iteration just to get stuck in the third one. – Ivanovitch Feb 19 '18 at 13:46
  • 1
    @StutiRastogi thanks a lot! that post help me to solve my problem. – Ivanovitch Feb 19 '18 at 15:34

1 Answers1

13

The problem arises where the tuples share the same first element, so

sorted(puntuados)

has to compare the second elements of the two tuples to determine their relative order, at which point you encounter this exception.

You can use

sorted(graded, key=lambda x: x[0])

to solve your problem, if you only want to sort based on the first element of the tuples.

Saeid SOHEILY KHAH
  • 747
  • 3
  • 10
  • 23