对称矩阵排列问题,请各位麻烦给个编程实现的思路或者伪代码,谢谢!!

Clutch_K 2020-01-12 01:12:51
请问各位,如何使用c语言实现:用初等矩阵R将一个对称阵A按照他对角线元素的大小重新进行排列得到A1=R*A*R?谢谢
比如:A=
3 1 8 10
1 2 25 37
8 25 5 70
10 37 70 4
按照对角线元素从小到大顺序,获取初等变换矩阵R,然后得到排列后的矩阵:
A1=
2 1 37 25
1 3 10 8
37 10 4 70
25 8 70 5
...全文
126 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
Clutch_K 2020-01-13
  • 打赏
  • 举报
回复
引用 9 楼 寻开心 的回复:
如果需要R,就自己合成吧。 原来想简单的依靠交换行列来实现, 看来是不行 在MatrixSort代码当中,每个步骤下都是生成了一个r, 用这个r每次新的在左侧,老的r在右侧, 做矩阵乘法吧
好的,谢谢您的解答和代码!
寻开心 2020-01-13
  • 打赏
  • 举报
回复
如果需要R,就自己合成吧。 原来想简单的依靠交换行列来实现, 看来是不行
在MatrixSort代码当中,每个步骤下都是生成了一个r, 用这个r每次新的在左侧,老的r在右侧, 做矩阵乘法吧
Clutch_K 2020-01-13
  • 打赏
  • 举报
回复
引用 6 楼 寻开心 的回复:
#include <stdio.h> #include <memory.h> #define LEN 6 void MatrixPrint(int (*m)[LEN]); void MatrixMul(int (*a)[LEN], int (*b)[LEN], int (*c)[LEN]) { int t[LEN][LEN] = {0}; int i, j, k; for (i=0; i<LEN;i++) { for ( j=0; j<LEN; j++ ) { for ( k=0; k<LEN; k++) t[i][j] += a[i][k]*b[k][j]; } } memcpy(c, t, LEN*LEN*sizeof(int)); } void MatrixNormal(int (*m)[LEN] ) { memset(m, 0, LEN*LEN*sizeof(int)); for (int i=0; i<LEN; i++) m[i][i] = 1; } void MatrixChange(int (*m)[LEN], int i, int j) { int t; for (int k=0; k<LEN; k++) t=m[i][k], m[i][k]=m[j][k], m[j][k]=t; } void MatrixSort(int(*m)[LEN]) { int d[LEN]={0}; int i, j, k; int r[LEN][LEN]; for ( i=0; i<LEN; i++ ) { d[i]=m[i][i]; } for ( i=0; i<LEN-1; i++) { for (j=i+1; j<LEN; j++) { if ( d[i]>d[j] ) { int t=d[i]; d[i]=d[j]; d[j]= t; MatrixNormal(r); MatrixChange(r, i, j); MatrixMul(r, m, m); MatrixMul(m, r, m); } } } for ( i=0; i<LEN; i++) printf("%d ", d[i]); printf("\n"); } void MatrixPrint(int (*m)[LEN]) { for (int i=0; i<LEN;i++) { for ( int j=0; j<LEN; j++ ) { printf("%3d", m[i][j]); } printf("\n"); } } int main( void ) { /*int a[LEN][LEN] = { 3,1,8,10, 1, 2,25,37, 8,25,5,70, 10,37,70,4}; */ int a[LEN][LEN] = {6,2,4,8,14,22, \ 2,1,6,10,16,24, \ 4,6,3,12,18,26, \ 8,10,12,2,20,28, \ 14,16,18,20,5,30, \ 22,24,26,28,30,8}; int r[LEN][LEN]; MatrixSort(a); MatrixPrint(a); return 0; } 先不合成R了, 主元排序的时候,同步更新矩阵。
最后我还是要把那个R阵求出来的,用于还原回去,可以按照您的算法实现吧?
Clutch_K 2020-01-13
  • 打赏
  • 举报
