Update for二维数组变换问题

mathe 2002-02-23 10:37:59
原先的代码在矩阵不可逆时处理的不对,比如n=4时,应该只用4个变换就可以覆盖了
#include <stdio.h>

#define MAXN 100
#define MAXTRIX_SIZE (MAXN*MAXN)

char **m;
char *b;
char *r;
int *index;

int main(int argc,char *argv[]){
int n;
int i,j,k;
int last;
char swap;
int iswap;
if(argc==2){
n=atoi(argv[1]);
}else{
scanf("%d",&n);
}
if(n>MAXN||n<=0){
printf("%d out of range\n",n);
return -1;
}
last=n*n;
m=(char **)malloc(sizeof(char*)*last+sizeof(char)*last*last);
b=(char *)malloc(sizeof(char)*last);
r=(char *)malloc(sizeof(char)*last);
index=(int *)malloc(sizeof(int)*last);
if(m==NULL||b==NULL||r==NULL||index==NULL){
fprintf(stderr,"Out of memory\n");
return -1;
}
m[0]=(char *)(m+last);
for(i=1;i<last;++i)m[i]=m[i-1]+last;
memset(m[0],0,sizeof(char)*last*last);
for(i=0;i<last;++i)index[i]=i;
//initialize data
for(i=0;i<n*n;++i){
m[i][i]=1;
if(i>=n)m[i][i-n]=1;
if(i%n!=0)m[i][i-1]=1;
if(i%n!=(n-1))m[i][i+1]=1;
if(i<n*n-n)m[i][i+n]=1;
b[i]=1;
}
for(i=0;i<last;++i){
for(j=i;j<n*n;++j){
if(m[j][i])
break;
}
if(j==n*n){
iswap=index[--last];
index[last]=index[i];
index[i]=iswap;
for(k=0;k<n*n;++k){
iswap=m[k][i];
m[k][i]=m[k][last];
m[k][last]=iswap;
}
}else{
for(k=i;k<last;++k){
swap=m[i][k];
m[i][k]=m[j][k];
m[j][k]=swap;
}

swap=b[i];
b[i]=b[j];
b[j]=swap;

for(j=i+1;j<n*n;++j){
if(m[j][i]){
b[j]^=b[i];
for(k=i;k<last;++k)
m[j][k]^=m[i][k];
}
}
}
}
if(last<n*n){
fprintf(stderr,"Matrix not invertible\n");
for(i=last;i<n*n;++i){
if(b[i]){
fprintf(stderr,"Cannot find result\n");
return -1;
}
}
}
for(i=last-1;i>=0;--i){
for(j=0;j<i;++j){
if(m[j][i]){
b[j]^=b[i];
m[j][i]=0;
for(k=last;k<n*n;++k){
m[j][k]^=m[i][k];
}
}
}
}
if(last==n*n){
iswap=0;
for(i=0,j=0;j<n;++j){
for(k=0;k<n;++k,++i){
if(b[index[i]])iswap++;
printf("%1d",(int)b[index[i]]);
}
printf("\n");
}
}
else{
int small=0x7FFFFFFF;
int smallk=-1;
if(n*n-last>=31){
fprintf(stderr,"Overflow because matrix order too small\n");
return -1;
}
printf("Free parameter count=%d\n",n*n-last);
for(k=0;k<(1<<(n*n-last));++k){
iswap=0;
for(i=last;i<n*n;++i){
r[i]=(k>>(i-last))&1;
if(r[i])iswap++;
}
for(i=0;i<last;++i){
r[i]=b[i];
for(j=last;j<n*n;++j){
r[i]^=m[i][j]&r[j];
}
if(r[i])iswap++;
}
printf("A good result k=%d,operation count=%d\n",k,iswap);
for(i=0,j=0;j<n;++j){
int t;
for(t=0;t<n;++t,++i){
printf("%1d",(int)r[index[i]]);
}
printf("\n");
}
if(iswap<small){
small=iswap;
smallk=k;
}
}
{
printf("Smallest k=%d,smallest operation count=%d\n",smallk,small);
for(i=last;i<n*n;++i){
r[i]=(smallk>>(i-last))&1;
if(r[i])iswap++;
}
for(i=0;i<last;++i){
r[i]=b[i];
for(j=last;j<n*n;++j){
r[i]^=m[i][j]&r[j];
}
if(r[i])iswap++;
}
for(i=0,j=0;j<n;++j){
for(k=0;k<n;++k,++i){
printf("%1d",(int)r[index[i]]);
}
printf("\n");
}
}
iswap=small;
}

printf("Total %d operation\n",iswap);
return 0;
}
...全文
80 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
mathe 2002-02-25
  • 打赏
  • 举报
回复
You're right. It's my bug.
I should modify
if(j==n*n){
iswap=index[--last];
index[last]=index[i];
index[i]=iswap;
for(k=0;k<n*n;++k){
iswap=m[k][i];
m[k][i]=m[k][last];
m[k][last]=iswap;
}
To
if(j==n*n){
iswap=index[--last];
index[last]=index[i];
index[i]=iswap;
for(k=0;k<n*n;++k){
iswap=m[k][i];
m[k][i]=m[k][last];
m[k][last]=iswap;
i--;
}
Then it seems impossible to search for n=47 in such a way.
Because we need to search for 1G possible solutions for n=47.
It seems further effort needed for large free parameter.

intfree 2002-02-25
  • 打赏
  • 举报
回复
无论n是多少,这个程序输出的Free parameter,都恰恰是我程序所输出的一半。这个程序没有产生所有解,不知你是否为了忽略旋转翻转等本质相同的解,而作了特殊处理。n=9时好像有问题,我的解需要25步:
100001001
001100000
001100110
100000110
000010000
011000001
011001100
000001100
100100001
mathe 2002-02-23
  • 打赏
  • 举报
回复
有兴趣可以计算一下n=47,看一下所花费的时间(不过要将结果重定向,最好将中间结果全部屏蔽掉,不然输出结果太多了)

33,010

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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