Ищете эффективный способ обновления многомерных массивов - PullRequest
0 голосов
/ 04 января 2019

Я обновляю значения многомерного массива (Y [i] [t] [k]). Поскольку обновление должно выполняться в течение многих итераций, время выполнения этой части кода действительно важно. Мне было интересно, если кто-нибудь знает, как сделать это более эффективным способом.

Ниже приведена часть, которую необходимо обновить.

double [][][] Y=new double [a.length][b.length][c.length];
for(int i=0;i<a.length;i++){
 for(int j=0;j<b;j++){
  for (int k=0; k<c.length; k++){
    if(i==w && j==r && k==u){// w, r and u can have any value.
      Y[i][j][k]=g;
     }else{
      Y[i][j][k]=f; 
     }
    }
  }
}

Обратите внимание, что:

    a is int [][].
    b is int.
    c is int [][].
    q is double.
    YIN is double [][][].
    F is double.
    g=q*YIN[i][j][k]+(1-q)*(Y[i][j][k]-F)
    f=q*YIN[i][j][k]+(1-q)*(Y[j][j][k])

Ответы [ 2 ]

0 голосов
/ 04 января 2019

Как я понял из вашего кода, ваша цель - установить Y [0] [0] [10] на g и другие элементы на f .

Так как насчет того, чтобы забыть о сумасшедших циклах и делать как в следующем коде?

Arrays.fill(Y, f);

Y[0][0][10] = g;
0 голосов
/ 04 января 2019

Вы устанавливаете каждый элемент области вашего многомерного массива по стоимости, пропорциональной количеству установленных элементов, поэтому нет оснований думать, что вы можете сделать это асимптотически лучше. Однако вполне вероятно, что вы можете получить некоторое увеличение скорости, используя методы массовой операции и обрабатывая особый случай вне цикла вместо того, чтобы проверять его на каждой итерации. Например,

for (int i = 0; i < a.length; i++) {
    for (int j = 0; j < b.length; j++) {
        Arrays.fill(Y[i][j], 0, c.length, f);
    }
}

if (c.length > 10) {
    Y[0][0][10] = g;
}

Конечно, это предполагает, что f является константным выражением или, по крайней мере, каждая его оценка равна любой другой (в смысле оператора ==) и не вызывает побочных эффектов. В этом случае, вероятно, еще лучше использовать массовое копирование вместо массовых настроек, где вы можете сделать это:

for (int i = 0; i < a.length; i++) {
    Arrays.fill(Y[i][0], 0, c.length, f);
    for (int j = 1; j < b.length; j++) {
        System.arraycopy(Y[i][0], 0, Y[i][j], 0, c.length);
    }
}

if (c.length > 10) {
    Y[0][0][10] = g;
}

Если выражение f не удовлетворяет указанным выше требованиям, лучшее, что вы можете сделать, - это просто вывести особый случай из цикла, не меняя ничего другого. Для некоторых выражений f и / или g даже это может оказаться невозможным в том смысле, что оно может привести к неэквивалентному результату. Например, это может быть в случае, когда один или оба сохраняют состояние каким-либо соответствующим способом, например, закрывая счетчик.

...