矩阵乘法在一些置换问题上有着很好的应用,特别置换次数较多时,采用矩阵快速幂运算可以加快运算过程。

任意一个置换都能够表示成矩阵的形式。比如,将序列1  2  3  4 置换为 3  1  2  4,相当于以下的矩阵乘法:

一般来说,对于序列1, 2, ..., n,若给出置换方法a1,a2,...,an ,该置换方法表示将原序列的第pi位置上的元素换到第i位置上。

则可以构造置换矩阵P为: P[ai][i]=1 (1<=i<=n), 其余元素全为0。

显然,置换矩阵每行只有一个元素为1,其余为0。

另外,构造的置换矩阵都是可逆的,并且它的逆矩阵等于它的转置矩阵。

【例1】解码字符串。

给定n个数,代表一个置换。一个长度为n的字符串s经过m次置换后变成另一个字符串t。

例如,输入5个数:2  3  1  5  4 代表一个置换操作。字符串s为“hello”,经过3次置换操作

"hello"  ->  "elhol"  ->  "lhelo"  ->  "helol"后,可得到字符串t为“helol”。

输入n、m和结果字符串t,输出转换前的原字符串s。

(1)编程思路。

由置换规则  2 3 1 5 4,可以快速构造用于字符串s转换到t的置换矩阵P。

而从字符串t转换到s显然是逆操作,而置换矩阵的逆矩阵就是其转置矩阵。因此,用于本题的置换矩阵PT应为:

构造好置换矩阵后,m次操作就是置换矩阵的m次幂,之后再乘以初始序列{1 2 3 4 ....n},然后输出相应位置的字符就可以了。

(2)源程序。

#include

#include

struct Matrix

{

int mat[81][81]; // 存储矩阵中各元素

};

Matrix matMul(Matrix a ,Matrix b,int n)

{

Matrix c;

memset(c.mat,0,sizeof(c.mat));

int i,j,k;

for (k = 1; k<=n ; k++)

for (i=1 ;i<=n ; i++)

if (a.mat[i][k]!=0)

for (j = 1 ;j<=n ;j++)

c.mat[i][j] = (c.mat[i][j] + a.mat[i][k] * b.mat[k][j]) ;

return c;

}

Matrix quickMatPow(Matrix a ,int n,int b) // n阶矩阵a快速b次幂

{

Matrix c;

memset(c.mat ,0 ,sizeof(c.mat));

int i;

for (i = 1 ;i <= n ;i++)

c.mat[i][i] = 1;

while (b!=0)

{

if (b & 1)

c = matMul(c ,a ,n); // c=c*a;

a = matMul(a ,a ,n); // a=a*a

b /= 2;

}

return c;

}

int main()

{

int n,m,p[81],i;

Matrix a,b,ans;

char str[82];

while (scanf("%d%d",&n,&m) && n!=0 && m!=0)

{

memset(b.mat,0,sizeof(b.mat));

for (i=1;i<=n;i++)

b.mat[1][i]=i;

memset(a.mat,0,sizeof(a.mat));

for (i=1;i<=n;i++)

{

scanf("%d",&p[i]);

a.mat[i][p[i]]=1;

}

getchar();

gets(str);

ans=quickMatPow(a,n,m);

ans=matMul(b,ans,n);

for (i=1;i<=n;i++)

printf("%c",str[ans.mat[1][i]-1]);

printf("\n");

}

return 0;

}

将此源程序提交给HDU 2371 “Decode the Strings”,可以Accepted。

【例2】送给圣诞夜的礼品。

已知序列1,2,3,…,n,给出m个置换操作, 例如某个置换操作 6 1 3 7 5 2 4,表示把6位置上的元素换到1位置上,1位置上的元素换到2位置上…。

求原序列为1,2,3,……,n的序列按给出的m个置换操作的顺序进行k次置换后得到的新序列。若k>m,则第m+1次置换操作做第1个置换操作,第m+2次置换操作做第2个置换操作,…。

