0

I'm quite new to Python but this is strange. So, I have a matrix (a list of lists) and I pass it to a function (creaMatrixVNS).

def creaMatrixVNS(best_matrice, time):
    matrice = best_matrice
    sol_init_ass = assegnamento(matrice)

    iteration = 1 #numero swap
    counter = 0 #numero iterazioni

    while True:
            temp = matrice

From this point

            for x in xrange(0,iteration):
                    temp = swap(temp, sol_init_ass)

to this point, I see that my variable matrice changes and is set to the value of temp. And I don't know why. That's the second part of the function.

            time2 = creaSoluzione(temp)

            if time2 < time:
                    time = time2
                    matrice = temp
                    if counter == 9:
                            break
                    else:
                            counter += 1
            else:
                    if iteration < 3:
                            iteration += 1
                            counter = 0
                    else:
                            break

    print(time)
    return matrice

Other functions:

def swap(matriceInput, lista):
        result = matriceInput

        i1, j1 = giveMeAcouple(lista)
        i2, j2 = giveMeAcouple(lista)

        while i1 == i2 and j1 == j2:
                i1, j1 = giveMeAcouple(lista)
                i2, j2 = giveMeAcouple(lista)

        result[i1][j1], result[i2][j2] = result[i2][j2], result[i1][j1]

        return result

def giveMeAcouple(sol_init_ass):
        j1 = randint(0,len(sol_init_ass)-1)
        while len(sol_init_ass[j1]) <= 0:
                j1 = randint(0,len(sol_init_ass)-1)

        i1 = randint(0,len(sol_init_ass[j1]) - 1)

        return sol_init_ass[j1][i1], j1


def assegnamento(matrice):
        listElementi = []
        temp = []
        n = len(matrice)
        m = len(matrice[0])

        for i in xrange(0,m): #Per ogni colonna
                for j in xrange(0,n): #Per ogni riga
                        if matrice[j][i] != 0:
                                temp.append(j)
                listElementi.append(temp)
                temp = []

        return listElementi


def creaSoluzione(matrix):
        n = len(matrix)
        m = len(matrix[0])

        max = 0
        for j in xrange(0,m):
                temp = 0
                for i in xrange(0,n):
                        temp += matrix[i][j]
                #print(temp)

                if temp > max:
                        max = temp
        return max

Any hints? Thanks

Tripp Kinetics
  • 5,178
  • 2
  • 23
  • 37
andrew
  • 3,879
  • 4
  • 25
  • 43

2 Answers2

2

When you do matrice = best_matrice, you're just creating a new reference named matrice pointing to the same object as the reference best_matrice.

Check out the accepted answer for Deep copy a list in Python for an example of a deep copy of a list in Python.

Community
  • 1
  • 1
Tripp Kinetics
  • 5,178
  • 2
  • 23
  • 37
-1

A quick shorthand for copying lists 'deeply' without importing is the use of the : slice operator. In your situation, you'd need to use it twice to explicitly duplicate the lists and their contents rather than copying references to the inner lists.

A trivial example is new_lst = old_lst[:] to copy all contents of old_lst -- in your case, you'd want to do matrice = best_matrice[:][:], thereby copying the contents of the inner lists, too.

a p
  • 3,098
  • 2
  • 24
  • 46
  • Strictly speaking, the slice operator is not a deep copy. Consider ```a = [1,2]; b = [3,4]; lst1 = [a, b]; lst2 = lst1[:]; b.append(5); print lst2 ``` – wnnmaw Jun 11 '14 at 19:53
  • I put 'deeply' in quotes for a reason, but it is actually a 'deep' copy - just one level deep. When you say `a = [1,2]` you're really saying "let 'a' be a name that refers to a list in memory somewhere containing 1 and 2". `b = a` is just saying, "let 'b' be a name referring to 'a'." The `[:]` idiom simply changes that to "let 'b' be a name referring to a list whose contents are whatever the contents of 'a' are, right now". If those contents happen to be names or references themselves, that's what you get. If you want a 2-level deep copy, `lst[:][:]` is the right idiom. – a p Jun 11 '14 at 20:00
  • 1
    lst[:][:] just copies the first layer twice: `l=[ ['one'], ['two']];l2=l[:][:];l2[0][0]='three';print l` gives `[['three'], ['two']]` – tdelaney Jun 11 '14 at 20:27
  • Hey, you're right! I've been doing it wrong. Thanks – a p Jun 11 '14 at 20:47