问题描述:有两个集合$\boldsymbol{X}$,$\boldsymbol{Y}$,且$\boldsymbol{X}$和$\boldsymbol{Y}$中元素的个数均为$d$。现给定$N$个由集合$\boldsymbol{X}$中某元素到集合$\boldsymbol{Y}$中某元素的映射,期望找出所有可能的双射的情形。
代码:
import copy
import numpy as np
import matplotlib.pyplot as plt
def find_solutions(X_to_Y_matrix, index_vectors,
connection_list, connection_index_list,
solution_set, solution_index_set):
"""
"""
start_pos = [-1, -1]
for i in range(X_to_Y_matrix.shape[1]):
if X_to_Y_matrix[0][i] == 1:
start_pos = [0, i]
reduced_matrix = np.zeros([X_to_Y_matrix.shape[0] - 1, X_to_Y_matrix.shape[1] - 1])
if reduced_matrix.shape[0] == 0 and reduced_matrix.shape[1] == 0:
connection_list.append(start_pos)
solution_set.append(copy.deepcopy(connection_list))
solution_index_set.append(copy.deepcopy(connection_index_list))
connection_list.pop()
break
n = 0
for i in range(X_to_Y_matrix.shape[0]):
if i != start_pos[0]:
current_row = np.array([])
for j in range(X_to_Y_matrix.shape[1]):
if j != start_pos[1]:
current_row = np.append(current_row, X_to_Y_matrix[i][j])
reduced_matrix[n, :] = current_row
n += 1
connection_list.append(start_pos)
index_row = np.append(\
index_vectors[0][ : start_pos[0]], index_vectors[0][start_pos[0] + 1: ])
index_col = np.append(\
index_vectors[1][ : start_pos[1]], index_vectors[1][start_pos[1] + 1: ])
reduced_index_vectors = np.array([index_row, index_col])
connection_index_list.append(reduced_index_vectors)
find_solutions(reduced_matrix, reduced_index_vectors, \
connection_list, connection_index_list, \
solution_set, solution_index_set)
if len(connection_list) != 0:
connection_list.pop()
if len(connection_index_list) != 0:
connection_index_list.pop()
return None
def test():
"""
"""
dim_X_to_Y_matrix = 5
X_to_Y_connections = np.array([[0, 0],
[0, 2],
[0, 4],
[1, 0],
[1, 2],
[2, 1],
[2, 3],
[3, 1],
[3, 3],
[4, 0],
[4, 4]])
X_to_Y_matrix = np.zeros([dim_X_to_Y_matrix, dim_X_to_Y_matrix])
for i in range(X_to_Y_connections.shape[0]):
X_to_Y_matrix[int(X_to_Y_connections[i][0])][int(X_to_Y_connections[i][1])] = 1
index_vectors = np.empty([2, dim_X_to_Y_matrix])
index_vectors[0, :] = np.arange(0, dim_X_to_Y_matrix, 1)
index_vectors[1, :] = np.arange(0, dim_X_to_Y_matrix, 1)
connection_list = []
connection_index_list = []
solution_set = []
solution_index_set = []
find_solutions(X_to_Y_matrix, index_vectors,
connection_list, connection_index_list,
solution_set, solution_index_set)
if len(solution_set) % 2 == 0:
plot_offset = 200 + (len(solution_set) + 2)/2 * 10
elif len(solution_set) % 2 == 1:
plot_offset = 200 + (len(solution_set) + 1)/2 * 10
plt.figure()
plt.subplot(plot_offset + 1)
for j in range(X_to_Y_connections.shape[0]):
plt.plot([1, 2], X_to_Y_connections[j, :], color='grey')
plt.grid()
plt.box()
plt.show()
for i in range(len(solution_set)):
X_to_Y_list = []
for j in range(len(solution_set[i])):
if j == 0:
X_to_Y_list.append(solution_set[i][0])
elif j >= 1:
X_to_Y_list.append( \
[int(solution_index_set[i][j - 1][0][int(solution_set[i][j][0])]), \
int(solution_index_set[i][j - 1][1][int(solution_set[i][j][1])])])
print(X_to_Y_list)
plt.subplot(plot_offset + i + 2)
for j in range(len(X_to_Y_list)):
plt.plot([1, 2], X_to_Y_list[j], 'o-', linewidth=1)
plt.grid()
plt.box()
plt.show()
if __name__ == "__main__":
test()
测试用例运行结果: