Как эффективно обновить вероятности в экземпляре EnumeratedDistribution? - PullRequest
0 голосов
/ 11 ноября 2019

Сводка вопроса

Есть ли способ обновить вероятности в существующем экземпляре класса 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, который будет проблематичным для графического интерфейса, но опять же, просто пытаюсь сократить код, который я должен показать здесь, чтобы понять суть.

...