问题
For example I need to get all combinations of 2-values array with numbers {0, 1, 2} where this two numbers are not the same. I get
0 1
0 2
1 0
1 2
2 0
2 1
and I ignore
0 0
1 1
2 2
Now I use
for (int i= 0; i < L ; i++) {
for (int j = 0; j < L; j++) {
if (i!= j) {
but it is very slow? Any solution for this? L will be > 4000.
What am I doing is finding every combinations of splitting matrix to 4 sub-matrices
example:
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
and computing their sum using sum-table.
Related question: Split matrix into 4 sub-matrices with lowest difference between their sum
So for matix I have one horizontal line and two vertical and I am computing sum of 4 matrices, but two vertical lines should not crate one big vertical line, so i != j.
UPDATE 1 order of the pairs is relevant
回答1:
you could improve the perfomance by:
for (int i= 0; i < L ; i++) {
for (int j = i + 1 ; j < L; j++) {
System.out.println.(i + " " + j + "\n" + j + " " + i);
}}
回答2:
If the order of the pairs is relevant (e.g. you want to consider both {1, 2}
and {2, 1}
as different), there is way to get a significant speedup at this level.
If the order of the pairs is irrelevant (e.g. you have considered {1, 2}
you can skip {2, 1}
), then @goten's Answer gives you a factor of 2 speedup. UPDATE the Question has been updated to confirm that the order is relevant ... so @goten's solution is not applicable.
You are unlikely to get a significant speedup by micro-optimizing it; e.g. turning it into a while loop, etc. The JIT compiler is most likely doing the equivalent optimizations behind the scenes anyway.
If you want better speedup, you will need to change your overall algorithm so that you don't need to consider so many combinations. Whether that is feasible will depend on your problem.
The other alternative to consider is processing the combinations in parallel. However, that only helps if you have multiple cores ... and your problem / algorithm are suitable for parallelization.
UPDATE - Your problem (per the updated question), looks like it should be suitable for parallelization, though you may need to do some careful tuning to minimize the effects of memory contention in accessing the large shared input array.
回答3:
for given pole and c is size of pole
long[] radky = new long[x];
long cisloRadku = 0;
long min = 0;
int q;
int radek = 0;
for (q = 0; q < (x); q++) {
for (int j = 0; j < x; j++) {
radky[q] += pole[q][j];
}
cisloRadku += radky[q];
}
long hodnota1 = 0;
long hodnota2 = 0;
for (int i = 0; i < (x - 1); i++) {
hodnota1 += radky[i];
hodnota2 = cisloRadku - hodnota1;
long druheMin = hodnota1 - hodnota2;
if (druheMin < 0) {
druheMin = druheMin * (-1);
}
if (i == 0) {
min = druheMin;
}
if (min > druheMin) {
min = druheMin;
radek = i;
}
}
long[][] poleHorni = new long[radek + 1][x];
long[][] poleDolni = new long[x - (radek + 1)][x];
for (int i = 0; i < (radek + 1); i++) {
for (int j = 0; j < x; j++) {
poleHorni[i][j] = pole[i][j];
}
}
long[] soucetHornich = new long[x];
long soucetSlopucuUp = 0;
for (int k = 0; k < x; k++) {
for (int j = 0; j < radek + 1; j++) {
soucetHornich[k] += poleHorni[j][k];
}
soucetSlopucuUp += soucetHornich[k];
}
long cislo1 = 0;
long cislo2;
int sloupec = 0;
long min2 = 0;
for (int i = 0; i < (x - 1); i++) {
cislo1 += soucetHornich[i];
cislo2 = soucetSlopucuUp - cislo1;
long druheMin2 = cislo1 - cislo2;
if (druheMin2 < 0) {
druheMin2 = druheMin2 * (-1);
}
if (i == 0) {
min2 = druheMin2;
vysledky[0] = cislo1;
vysledky[1] = cislo2;
}
if (min2 > druheMin2) {
min2 = druheMin2;
sloupec = i;
vysledky[0] = cislo1;
vysledky[1] = cislo2;
}
}
int a = 0;
int b = 0;
for (int i = (radek + 1); i < (x); i++) {
for (int j = 0; j < x; j++) {
poleDolni[a][b] = pole[i][j];
b++;
}
b = 0;
a++;
}
long[] soucetDolnich = new long[x];
long soucetSlopucuDown = 0;
for (int k = 0; k < x; k++) {
for (int j = 0; j < (x - (radek + 1)); j++) {
soucetDolnich[k] += poleDolni[j][k];
}
soucetSlopucuDown += soucetDolnich[k];
}
long cislo1A = 0;
long cislo2A;
long min2A = 0;
for (int i = 0; i < (x - 1); i++) {
cislo1A += soucetDolnich[i];
cislo2A = soucetSlopucuDown - cislo1A;
long druheMin2A = cislo1A - cislo2A;
if (druheMin2A < 0) {
druheMin2A = druheMin2A * (-1);
}
if (i == 0) {
min2A = druheMin2A;
vysledky[2] = cislo1A;
vysledky[3] = cislo2A;
}
if (min2A > druheMin2A) {
min2A = druheMin2A;
vysledky[2] = cislo1A;
vysledky[3] = cislo2A;
}
long[] vyslRozdil = new long[6];
vyslRozdil[0] = vysledky[0] - vysledky[1];
vyslRozdil[1] = vysledky[0] - vysledky[2];
vyslRozdil[2] = vysledky[0] - vysledky[3];
vyslRozdil[3] = vysledky[1] - vysledky[2];
vyslRozdil[4] = vysledky[1] - vysledky[3];
vyslRozdil[5] = vysledky[2] - vysledky[3];
long max = 0;
long max2;
for (int i = 0; i < 6; i++) {
if (vyslRozdil[i] < 0) {
vyslRozdil[i] *= -1;
}
max2 = vyslRozdil[i];
if (i == 0) {
max = max2;
}
if (max < max2) {
max = max2;
}
}
System.out.println(max);
回答4:
You might be able to get some benefit from
for (int i= 0; i < L ; ++i) {
int j=0;
for (; j < i; ++j) {
}
for (++j; j < L; ++j) {
}
}
which avoids testing L
while you're still testing i
. I've also switched to pre-increment -- since you aren't using the result it probably doesn't make any difference after the optimizer is done with it, but postincrement is, conceptually, a more complicated operation unless there happens to be instruction-set support for it.
If you can change the order in which results are reported, this would be faster:
int L1=L-1;
for (int i=L1; i >=0 ; --i) {
int j=L1;
for (; j > i; --j) {
}
for (--j; j >=0; --j) {
}
}
Testing against most values requires a subtraction. Testing against zero doesn't; it occurs "for free" when the value is loaded. In fact, you could improve it further:
int L1=L-1, i=L1;
do {
int j=L1;
do {
} while(--j>i);
while(--j>=0)
{
}
} while(--i >= 0);
That avoids the redundant initial test. (Note that you still need to test at the top of the second loop, in case i was 0.)
However, in fact the loop overhead is the least of your problems here; the System.out.println() calls are going to consume far more cycles than the loop control will.
来源:https://stackoverflow.com/questions/22109043/loop-i-and-j-where-i-j