简体   繁体   中英

Creating a square matrix from a .txt file in Python

I'm about to create a program running a Hamiltonian cycle for TSP(symmetrical) problem which means that a path goes only to one point and then goes further. The distance between those points can be written as a square matrix. Because the problem is symmetrical, i only have a half of this matrix as a.txt file

I need to create a program which will allow me to insert values separated by spaces from a.txt file into an array, and create a symmetrical square matrix out of it.

URL to see present the idea and data layout in.txt file:

https://imgur.com/4G3sXrp

I'm a newbie in Python and i don't really understand how to work with IO at this level.

I've tried using numpy function: loadtxt but did not work for me, i recieved an error message saying that i cannot convert string to float

i've also tried doing by creating loops that were supposed to split the text and create this matrix.

def createMatrix(rows):
    matrix= [[0 for col in range(int(rows[0]))] for row in range(int(rows[0]))]
    i = 0
    for w in rows[1:]:
        w = string.strip(w).split(' ')
        j = 0
        for dist in w:
            matrix[i][j] = int(dist)
            matrix[j][i] = int(dist)
            j+=1
        i+=1
 return matrix

I expected the code result to at least guide me somehow on what should i do, but as i've mentioned i'm a newbie and i don't really know how to get started with this particular problem.

In the picture you linked to, showing how you'd like for the matrix to look, the last column has 12 two times. Also, in the second to last column, you've got a 19. Huh? Also, the last two lines / rows of your input text file both have five numbers. I'm guessing the last line should have six numbers.

The fact that the numbers have varying numbers of digits makes it harder to visually verify that everything is correct.

If you have a text file ("stuff.txt") that looks like this (note, the leading zeros for padding):

00
01 00
02 03 00
04 05 06 00
07 08 09 10 00
11 12 13 14 00

And the code:

with open("stuff.txt", "r") as file:
    lines = list(map(str.split, file.read().splitlines()))

    missing_values = []

    for index in range(len(lines)):
        missing_values.append([line[index] for line in lines[index+1:]])

    matrix = [line + values for line, values in zip(lines, missing_values)]

    for row in matrix:
        print(row)

Output:

['00', '01', '02', '04', '07', '11']
['01', '00', '03', '05', '08', '12']
['02', '03', '00', '06', '09', '13']
['04', '05', '06', '00', '10', '14']
['07', '08', '09', '10', '00', '00']
['11', '12', '13', '14', '00']

The matrix is not square because the last two lines in your text file have five numbers (where the last line should have six).

You can use np.tril_indices for filling the lower triangular part of the final square matrix and then M += MT for filling the rest (since your diagonal is zero):

import numpy as np

with open('/tmp/test.txt') as fh:
    data = np.fromstring(fh.read().replace('\n', ' '), dtype=int, sep=' ')

n = int(np.sqrt(8*data.size + 1) - 1) // 2
matrix = np.zeros((n, n), dtype=int)
matrix[np.tril_indices(len(matrix))] = data
matrix += matrix.T  # Only works if diagonal is zero.

print(matrix)

Test with the example data of the OP:

text = '''0
1 0
2 3 0
4 5 6 0
7 8 9 10 0
11 12 13 14 15 0'''

with open('/tmp/test.txt', 'w') as fh:
    fh.write(text)

We get the output:

[[ 0  1  2  4  7 11]
 [ 1  0  3  5  8 12]
 [ 2  3  0  6  9 13]
 [ 4  5  6  0 10 14]
 [ 7  8  9 10  0 15]
 [11 12 13 14 15  0]]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM