Сводка вопроса
Есть ли способ обновить вероятности в существующем экземпляре класса EnumeratedIntegerDistribution без создания совершенно нового экземпляра?
Фон
Я пытаюсь реализовать упрощенную демонстрацию стиля Q-обучения с помощью телефона Android. Мне нужно обновить вероятности для каждого элемента с каждым циклом в процессе обучения. В настоящее время я не могу найти какой-либо метод, доступный из моего экземпляра enumeratedIntegerDistribution
, который позволил бы мне сбросить | обновить | изменить эти вероятности. Таким образом, единственный способ сделать это - создать новый экземпляр EnumeratedIntegerDistribution в каждом цикле. Учитывая, что длина каждого из этих циклов составляет всего 20 мс, я понимаю, что это будет ужасно неэффективно по сравнению с созданием одного экземпляра и обновлением значений в существующем экземпляре. Нет ли стандартных методов стиля набора для обновления этих вероятностей? Если нет, есть ли рекомендуемый способ обхода (например, использование другого класса, создание собственного класса, переопределение чего-либо, чтобы сделать его доступным и т. Д .?)
Последующее решение будет, является ли этот вопрос спорнымусилия. Будет ли скомпилированный код на самом деле более / менее эффективным, пытаясь избежать этого нового экземпляра каждый цикл? (Я недостаточно осведомлен, чтобы знать, как компиляторы будут обрабатывать такие вещи).
Код
Ниже приведен минимальный пример:
package com.example.mypackage.learning;
import android.app.Activity;
import android.os.Bundle;
import org.apache.commons.math3.distribution.EnumeratedIntegerDistribution;
public class Qlearning extends Activity {
private int selectedAction;
private int[] actions = {0, 1, 2};
private double[] weights = {1.0, 1.0, 1.0};
private double[] qValues = {1.0, 1.0, 1.0};
private double qValuesSum;
EnumeratedIntegerDistribution enumeratedIntegerDistribution = new EnumeratedIntegerDistribution(actions, weights);
private final double alpha = 0.001;
int action;
double reward;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
while(true){
action = determineAction();
reward = determineReward();
learn(action, reward);
}
}
public void learn(int action, double reward) {
qValues[selectedAction] = (alpha * reward) + ((1.0 - alpha) * qValues[selectedAction]);
qValuesSum = 0;
for (int i = 0; i < qValues.length; i++){
qValuesSum += Math.exp(qValues[i]);
}
weights[selectedAction] = Math.exp(qValues[selectedAction]) / qValuesSum;
// *** This seems inefficient ***
EnumeratedIntegerDistribution enumeratedIntegerDistribution = new EnumeratedIntegerDistribution(actions, weights);
}
}
Пожалуйста, не сосредотачивайтесь на отсутствии методов determineAction()
или determineReward()
, так как это простоминимальный пример. Вы можете легко просто вставить фиксированные значения там (например, 1 и 1,5), если вы хотите рабочий пример.
Кроме того, я хорошо осведомлен о бесконечном цикле while, который будет проблематичным для графического интерфейса, но опять же, просто пытаюсь сократить код, который я должен показать здесь, чтобы понять суть.