数据说明: 1<=n<=100;1<=m<=10;1<=k<=2^31-1。

(1)编程思路。

搞懂了例1,本题就容易入手了。m 个置换操作需要构造m个置换矩阵。

构造好置换矩阵后,先将m个置换矩阵乘起来,得到ans矩阵,则此时的ans矩阵相当进行了m次操作;再将ans矩阵进行k/m次幂,此时相当进行了k次操作。当然,由于k不一定整除m,因此还需按m个置换操作的顺序进行k%m次的置换操作。

(2)源程序。

#include

#include

struct Matrix

{

int mat[101][101]; // 存储矩阵中各元素

};

Matrix p[11];

Matrix matMul(Matrix a ,Matrix b,int n)

{

Matrix c;

memset(c.mat,0,sizeof(c.mat));

int i,j,k;

for (k = 1; k<=n ; k++)

for (i=1 ;i<=n ; i++)

if (a.mat[i][k]!=0)

for (j = 1 ;j<=n ;j++)

c.mat[i][j] = (c.mat[i][j] + a.mat[i][k] * b.mat[k][j]) ;

return c;

}

Matrix quickMatPow(Matrix a ,int n,int b) // n阶矩阵a快速b次幂

{

Matrix c;

memset(c.mat ,0 ,sizeof(c.mat));

int i;

for (i = 1 ;i <= n ;i++)

c.mat[i][i] = 1;

while (b!=0)

{

if (b & 1)

c = matMul(c ,a ,n); // c=c*a;

a = matMul(a ,a ,n); // a=a*a

b /= 2;

}

return c;

}

int main()