回复
引用 6 楼 寻开心 的回复:
#include <stdio.h> #include <memory.h> #define LEN 6 void MatrixPrint(int (*m)[LEN]); void MatrixMul(int (*a)[LEN], int (*b)[LEN], int (*c)[LEN]) { int t[LEN][LEN] = {0}; int i, j, k; for (i=0; i<LEN;i++) { for ( j=0; j<LEN; j++ ) { for ( k=0; k<LEN; k++) t[i][j] += a[i][k]*b[k][j]; } } memcpy(c, t, LEN*LEN*sizeof(int)); } void MatrixNormal(int (*m)[LEN] ) { memset(m, 0, LEN*LEN*sizeof(int)); for (int i=0; i<LEN; i++) m[i][i] = 1; } void MatrixChange(int (*m)[LEN], int i, int j) { int t; for (int k=0; k<LEN; k++) t=m[i][k], m[i][k]=m[j][k], m[j][k]=t; } void MatrixSort(int(*m)[LEN]) { int d[LEN]={0}; int i, j, k; int r[LEN][LEN]; for ( i=0; i<LEN; i++ ) { d[i]=m[i][i]; } for ( i=0; i<LEN-1; i++) { for (j=i+1; j<LEN; j++) { if ( d[i]>d[j] ) { int t=d[i]; d[i]=d[j]; d[j]= t; MatrixNormal(r); MatrixChange(r, i, j); MatrixMul(r, m, m); MatrixMul(m, r, m); } } } for ( i=0; i<LEN; i++) printf("%d ", d[i]); printf("\n"); } void MatrixPrint(int (*m)[LEN]) { for (int i=0; i<LEN;i++) { for ( int j=0; j<LEN; j++ ) { printf("%3d", m[i][j]); } printf("\n"); } } int main( void ) { /*int a[LEN][LEN] = { 3,1,8,10, 1, 2,25,37, 8,25,5,70, 10,37,70,4}; */ int a[LEN][LEN] = {6,2,4,8,14,22, \ 2,1,6,10,16,24, \ 4,6,3,12,18,26, \ 8,10,12,2,20,28, \ 14,16,18,20,5,30, \ 22,24,26,28,30,8}; int r[LEN][LEN]; MatrixSort(a); MatrixPrint(a); return 0; } 先不合成R了, 主元排序的时候,同步更新矩阵。
好的,大概我看懂您的算法了,十分感谢,我要是对一维数组操作的时候,就按照上面的算法相应的改一下就可以了吧? 比如读进去的一维数组是这样的 int a[36] = {6,2,4,8,14,22, 2,1,6,10,16,24, 4,6,3,12,18,26, 8,10,12,2,20,28, 14,16,18,20,5,30, 22,24,26,28,30,8};
寻开心 2020-01-13
  • 打赏
  • 举报
回复
#include <stdio.h>
#include <memory.h>

#define LEN 6
void MatrixPrint(int (*m)[LEN]);
void MatrixMul(int (*a)[LEN], int (*b)[LEN], int (*c)[LEN]) {
int t[LEN][LEN] = {0};
int i, j, k;
for (i=0; i<LEN;i++) {
for ( j=0; j<LEN; j++ ) {
for ( k=0; k<LEN; k++)
t[i][j] += a[i][k]*b[k][j];
}
}
memcpy(c, t, LEN*LEN*sizeof(int));
}

void MatrixNormal(int (*m)[LEN] )
{
memset(m, 0, LEN*LEN*sizeof(int));
for (int i=0; i<LEN; i++) m[i][i] = 1;
}

void MatrixChange(int (*m)[LEN], int i, int j)
{
int t;
for (int k=0; k<LEN; k++)
t=m[i][k], m[i][k]=m[j][k], m[j][k]=t;
}


