| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 2877 人关注过本帖
标题:如何优化程序使程序运行时间缩短?
只看楼主 加入收藏
黑龙风月
Rank: 1
等 级:新手上路
帖 子:17
专家分:0
注 册:2014-6-6
结帖率:100%
收藏
 问题点数:0 回复次数:5 
如何优化程序使程序运行时间缩短?
这是一个大型矩阵求逆的算法,是用的初等行变换来实现的,10000*10000的矩阵大概运行1小时20分(以前是用高斯消元法,但是运行时间比现在这种慢,大概是1小时40分,不包括随机数生成部分),希望能改进一下,让程序运行的快一点。下面是源码


#include <iostream>
#include<math.h>
#include<malloc.h>
#include<iomanip>
#include<time.h>
#include<stdio.h>
#include<stdlib.h>

//#define N 10000 //注意大小
#define random(x)((float)rand()/x)

//函数声明部分
bool Matrix_Inv(float **A,int n,float **B);  //应用矩阵初等变换的方法求逆矩阵

using namespace std;
int main()
{
     int i,j;

     
     int n;
     float x;
     double start,end;
     bool test;

     x = pow(2.0,20);

     cout<<"采用部分主元的高斯消去法求方阵的逆矩阵!\n";
     cout<<"请输入方阵的阶数:";
     cin>>n;

     float** a=new float*[n];
     for(i=0;i<n;++i)a[i]=new float[n];

     float** b=new float*[n];
     for(i=0;i<n;++i)b[i]=new float[n];

    // srand((int)time(0));
     for(i=0;i<n;i++)
     {
         for(j=0;j<n;j++)
         {
             a[i][j] = random(x);
         }
 }

     start = (double)clock()/CLOCKS_PER_SEC;

     test=Matrix_Inv(a,n,b);
     end = (double)clock()/CLOCKS_PER_SEC;

/*
     //运用高斯消去法求该矩阵的逆矩阵并输出
   if(test)
     {
         cout<<"该方阵的逆矩阵为:\n";

         for(i=0;i<n;i++)
         {
             cout<<setw(4);
             for(j=0;j<n;j++)
             {
                 cout<<b[i][j]<<setw(10);
             }
             cout<<endl;
              cout<<endl;
         }
     }
     */
//end = (double)clock()/CLOCKS_PER_SEC;


     cout<<start<<endl;
     cout<<end<<endl;
     cout<<end-start<<"s"<<endl;

     for(i=0;i<n;++i){delete[] a[i]; delete[] b[i];}
     delete[] a; delete[] b;
     return 0;
}


//应用矩阵初等变换的方法求逆矩阵
//参数说明:
//        **A 原矩阵
//        n 矩阵的阶数
//        **B 求解结果,逆矩阵
bool Matrix_Inv(float **A,int n,float **B)
{
       int i,j,k;
       float **MatEnhanced;//增广矩阵(A|E)
       MatEnhanced = (float**)malloc(n*sizeof(float*));
       for(i=0;i<n;i++)
           MatEnhanced[i] = (float*)malloc(2*n*sizeof(float));
 
       float *temp;
       temp = (float*)malloc(2*n*sizeof(float));
 
       float xishu=1;//初等变换时系数,设初值为1
 
       for(i=0;i<n;i++)                            //增广矩阵赋值,前半部分
       {
              for(j=0;j<n;j++)
                     MatEnhanced[i][j] = A[i][j];
       }
       for(i=0;i<n;i++)                            //增广矩阵赋值,后半部分
       {
              for(j=n;j<2*n;j++)
                     MatEnhanced[i][j] = 0;//先将后半部分全部赋值为0
 
              MatEnhanced[i][i+n] = 1;//再将其对角线部分赋值为1
       }
 
       //接下来进行初等行变换
       for(i=0;i<n;i++)
       {
              if(MatEnhanced[i][i] == 0)//如果前半部分的对角线上的元素为0,此时进行行变换
              {
                     if(i == n-1)//如果是最后一行,那么说明该矩阵不可逆
                            return false;
//对第i行以后的各行进行判断,找到第i个元素不为零的行,并与第i行进行交换
                     for(j=i;j<n;j++)
                     {
                            if(MatEnhanced[j][i] != 0)
                            {
                                   k = j;//记住该行的行号
                                   break;//退出循环
                            }
                     }
                     //接下来对第i行和第k行进行交换
                     temp = MatEnhanced[k];//第k行
                     MatEnhanced[k] = MatEnhanced[i];
                     MatEnhanced[i] = temp;
              }
 
              //初等变换
              for(j=0;j<n;j++)//对其他行的所有列进行计算
              {
                     if(j != i)//本行不参与计算
                     {
                            if(MatEnhanced[j][i] != 0)//只有当其不为零时进行计算,否则不计算
                            {
                                   xishu = MatEnhanced[j][i]/MatEnhanced[i][i];
                                   for(k=i;k<2*n;k++)//对后面的所有列进行计算
                                   {
                                          MatEnhanced[j][k] -= xishu*MatEnhanced[i][k];
                                   }
                            }
                     }
              }
//将本行所有列都除以对角线上的值,将前半部分化成单位矩阵
              xishu = MatEnhanced[i][i];
              for(j=i;j<2*n;j++)
                     if(xishu != 0)
                     MatEnhanced[i][j] /= xishu;
       }
 
       //计算完成后,后半部分即为原矩阵的逆矩阵,将其赋值给InvMat.
       for(i=0;i<n;i++)
       {
              for(j=0;j<n;j++)
                    B[i][j] = MatEnhanced[i][j+n];
       }
//内存释放
       free(MatEnhanced);
       free(temp);
 
       return true;//返回
}
搜索更多相关主题的帖子: include 如何 高斯 
2015-03-30 17:55
黑龙风月
Rank: 1
等 级:新手上路
帖 子:17
专家分:0
注 册:2014-6-6
收藏
得分:0 
// srand((int)time(0));
去掉//
2015-03-30 17:57
黑龙风月
Rank: 1
等 级:新手上路
帖 子:17
专家分:0
注 册:2014-6-6
收藏
得分:0 
或者哪位大神有更好的算法实现也可以
2015-04-07 21:03
黑龙风月
Rank: 1
等 级:新手上路
帖 子:17
专家分:0
注 册:2014-6-6
收藏
得分:0 
老师提议和大数乘法的算法结合,但是有点儿不会
2015-05-14 21:22
倾听一种悲伤
Rank: 2
等 级:论坛游民
威 望:1
帖 子:3
专家分:20
注 册:2015-6-2
收藏
得分:0 
我的建议是在Matrix_Inv函数中用
start = (double)clock()/CLOCKS_PER_SEC;
end = (double)clock()/CLOCKS_PER_SEC;
将每一个for循环 都做这样时间差的计算,看看在这个函数中,造成时间最长的那段for循环,还是每一段for循环都会很慢,先把这个给确定下,再去想办法去优化程序,不然你都不知道你的函数到底是犹豫那段代码引起的效率问题~
2015-06-03 16:37
诸葛欧阳
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:流年
等 级:贵宾
威 望:82
帖 子:2790
专家分:14619
注 册:2014-10-16
收藏
得分:0 
你可以看看一些图形学算法中怎么求逆矩阵,可能会有帮助

一片落叶掉进了回忆的流年。
2015-06-06 21:40
快速回复:如何优化程序使程序运行时间缩短?
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.015979 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved