例如,我需要得到数字{0,1,2}的2-值数组的所有组合,其中这两个数字并不相同。我得到了
0 1
0 2
1 0
1 2
2 0
2 1而我忽略了
0 0
1 1
2 2现在我用
for (int i= 0; i < L ; i++) {
for (int j = 0; j < L; j++) {
if (i!= j) {但是它很慢?有什么解决办法吗?我将超过4000。
我要做的是找出将矩阵分解成4个子矩阵的每一个组合。
示例:
3 | 0 2 -8 -8
5 | 3 2 2 3
2 | 5 2 1 4
-------------------
3 4 -1 | 4 2
-3 6 2 | 4 3用和表计算他们的和。
相关问题:Split matrix into 4 sub-matrices with lowest difference between their sum
所以对于matix,我有一条水平线和两条垂直线,我正在计算4个矩阵的和,但是两条垂直线不应该把一条大的垂直线,所以i != j。
更新1对顺序是相关的
发布于 2014-03-01 01:52:14
你可以通过以下方式来提高业绩:
for (int i= 0; i < L ; i++) {
for (int j = i + 1 ; j < L; j++) {
System.out.println.(i + " " + j + "\n" + j + " " + i);
}}发布于 2014-03-01 02:10:45
你也许能从
for (int i= 0; i < L ; ++i) {
int j=0;
for (; j < i; ++j) {
}
for (++j; j < L; ++j) {
}
}这样可以避免在您还在测试L时测试i。我还切换到了预增量--因为您没有使用结果--在优化器完成后,它可能不会有任何不同,但从概念上讲,如果没有指令集支持,后置增量是一个更复杂的操作。
如果您可以更改报告结果的顺序,这将更快:
int L1=L-1;
for (int i=L1; i >=0 ; --i) {
int j=L1;
for (; j > i; --j) {
}
for (--j; j >=0; --j) {
}
}对大多数值进行测试需要减法。对零的测试不是这样的;当加载值时,它会“免费”发生。实际上,您可以进一步改进它:
int L1=L-1, i=L1;
do {
int j=L1;
do {
} while(--j>i);
while(--j>=0)
{
}
} while(--i >= 0);这样就避免了冗余的初始测试。(请注意,您仍然需要在第二个循环的顶部进行测试,以防我是0。)
但是,实际上,循环开销是这里问题最少的部分;System.out.println()调用将消耗比循环控件更多的周期。
发布于 2014-03-01 02:13:31
如果对的顺序是相关的(例如,您希望将{1, 2}和{2, 1}视为不同的),那么可以在这个级别上获得显着的加速。
如果这些对的顺序无关(例如,您已经考虑过{1, 2},您可以跳过{2, 1}),那么@goten的回答给出了2加速比的因子。更新问题已经更新以确认订单是相关的.所以@goten的解决方案是不适用的。
通过对其进行微优化,您不太可能得到显著的加速;例如,将其转换为while循环,等等。无论如何,JIT编译器最有可能在幕后进行等效的优化。
如果你想要更好的加速,你将需要改变你的整体算法,这样你就不需要考虑这么多的组合。这是否可行将取决于你的问题。
另一个需要考虑的选择是并行处理这些组合。但是,只有当你有多个核心时才有帮助.你的问题/算法适合并行化。
UPDATE --您的问题(根据更新的问题)看起来应该适合并行化,尽管您可能需要进行一些仔细的调优,以尽量减少访问大型共享输入数组时内存争用的影响。
https://stackoverflow.com/questions/22109043
复制相似问题