void MatrixSort(int(*m)[LEN]) {
int d[LEN]={0};
int i, j, k;
int r[LEN][LEN];
for ( i=0; i<LEN; i++ ) {
d[i]=m[i][i];
}
for ( i=0; i<LEN-1; i++) {
for (j=i+1; j<LEN; j++) {
if ( d[i]>d[j] ) {
int t=d[i];
d[i]=d[j];
d[j]= t;
MatrixNormal(r);
MatrixChange(r, i, j);
MatrixMul(r, m, m);
MatrixMul(m, r, m);
}
}
}
for ( i=0; i<LEN; i++)
printf("%d ", d[i]);
printf("\n");
}

void MatrixPrint(int (*m)[LEN]) {
for (int i=0; i<LEN;i++) {
for ( int j=0; j<LEN; j++ ) {
printf("%3d", m[i][j]);

}
printf("\n");
}
}
int main( void )
{
/*int a[LEN][LEN] = { 3,1,8,10, 1, 2,25,37, 8,25,5,70, 10,37,70,4};
*/
int a[LEN][LEN] = {6,2,4,8,14,22, \
2,1,6,10,16,24, \
4,6,3,12,18,26, \
8,10,12,2,20,28, \
14,16,18,20,5,30, \
22,24,26,28,30,8};

int r[LEN][LEN];
MatrixSort(a);
MatrixPrint(a);
return 0;
}

先不合成R了, 主元排序的时候,同步更新矩阵。
Clutch_K 2020-01-12
  • 打赏
  • 举报
回复
引用 1 楼 寻开心 的回复:
0 1 0 0 1 0 0 0 0 0 0 1 0 0 1 0 用这个矩阵作为R去就做乘法就可以了, R在左边乘法,完成了行交换, 再在右侧乘完成了列交换 算法无非是根据主对角线元素排序的结果构造这个R矩阵 初始化R为单位矩阵 对主对角线元素用冒泡方法排序, 在这个排序过程当中要交换下标i,j两个位置的元素的时候,同步对R矩阵实施行交换 主对角线排列完毕, R也就构造完毕了
查了下矩阵变换的理论,变换后的矩阵这样实现是不是合理一些:A1 = Rn' * A * Rn ,(Rn'为Rn转置),因为一般Rn都是正交阵,Rn^-1=Rn'
Clutch_K 2020-01-12
  • 打赏
  • 举报
回复
引用 2 楼 寻开心 的回复:
#include <stdio.h> #include <memory.h> void MatrixMul(int (*a)[4], int (*b)[4], int (*c)[4]) { int t[4][4] = {0}; int i, j, k; for (i=0; i<4;i++) { for ( j=0; j<4; j++ ) { for ( k=0; k<4; k++) t[i][j] += a[i][k]*b[k][j]; } } memcpy(c, t, 4*4*sizeof(int)); } void MatrixChange(int (*m)[4], int i, int j) { int t; for (int k=0; k<4; k++) t=m[k][i], m[k][i]=m[k][j], m[k][j]=t; } void MatrixSort(int(*m)[4], int(*r)[4]) { int d[4]; int i, j, k; memset(r, 0, 4*4*sizeof(int)); for ( i=0; i<4; i++ ) { d[i]=m[i][i]; r[i][i]=1; } for ( i=0; i<3; i++) for (j=i+1; j<4; j++) { if ( d[i]>d[j] ) { int t=d[i]; d[i]=d[j]; d[j]= t; MatrixChange(r, i, j); } } } void MatrixPrint(int (*m)[4]) { for (int i=0; i<4;i++) { for ( int j=0; j<4; j++ ) { printf("%3d", m[i][j]); } printf("\n"); } } int main( void ) { int a[4][4] = { 3,1,8,10, 1, 2,25,37, 8,25,5,70, 10,37,70,4}; int r[4][4]; MatrixSort(a, r); MatrixPrint(r); MatrixMul(r,a, a); MatrixMul(a,r,a); MatrixPrint(a); return 0; }
感谢楼主码了代码,但是我重新测试6x6的对称阵,比如这个矩阵Q1=[6,2,4,8,14,22; 2,1,6,10,16,24; 4,6,3,12,18,26; 8,10,12,2,20,28; 14,16,18,20,5,30; 22,24,26,28,30,8;] 代码运行结果是不对的,我在想是不是每次冒泡产生交换时,都要交换N阶单位矩阵对应的行生成当前一个初等变换阵,然后最后得到Rn=R1*R2*...*Rn ???希望和楼主讨论一下怎么才能实现这种矩阵排序,谢谢
Clutch_K 2020-01-12
  • 打赏
  • 举报