{

int n,m,k,i,j,num,a[101];

Matrix ans;

scanf("%d%d%d",&n,&m,&k);

for (i=0;i

{

memset(p[i].mat,0,sizeof(p[i].mat));

for (j=1;j<=n;j++)

{

scanf("%d",&num);

p[i].mat[j][num]=1;         // 构造的置换矩阵

}

}

memset(ans.mat,0,sizeof(ans.mat));

for (i=1;i<=n;i++)

ans.mat[i][i]=1;

for (i=0;i

ans=matMul(p[i],ans,n);      // m个置换矩阵先乘起来,注意是左乘

ans=quickMatPow(ans,n,k/m);

for (i=0;i

ans=matMul(p[i],ans,n);    // 剩余的k%m个矩阵相乘,代表剩余的k%m次操作

memset(a,0,sizeof(a));

for (i=1;i<=n;i++)

for (j=1;j<=n;j++)

a[i]=a[i]+(ans.mat[i][j])*j;

for (i=1;i<=n;i++)

printf("%d ",a[i]);

printf("\n");

return 0;

}

java如何求矩阵的置换_矩阵乘法(五):置换相关推荐

  1. python矩阵和向量乘积_矩阵与向量的乘积

    以下内容来源于:https://www.zhihu.com/people/August_666/posts 先上运算,再解读: 一个矩阵乘以一个列向量相当于矩阵的列向量的线性组合. 一个行向量乘以矩阵 ...

  2. 将矩阵转为一行_矩阵与矩阵乘积简介

    作者|Hadrien Jean 编译|VK 来源|Towards Data Science 原文链接:https://towardsdatascience.com/introduction-to-ma ...

  3. python矩阵施密特标准型_矩阵与数值计算(3)——Schur标准型和Jordan分解

    前言 之前介绍过几种矩阵分解方法,都可以有效的提升矩阵方程的数值求解问题,其中LU分解尤其适合于中小型.稠密矩阵的求解问题.我们最理想的矩阵就是可相似对角化的矩阵,直接可以分解成两个酉矩阵和一个对角矩 ...

  4. 一对矩阵的相关性_矩阵分析学习笔记(1)

    线性空间与线性映射 一.线性空间的概念: 记实数域 为 , 复数域为 , 统称数域 .设有一非空 集合记为 , 对集合 中的元素定义二元加法运算和数乘运算.(二元加法运算和数乘运算是一种线性映射,集合 ...

  5. python判断矩阵是否对称_矩阵的特征分解(推导+手算+python计算+对称矩阵的特征分解性质)...

     1. 前言 最近几天一直在学习矩阵的知识,恶补了特征分解和SVD算法,发现网上很多资料都是不全的,所以想记录一下这里面的特征分解推导过程. 2.矩阵的进阶知识 2.1 特征分解(谱分解)=> ...

  6. 计算机键盘是编码键盘还是非编码键盘,矩阵按键原理图_矩阵按键扫描实例

    键盘分编码键盘和非编码键盘.键盘上闭合键的识别由专用的硬件编码器实现,并产生键编码号或键值的称为编码键盘,如计算机键盘.而靠软件编程来识别的称为非编码键盘. 在一般嵌入式应用中,用的最多的是非编码键盘 ...

  7. python实现矩阵叉乘_矩阵乘法的纯Python实现 | 离开Python库!!

    点击关注我哦 一篇文章带你了解矩阵乘法的纯Python实现 在<这篇文章>中,我们有简单提到"矩阵乘法"的相关知识,如果你不记得了,可以复习一下这张图片. 想起来了没? ...

  8. java迭代法求圆周率用梯形_常用的圆周率计算公式

    (I)设备筒体.管道表面积计算公式为: S=πDL (1-2) 式中 π--圆周率,取 3.14; D--设备简体.管道直径(m); L--设备筒体.管道高或延长米(m)...... (二)椭圆面积计 ...

  9. java迭代法求圆周率用梯形_感悟数学“近似计算”之美——“望星楼”里的圆周率...

    人类求解圆周率的历史非常悠久.在数学史上,圆周率的计算方法大体上可以分为两类:早期大多使用的是几何算术方法,即利用多边形逼近单位圆来近似求解:第二类是近现代数学中的解析方法.本文主要讲前者,读者们一般 ...

最新文章

  1. C++的坑真的多吗?
  2. cannot write file to virtual machine aborting the file copy operation.
  3. android SharedPreferences保存list数据
  4. 面向对象要点(构造函数)
  5. 大橙子_【大橙子活动】工程学院新媒体中心第二届总结大会圆满结束!
  6. 机器人布罩_机器人防护罩的主要作用是什么?
  7. win32学习之 --------GDI使用 代码记录
  8. 向C语言之父—丹尼斯·里致敬
  9. oracle solaris翻译,详解Oracle云操作系统Solaris 11.2
  10. 金蝶注册不了服务器,金蝶KIS专业版V10.0加密服务器无法注册?
  11. 图扑数字孪生青岛城轨,赋能智慧交通低碳发展
  12. 线程的6种状态(NEW,RUNNABLE,BLOCKED,WAITING,TINED_WATING,TEMINATE)
  13. 宽带服务器盒信号灯红色闪烁,光纤灯红色闪烁怎么解决(图文)
  14. 我现在的笔记有哪几个地方?
  15. python保存turtle绘制的图片_turtle绘图保存png图片
  16. PHP与SEO,应用curl及正则获取搜狗搜索相关关键词
  17. c罗图片带字经典语言,20条经典的唯美的图片带字-感人的情话
  18. adobe acrobat pro dc 无法打开PDF_PDF编辑Acrobat Pro软件教程 Acrobat XI Pro 全面技能标准培训视频...
  19. 这个扯淡的世界!一个80后眼中的中国经济
  20. 深入浅出设计模式之命令模式

热门文章

  1. pgsql数据库自动备份、删除及恢复
  2. 若依 修改默认跳转页面
  3. Python中向列表连续输入10个值
  4. 两个人玩抛硬币的游戏,谁先抛到正面就获胜。那么先抛的人获胜概率为()。两种思路
  5. 第二周学习python总结
  6. adb push文件到模拟器
  7. 微信小程序---地图导航(点击地址,可以进行导航)
  8. 一个列子看懂 隐藏(hide)
  9. mov指令和 add以及sub 指令的区别
  10. 交互设计学习心得体会