package be.iminds.iot.dianne.rl.agent;

import java.util.Arrays;
import java.util.Map;

import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;

import be.iminds.iot.dianne.tensor.Tensor;
import be.iminds.iot.dianne.tensor.TensorFactory;

@Component(property={"strategy=greedy"})
public class GreedyActionStrategy implements ActionStrategy {
	
	private TensorFactory factory;
	
	private double epsilonMax = 1e0;
	private double epsilonMin = 0;
	private double epsilonDecay = 1e-6;
	
	public Tensor selectActionFromOutput(Tensor output, long i) {
		
		Tensor action = factory.createTensor(output.size());
		action.fill(-1);
		
		double epsilon = epsilonMin + (epsilonMax - epsilonMin) * Math.exp(-i * epsilonDecay);
		
		if(i % 1000 == 0)
			System.out.println(i + "\tQ: " + Arrays.toString(output.get()) + "\te: " + epsilon);

		if (Math.random() < epsilon) {
			action.set(1, (int) (Math.random() * action.size()));
		} else {
			action.set(1, factory.getTensorMath().argmax(output));
		}
		
		return action;
	}
	
	@Override
	public void configure(Map<String, String> config) {
		if (config.containsKey("epsilonMax"))
			epsilonMax = Double.parseDouble(config.get("epsilonMax"));
		
		if (config.containsKey("epsilonMin"))
			epsilonMin = Double.parseDouble(config.get("epsilonMin"));
		
		if (config.containsKey("epsilonDecay"))
			epsilonDecay = Double.parseDouble(config.get("epsilonDecay"));
		
		System.out.println("Greedy Action Selection");
		System.out.println("* epsilon max = "+epsilonMax);
		System.out.println("* epsilon min = "+epsilonMin);
		System.out.println("* epsilon decay = "+epsilonDecay);
		System.out.println("---");
	}

	@Reference
	public void setTensorFactory(TensorFactory f){
		this.factory =f;
	}
}

@@ -37,33 +37,8 @@
 t;%0A%0A
-import java.util.Arrays;%0A
 impo
@@ -170,16 +170,132 @@
 erence;%0A
+import org.osgi.service.component.annotations.ReferenceCardinality;%0A%0Aimport be.iminds.iot.dianne.api.log.DataLogger;
 %0Aimport 
@@ -625,16 +625,126 @@
 1e-6;%0A%09%0A
+%09private DataLogger logger = null;%0A%09private String%5B%5D loglabels = new String%5B%5D%7B%22Q0%22, %22Q1%22, %22Q2%22, %22epsilon%22%7D;%0A%09%0A
 %09public 
@@ -979,101 +979,113 @@
 %09if(
-i %25 1000 == 0)%0A%09%09%09System.out.println(i + %22%5CtQ: %22 + Arrays.toString(output.get()) + %22%5Cte: %22 + 
+logger!=null)%7B%0A%09%09%09logger.log(%22AGENT%22, loglabels, output.get()%5B0%5D,output.get()%5B1%5D,output.get()%5B2%5D, (float)
 epsi
@@ -1090,16 +1090,22 @@
 silon);%0A
+%09%09%7D%0A%09%09
 %0A%09%09if (M
@@ -1997,10 +1997,275 @@
  =f;%0A%09%7D%0A
+%09%0A%09@Reference(cardinality = ReferenceCardinality.OPTIONAL)%0A%09public void setDataLogger(DataLogger l)%7B%0A%09%09this.logger = l;%0A%09%09this.logger.setAlpha(%22epsilon%22, 1f);%0A%09%09this.logger.setAlpha(%22Q0%22, 1f);%0A%09%09this.logger.setAlpha(%22Q1%22, 1f);%0A%09%09this.logger.setAlpha(%22Q2%22, 1f);%0A%09%7D%0A%0A
 %7D%0A

use DataLogger for printing in GreedyActionStrategy