虽然你可能不会认识到这一点,但你的问题可能比方案拟定问题更是一个线性-摩布拉问题,尽管它确实涉及方案拟定问题。
在这项答复中,我假定,你的实际问题可能比N = 8 篮子大得多。 首次进行数学讨论。 样本代码如下。
班轮图书馆问题的性质似乎是,它们实际上可以采用普通班轮式图书馆技术处理,或者没有。 自1960年代以来,全面开发了诸如L-U系数化和单项价值分解等一般线-图书馆技术,具有坚实的理论基础。 问题在于,这种一般技术倾向于O(N*N*N)进行计算处理,也就是说,使你的病媒需要10倍以上的计算机时间来治疗。 除了一些最大的实际规模外,你的问题在计算上变得难以解决——至少是一般线性图书馆技术造成的。
FI YOUR PROBLEM ISEXTREMELY LARGE
幸运的是,存在着各种特殊用途技术,将O(N*N)问题减少到O(N*N)问题。 这些技术大多自1960年代以来出现,是积极研究的领域。 不幸的是,要了解哪些技术可以适用,以及怎样,需要对这个问题有密切的理解,并公平地掌握数学矩阵。 在O(N*N*N),人们知道一般技术。 在O(N*N)没有一般技术,只有许多特殊用途技术从事限制型系统的工作。 如果你工作的时间足够长,你往往可以找到适当的限制,但从来不像把你的矩阵放在某些普通用途解决器上那样简单。 不在O(N*N)。
我阅读的关于这个主题的最好书是:Henk A. van der Vorst s Iterative Krylov Methods for Great Linear Systems.。 估计该书的价格是合理的。 当然,在处理van der Voorst之前,你需要一种以一般线性-algebra技术为基础的坚实基础。 我建议Joel N. 富兰克林于1968年出版的书Matrix Theory,,可在Dover1993年廉价纸张上查阅。 (Van der Vorst没有提及Kapp s和Browns clever,简单而且常常是有效的多管交方法,我一再认为这种做法有用,因此请允许我在此提及,以便你能够在必要时研究。 披露: 我亲眼知道布朗,因此可以部分发言;但是,他和Kapp的手法是一种罚款,它会破坏Vorst。
出于我不完全理解的原因,最近的大多数技术(虽然不是Kapp s和Brown s)似乎更倾向于以实际数字工作,将复杂数目作为特殊案例处理,或完全忽视这些技术。 你没有提及你的人数是否复杂,但如果是,这可能会限制你们的选择。
作为富兰克兰克林和范德韦斯特之间的中间层次,如果你没有时间或兴趣来应对后者,那么你至少应当研究并熟悉梯度法。
法国
如果你的问题非常大——例如,N <20,000左右——那么你的任务就更加容易了。 Forget van der Vorst in this case: You no need he. 视你是否想要回答小秒、秒、几分钟或数小时(你提到,虽然这只影响到对N的实际限制),你可以容忍O(N*N)的表现,在这种情况下,Cranklin从1960年代开始的一般技术相当有力。
快速、高效、彻底和正确,LAPACK图书馆及其低级助手BLAS是该领域的标准。 你们应当使用这些工具。
LAPACK, BLAS and C++
一组地雷和我分别尝试了LAPACK和BLAS的各种C和C++接口。 出于各种原因,我们发现其中没有一个完全令人满意,尽管它们确实发挥了有益的作用。 我们大家最终决定完全绕过接口,并直接使用LAPACK和BALAS。 我倾向于建议你这样做。
LAPACK和BALAS据称是从第77号大通车而不是从C++号船运来的。 然而,将其从C++中删除并非如此困难,你不需要C++接口。 事实上,你可能不想使用C++接口,至少不是由他人编写的通用接口。 如果你不把他们other在一边的话,LAPACK和BLAS就会成为 ha。 (注意到连接设施虽然有限,但其连接设施却缺乏C型头盔档案)
你们必须知道直接使用LAPACK和BALAS的第一件事就是这样,在你们理解之前,你会错失:矩阵被储存在一栏-major。 也就是说,每个栏目,而不是每栏,都按顺序作为单位记名。 因此,一个矩阵元件立即储存在上面和以下各点之间,而不是在所剩要素和权利之间。 实际上,LAPACK和BALAS谨慎地为Cernighan和Ritchie储存这种玉米,他们发明C,从来似乎对线性黄色图书馆非常感兴趣。 C是一种精细的语言,但C的缺省矩阵储存公约可能从一开始就是错误的。 从数学角度来说,LAPACK和BAA储存了它们应当储存的方式的矩阵,一栏;如果是书写直线图书馆的代码,那么你也应以这种方式储存其矩阵。 Ignore C sail, row-major Convention: It has no to do with the conventions of Max and You do not ne it.
Here is a complete example:
#include <iostream>
extern "C" {
void dgesv_(
const int *N,
const int *NRHS,
double *A,
const int *LDA,
int *IPIV,
double *B,
const int *LDB,
int *INFO
);
}
int main()
{
const int N = 2;
// Let A = | 3.0 6.1 |
// |-1.2 1.7 |
double A[N*N] = {3.0, -1.2, 6.1, 1.7};
// Let b = | 5.5 |
// | 0.4 |
double x[N] = {5.5, 0.4};
// (Why is b named x? Answer: because b and x share
// the same storage, because Lapack will write x over b.)
// Solve the linear system A*x = b.
const int NRHS = 1;
const int LDA = N;
int IPIV [N];
const int LDB = N;
int INFO;
dgesv_(&N, &NRHS, A, &LDA, IPIV, x, &LDB, &INFO);
// Uncomment the next line if you wish to see
// the error code Lapack returns.
//std::cout << "INFO == " << INFO << "
";
// Output x.
for (int i = 0; i < N; ++i) std::cout << x[i] << "
";
return 0;
}
[这种职能的名称是dgesv_()? 答复:它指名DGESV,至少在第77号表格中。 然而,第77号邮管组织对个案不敏感,而且当我们把这一点转化为连接公约时,我们就得 d。 至少,这符合我的同事和我所掌握的每台六氯环己烷、BSD或OSX机器。 在Debian或Utu,“Embols /usr/libla Pack.so Čep-i DGESV”发现这一点。 在Microsoft平台上,C-linked文号可能还有其他一些名称:如果与你有关,你必须调查。]
LAPACK and BLAS are very good at what they do. You should use them.
Whether you store your data in C-style arrays (as the example does) or in C++-style std::valarrays is up to you. LAPACK and BLAS don t care, so long as the storage is column-major.
科摩罗
你没有向我提供足够的资料,以确切说明你希望与你的系数做些什么,但一名嫌疑人认为,你可能需要的是解决一个N-by-(2*N)未定系统的问题。 这种做法超出了富兰克林书的范围,但如果你已经吸收了富兰克林材料,那么my本身关于假冒的说明可帮助您。
Obviously, if you were looking for a quick solution, I don t have it. There may be a precanned software package that does precisely what you want, but my experience suggests that the odds are against you in this. There are just too many hundreds of distinct kinds of matrix problems that arise in practice for precanned software to crack. However, LAPACK and BLAS, together with Franklin, van der Vorst and the answer you are now reading, offer all the tools you should need to crack your specific problem.
Good luck.