构建一个n×n的unique矩阵

原文地址:Construct a unique matrix n x n for an input n

已知一个奇数n,根据下面的条件得到一个n×n大小的矩阵:

  • 每个元素是1到n之间的一个整数(包含1和n);
  • 在同一行,同一列没有相同的数字;
  • 所有的1必须距矩阵的中心任意可能的距离,对于一个奇数n,n×n的矩阵中心是cell ((n-1)/2, (n-1)/2)。

输出:

Input  : n = 1
Output : 1

Input : n = 3
Output: 3 2 1
        1 3 2
        2 1 3

Input : n = 5
Output : 5 3 2 4 1 
         1 4 3 5 2 
         2 5 4 1 3 
         3 1 5 2 4 
         4 2 1 3 5 

首先要定下来1的位置。当n=5的时候,这里有一种1的可能位置:

_ _ _ _ 1 
1 _ _ _ _ 
_ _ _ 1 _ 
_ 1 _ _ _ 
_ _ 1 _ _ 

一旦我们定下了1的位置,填补剩下的项就比较简单了。我们逐列填充剩下的数字。对于每个1,我们遍历这个列,在1下面用2, 3,…p来填充,上面用p+1, .. n填充,于是得到下面的矩阵:

5 3 2 4 1 
1 4 3 5 2 
2 5 4 1 3 
3 1 5 2 4 
4 2 1 3 5 

为了定下1的初始位置,我们遍历所有的行,并跟踪“left”与“right”两列的数字。

  • “right”始于n-1,然后在轮过每一行后做递减;
  • “left”始于0,然后在轮过每一行后做递增;

以下是上面想法的C++实现

// C++ program to construct an n x n matrix such that
// every row and every column has distinct values.
#include <iostream>
#include <bits/stdc++.h>
using namespace std;

const int MAX = 100;
int mat[MAX][MAX];

// Fills non-one entries in column j
// Given that there is a "1" at position mat[i][j],
// this function fills other entries of column j.
void fillRemaining(int i, int j, int n)
{
    // Initialize value to be filled
    int x = 2;

    // Fill all values below i as 2, 3, ...p
    for (int k=i+1; k<n; k++)
        mat[k][j] = x++;

    // Fill all values above i as p+1, p+2, .. n
    for (int k=0; k<i; k++)
        mat[k][j] = x++;
}

// Fills entries in mat[][] with the given set of
// rules
void constructMatrix(int n)
{
    // Alternatively fill 1s starting from
    // rightmost and leftmost columns. For
    // example for n = 3, we get { {_ _ 1},
    // {1 _ _} {_ 1 _}}
    int right = n-1, left = 0;
    for (int i=0; i < n; i++)
    {
        // If i is even, then fill next column
        // from right
        if (i%2 == 0)
        {
            mat[i][right] = 1;

            // After filling 1, fill remaining entries
            // of column "right"
            fillRemaining(i, right, n);

            // Move right one column back
            right--;
        }
        else // Fill next column from left
        {
            mat[i][left] = 1;

            // After filling 1, fill remaining entries
            // of column "left"
            fillRemaining(i, left, n);

            // Move left one column forward
            left++;
        }
    }
}

// Driver program to test above function
int main()
{
    int n = 5;

    // Passing n to constructMatrix function
    constructMatrix(n);

    // Printing the desired unique matrix
    for (int i=0; i<n; i++)
    {
        for (int j=0 ; j<n; j++)
            printf("%d ",mat[i][j]);
        printf ("\n");
    }
    return 0;
}

输出:

5 3 2 4 1 
1 4 3 5 2 
2 5 4 1 3 
3 1 5 2 4 
4 2 1 3 5 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
当然可以!下面是一个使用Matlab计算排列熵的简单示例: ```matlab function permutation_entropy = calculate_permutation_entropy(data, m, r) % data: 输入数据序列 % m: 子序列的长度 % r: 相对阈值 N = length(data); permutations = zeros(N-m+1, m); % 构造所有可能的子序列 for i = 1:N-m+1 permutations(i,:) = data(i:i+m-1); end % 统计每个子序列出现的次数 unique_permutations = unique(permutations, 'rows'); counts = histcounts(perm_to_index(permutations, unique_permutations)); % 计算概率分布 probabilities = counts / sum(counts); % 计算排列熵 permutation_entropy = -sum(probabilities .* log2(probabilities)); % 序列转索引函数 function indices = perm_to_index(perm, unique_perm) [~, indices] = ismember(perm, unique_perm, 'rows'); end end % 示例用法 data = [1 2 3 4 5 6 7 8 9 10]; % 输入数据序列 m = 3; % 子序列长度 r = 0.1; % 相对阈值 permutation_entropy = calculate_permutation_entropy(data, m, r); disp(['Permutation entropy: ' num2str(permutation_entropy)]); ``` 在这个示例中,我们定义了一个名为`calculate_permutation_entropy`的函数,它接受数据序列`data`、子序列长度`m`和相对阈值`r`作为输入,并返回计算得到的排列熵。 首先,我们使用一个循环构建所有可能的子序列,并将它们存储在`permutations`矩阵中。然后,我们使用`unique`函数找到所有独特的子序列,并计算它们在原始序列中出现的次数。 接下来,我们根据计数计算概率分布,并使用该分布计算排列熵。最后,我们将排列熵的结果显示在命令窗口中。 请注意,这只是一个简单的示例,实际的排列熵计算可能需要更多的考虑因素和优化。此外,你还可以根据自己的需求进行修改和扩展。希望对你有所帮助!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值