社区
C语言
帖子详情
用 c 语言实现 高斯消去法 解线性方程组解 (512 * 512 的方程组)大概需要多少时间?
tiaoci
2005-01-17 11:55:32
在我 PIII900的机器上运行了 3-4秒,是不是太慢了?
...全文
474
19
打赏
收藏
用 c 语言实现 高斯消去法 解线性方程组解 (512 * 512 的方程组)大概需要多少时间?
在我 PIII900的机器上运行了 3-4秒,是不是太慢了?
复制链接
扫一扫
分享
转发到动态
举报
写回复
配置赞助广告
用AI写文章
19 条
回复
切换为时间正序
请发表友善的回复…
发表回复
打赏红包
gongluyang
2005-05-15
打赏
举报
回复
to tiaoci(我挑刺,我快乐)
我怎么用你这个算法得不到正确的结果呢
就算我输入a={1,1,1,-1}; b ={1,0}
应该得到的是{0.5,0.5}
怎么我得到的是{0.043620,0.078776}
还是有什么别的原因??
tiaoci
2005-01-19
打赏
举报
回复
这里是一个选主列的gauss过程,我没有做刻意的优化,
比方 m[i * n + j] 可以先计算 m[i * n] 然后通过指针取得
因为我相信编译器会自动优化的,看谁能改得更快点
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <time.h>
void T()
{
time_t ltime;
time(<ime);
printf("The time is %s\n", ctime( <ime ));
}
int gauss(double * m, int n, double * b)
{
int i,j,k;
double temp = 0.0;
double max = 0.0;
int pos = 0;
for(i = 0; i < n; i++)
{
max = fabs(m[i * n + i]);
pos = i;
// 选最大主列
for(j = i + 1; j < n; j++)
{
if(fabs(m[j * n +i]) > max)
{
max = fabs(m[j * n + i]);
pos = j;
}
}
if(i != pos)
{
// 交换两行的数据
for(j = i; j < n; j++)
{
temp = m[i * n + j];
m[i * n + j] = m[pos * n + j];
m[pos * n + j] = temp;
}
temp = b[i];
b[i] = b[pos];
b[pos] = temp;
}
// 当前行规一化
max = m[i * n + i];
if(fabs(max) < 0.00000001) return 0;
for(j = i + 1; j < n; j++)
{
m[i * n + j] = m[i * n + j] / max;
}
b[i] = b[i] / max;
// 执行消去操作
for(j = 0; j < n; j++)
{
if(j == i) continue;
for(k = i + 1; k < n; k++)
{
m[j * n + k] = m[j * n + k] - m[j * n + i] * m[i * n + k];
}
b[j] = b[j] - m[j * n + i] * b[i];
}
}
return 1;
}
void main()
{
int n = 1024;
double * m = (double *)malloc(sizeof(double)*n*n);
double * a = (double *)malloc(sizeof(double) * n);
int i,j;
srand(1);
for(i = 0; i < n; i++)
{
for(j = 0; j < n; j++)
{
m[i * n + j] = (double)rand() / (double)RAND_MAX;
}
a[i] = (double)rand() / (double)RAND_MAX;
}
T();
if(gauss(m, n, a) == 1)
{
T();
}
}
tiaoci
2005-01-19
打赏
举报
回复
看看谁能写一个解线形方程组得算法,
能比现在的2秒再快上点
tiaoci
2005-01-19
打赏
举报
回复
to happy__888
这样的代码最多快个一倍两倍,即使某个操作被多做了100倍,
但是和 1000000( O(N^3) )的总操作量来说,几乎不算什么
而且现代的编译器已经相当智能了,象这种 x/y/z 这样的
都能自动优化掉的,现代编译器甚至能发现 /y/z 被做了多次
而使用一个预计算量来代替
寻开心
2005-01-19
打赏
举报
回复
为什么不可能呢
比如在涉及到循环的算法当中
循环体内的任何一个改动, 都可以被循环本身所放大
也许这个改动只是使得算法多执行了一个乘法
那么一个100次的循环就使得这个乘法被对执行了100次
如果再有二层,三层循环, 这个执行就会被再次的放大放大
比如公式 x/y/z 和 x/(y*z) 在公式的层面上是一致的
但是在电脑的执行速度上差异是很大的
类似的问题在实现具体算法的时候,会遇到很多的
这些都是优化自己的算法实现代码的重点所在
尤其是在多重循环的最里层循环当中, 一个小的改动就可以把运行速度影响很大
tiaoci
2005-01-19
打赏
举报
回复
我的算法肯定是没有问题的,Gauss消去法是一个标准算法
要说“理论上的算法, 到具体的实践代码的转换过程当中都是有可能造成
数倍,几十倍甚至成百上千倍的运行速度上的差异的”
我可不大相信,应当不会这么夸张的,
这么悬殊的差异只有可能是算法本身造成的
要不谁来写一个解线形方程组得过程,看看是否能更快
目前在我PIII 900的机器下,使用MS的VC
计算512*512
如果不使用编译器优化大概是 3-4秒,
如果使用编译器优化 /O2大概2秒
计算1024*1024
如果不使用编译器优化大概是 40秒,
如果使用编译器优化 /O2 大概20秒
顺便贴一下使用C#实现的速度结果
计算512*512 大概是 4秒
计算1024*1024 大概是 30秒
寻开心
2005-01-19
打赏
举报
回复
单纯的对一个程序的测试估算时间没有多大的意义
重点要做的是检测算法本身以及代码编写当中可优化的地方
任何一个理论上的算法, 到具体的实践代码的转换过程当中都是有可能造成数倍,几十倍甚至成百上千倍的运行速度上的差异的, 原因就是编码水平和优化技巧的使用的问题
寻开心
2005-01-19
打赏
举报
回复
它的运算量是可以预计的啊
对于第n列来说,涉及到的是 n-1*(交换或者是消元计算, 交换也好, 消元也好都是n次计算), 所以是O(n^2)的计算两
因此总体变成上三角时候,就是 O(n^3)的计算量
再次回退计算结果的时候, 和上面的过程类似
所以总的计算量就是O(n^3)这个数量级的
如果你认为你的速度慢, 首先是检测你的计算方法有无问题
其次是看在那个部分运行占据的时间最多, 然后优化它
时间计算,如果在VC下用GetTickCount这样的毫米级的时钟就可以了
dongpy
2005-01-19
打赏
举报
回复
<数值分析>里编过高斯消去法解线性方程组,不过没有512 * 512 这么大.
PIII900的机器上运行3-4秒,我觉得不是很慢.
mathe
2005-01-19
打赏
举报
回复
增加内存,换个L2Cache大些的CPU的就可以加快速度
nicknide
2005-01-19
打赏
举报
回复
选择你相信的,相信你选择的
仅此而已。
如果你认为C#对你更加合适,大可以用C#啊……
C的优势并不在数值运算,而在于对地层的接近上,因此适合做系统。
如果搂主追求数值计算的速度,推荐用Fortain
tiaoci
2005-01-19
打赏
举报
回复
你有看到C#的相应数据吗?关键是相同的代码C#也能达到3-4秒和 30秒
而且在1024*1024时,C#的速度甚至比c未优化前的还快(30秒:40秒)
如果只有这么点差异,那么用c是否还有意义?
DiabloWalkOnTheEarth
2005-01-19
打赏
举报
回复
已经如此简单的东西了,如果不是使用别的算法,速度都不会有明显的提高了.
swap时用 memcpy 应该没什么用,程序主要运行的时间不是在 swap 而在消去操作的地方.
寻开心
2005-01-19
打赏
举报
回复
另外, 既然你对你的算法和代码都很有信心,
那么你就应该认可你的执行速度
你在怀疑什么呢?
寻开心
2005-01-19
打赏
举报
回复
从这个程序看, 你的代码已经写的很好了
但是也不是没有可以优化的地方
比如行交换的地方, 使用memcpy替代逐个的交换数据
例如, 在malloc 指针的时候, 再多malloc一个临时空间double * t
行交换就是
memcpy(t, i行, 长度)
memcpy(i行, j行, 长度)
memcpy(j行, t, 长度)
对max的除法转换对统一的max的倒数的乘法
在对行循环的时候, 数组的开始地址可以用指针方式
这些优化可以对效率有一定的提高, 但是不会是翻倍的提高
sunwebmaster
2005-01-18
打赏
举报
回复
vc中测试一段程序的运行时间我这样写了:
void CTestTimeView::OnMyTestTime()
{
CClientDC pDC(this);
CString str;
int timer=0,t,x=50,y=-10;
double counter=0.0;
SYSTEMTIME st,et;
GetSystemTime(&st);
while(counter<1.0e+6)
counter+=0.1;
GetSystemTime(&et);
if(t=et.wHour-st.wHour)
timer+=t*60*60*1000;
if(t=et.wMinute-st.wMinute)
timer+=t*60*1000;
if(t=et.wSecond-st.wSecond)
timer+=t*1000;
t=et.wMilliseconds-st.wMilliseconds;
timer+=t;
str.Format("start time=%d(h)",et.wHour);
pDC.TextOut(x,y+=20,str);
str.Format("start time=%d(h)",st.wHour);
pDC.TextOut(x,y+=20,str);
str.Format("start time=%d(m)",et.wMinute);
pDC.TextOut(x,y+=20,str);
str.Format("start time=%d(m)",st.wMinute);
pDC.TextOut(x,y+=20,str);
str.Format("start time=%d(s)",et.wSecond);
pDC.TextOut(x,y+=20,str);
str.Format("start time=%d(s)",st.wSecond);
pDC.TextOut(x,y+=20,str);
str.Format("start time=%d(ms)",et.wMilliseconds);
pDC.TextOut(x,y+=20,str);
str.Format("start time=%d(ms)",st.wMilliseconds);
pDC.TextOut(x,y+=20,str);
str.Format("total time=%d(ms)",timer);
pDC.TextOut(x,y+=20,str);
} 但是,小时显示的总比实际的少8个小时,大家看看
cfadongdongcfa
2005-01-18
打赏
举报
回复
差不多了,高斯的效率本来就低
tiaoci
2005-01-18
打赏
举报
回复
竟然没人做过这种事?
tiaoci
2005-01-17
打赏
举报
回复
up
高斯消去法
和列主元
高斯消去法
解
线性
方程组
的程序C
语言
.doc
高斯消去法
和列主元
高斯消去法
解
线性
方程组
的程序C
语言
列主元
高斯消去法
解
线性
方程组
的程序(MATLAB版)
列主元
高斯消去法
解
线性
方程组
的MATLAB程序,参考教材《数值分析》李乃成
大白话EM算法--从此爱上EM迭代
1.8EM算法案例 1.9EM算法应用之GMM(高斯混合模型)的目标函数表示 1.10EM算法应用之GMM(高斯混合模型)的迭代过程 1.11EM算法代码之手动
实现
GMM迭代过程 1.12EM算法代码之基于sklearn身高性别数据GMM高斯混合聚类
实现
高斯列主元消去法
解
线性
方程组
--课程设计报告
高斯列主元消去法
解
线性
方程组
--课程设计报告,里边描述了整个课程的
实现
过程,且附有截图及代码
基于
高斯消去法
解
线性
方程组
(MPI)
基于
高斯消去法
解
线性
方程组
(MPI),
高斯消去法
把Ax=b归约为上三角
方程组
Tx=c,这样利用回带算法求
解
x。第i次迭代时,选取i列的最大元素作为主元,主元所在的行称为枢轴行(枢轴行的行数会被标记),枢轴行与第i行...
C语言
69,371
社区成员
243,082
社区内容
发帖
与我相关
我的任务
C语言
C语言相关问题讨论
复制链接
扫一扫
分享
社区描述
C语言相关问题讨论
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
暂无公告
试试用AI创作助手写篇文章吧
+ 用AI写文章