回复
引用 1 楼 寻开心 的回复:
0 1 0 0 1 0 0 0 0 0 0 1 0 0 1 0 用这个矩阵作为R去就做乘法就可以了, R在左边乘法,完成了行交换, 再在右侧乘完成了列交换 算法无非是根据主对角线元素排序的结果构造这个R矩阵 初始化R为单位矩阵 对主对角线元素用冒泡方法排序, 在这个排序过程当中要交换下标i,j两个位置的元素的时候,同步对R矩阵实施行交换 主对角线排列完毕, R也就构造完毕了
这个算法理论上是这样构造初等矩阵R,但是对于多维的对称方阵进行冒泡排序,然后根据冒泡过程中,只要发生交换就要对单位阵行交换,是不是应该每次交换就生成一个Ri,最终的Rn=R1*R2*...*Rn,变换后的矩阵A1=Rn*A*Rn ?
寻开心 2020-01-12
  • 打赏
  • 举报
回复
#include <stdio.h>
#include <memory.h>
void MatrixMul(int (*a)[4], int (*b)[4], int (*c)[4]) {
int t[4][4] = {0};
int i, j, k;
for (i=0; i<4;i++) {
for ( j=0; j<4; j++ ) {
for ( k=0; k<4; k++)
t[i][j] += a[i][k]*b[k][j];
}
}
memcpy(c, t, 4*4*sizeof(int));
}

void MatrixChange(int (*m)[4], int i, int j)
{
int t;
for (int k=0; k<4; k++) t=m[k][i], m[k][i]=m[k][j], m[k][j]=t;
}

void MatrixSort(int(*m)[4], int(*r)[4]) {
int d[4];
int i, j, k;
memset(r, 0, 4*4*sizeof(int));
for ( i=0; i<4; i++ ) {
d[i]=m[i][i];
r[i][i]=1;
}
for ( i=0; i<3; i++)
for (j=i+1; j<4; j++) {
if ( d[i]>d[j] ) {
int t=d[i];
d[i]=d[j];
d[j]= t;
MatrixChange(r, i, j);
}
}
}

void MatrixPrint(int (*m)[4]) {
for (int i=0; i<4;i++) {
for ( int j=0; j<4; j++ ) {
printf("%3d", m[i][j]);

}
printf("\n");
}
}
int main( void )
{
int a[4][4] = { 3,1,8,10, 1, 2,25,37, 8,25,5,70, 10,37,70,4};
int r[4][4];
MatrixSort(a, r);
MatrixPrint(r);
MatrixMul(r,a, a);
MatrixMul(a,r,a);
MatrixPrint(a);
return 0;
}
寻开心 2020-01-12
  • 打赏
  • 举报
回复
0 1 0 0
1 0 0 0
0 0 0 1
0 0 1 0
用这个矩阵作为R去就做乘法就可以了, R在左边乘法,完成了行交换, 再在右侧乘完成了列交换

算法无非是根据主对角线元素排序的结果构造这个R矩阵
初始化R为单位矩阵
对主对角线元素用冒泡方法排序, 在这个排序过程当中要交换下标i,j两个位置的元素的时候,同步对R矩阵实施行交换
主对角线排列完毕, R也就构造完毕了

69,369

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