推广希腊罗马矩阵的构建 - Python

时间:2018-04-30 14:01:07

标签: python-3.x matrix traversal

我编写了一个python程序,其中包含一个矩阵,其中每个元素在每行和每列中出现一次。元素只是正整数。

e.g。

0,2,3,1
3,1,0,2
1,3,2,0
2,0,1,3

然后我发现所有可能的遍历。它们被定义为:

  • 从第一列中选​​择一个元素
  • 转到下一栏
  • 选择遍历中前一个元素不在同一行的元素,并且该元素与遍历中的前一个元素的值不同。

e.g。

0,*,*,*
*,*,*,2
*,3,*,*
*,*,1,*

我已经构造了找到矩阵4x4的遍历的代码,但是我在为NxN矩阵推广它时遇到了麻烦。我的代码如下。不寻求解决方案,任何提示都会有所帮助。

import sys       # Import to input arguments from cmd.
import pprint    # Import for a cool print of the graph
import itertools # Import to find all crossings' combinations

# Input of arguments
input_filename = sys.argv[1]

# Create an empty graph
g = {} 
# Initialize variable for the list count
i = 0 

# Opens the file to make the transfer into a matrix
with open(input_filename) as graph_input:
    for line in graph_input:
        # Split line into four elements.
        g[i] = [int(x) for x in line.split(',')]
        i += 1

# Initialize variable
var = 0
# Lists for the crossings, plus rows and cols of to use for archiving purposes
f = {}
r = {}
c = {}
l = 0

# Finds the all the crossings
if len(g) == 4:
    for x in range (len(g)): 
        for y in range (len(g)):
            # When we are in the first column
            if y == 0:
                # Creates the maximum number of lists that don't include the first line
                max_num = len(g) -1
                for z in range (max_num):
                    f[l] = [g[x][y]]
                    r[l] = [x]
                    c[l] = [y]
                    l += 1
            # When on other columns
            if y != 0:
                for z in range(len(g)):
                    # Initializes a crossing archive
                    used = [-1]
                    for item in f:
                        # Checks if the element should go in that crossing
                        if f[item][0] == g[x][0]:
                            if g[z][y] not in f[item] and z not in r[item] and y not in c[item] and g[z][y] not in used:
                                # Appends the element and the archive  
                                f[item].append(g[z][y])
                                used.append(g[z][y])
                                r[item].append(z)
                                c[item].append(y)

# Removes unused lists 
for x in range (len(f)):
    if len(f[x]) != len(g):
        f.pop(x)

#Transfers the value from a dictionary to a list
f_final = f.values()

# Finds all the combinations from the existing crossings
list_comb = list(itertools.combinations(f_final, i))

# Initialize variables
x = 0
w = len(list_comb)
v = len(list_comb[0][0])

# Excludes from the combinations all invalid crossings
while x < w:
    # Initialize y
    y = 1
    while y < v:
        # Initialize z
        z = 0
        while z < v:
            # Check if the crossings have the same element in the same position
            if list_comb[x][y][z] == list_comb[x][y-1][z]:
                # Removes the combination from the pool
                list_comb.pop(x)
                # Adjust loop variables
                x -= 1
                w -= 1
                y = v
                z = v
            z += 1
        y += 1
    x += 1  

# Inputs the first valid solution as the one to create the orthogonal latin square
final_list = list_comb[0]

# Initializes the orthogonal latin square matrix
orthogonal = [[v for x in range(v)] for y in range(v)]

# Parses through the latin square and the chosen solution
# and creates the orthogonal latin square
for x in range (v):
    for y in range (v):
        for z in range (v):
            if final_list[x][y] == g[z][y]:
                orthogonal[z][y] = int(final_list[x][0])
                break

# Initializes the orthogonal latin square matrix
gr_la = [[v for x in range(v)] for y in range(v)]

# Creates the greek-latin square
for x in range (v):
    for y in range (v):
        coords = tuple([g[x][y],orthogonal[x][y]])
        gr_la[x][y] = coords

pprint.pprint(gr_la)

上述4x4矩阵的有效遍历为:

[[0123],[0312],[3210],[3021],[1203],[1032],[2130],[2301]]

0 个答案:

没有答案