一个有趣的一一配对问题

问题描述:有两个集合$\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()
    
    

测试用例运行结果:


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值