From c4985f2ed525341a2408ecdb34a5808a5c549101 Mon Sep 17 00:00:00 2001
From: Hugo Roussel <hugo.roussel@univ-tlse3.fr>
Date: Thu, 11 Jul 2019 16:16:58 +0200
Subject: [PATCH] Refactor LocalModel

---
 AMOEBAonAMAK/src/agents/context/Context.java  |  36 ++----
 .../agents/context/localModel/LocalModel.java | 121 +++++++++++++-----
 .../LocalModelMillerRegression.java           | 114 +++++------------
 AMOEBAonAMAK/src/agents/head/Head.java        |  13 +-
 AMOEBAonAMAK/src/kernel/AMOEBA.java           |   2 +-
 5 files changed, 138 insertions(+), 148 deletions(-)

diff --git a/AMOEBAonAMAK/src/agents/context/Context.java b/AMOEBAonAMAK/src/agents/context/Context.java
index 0f601e60..652269f8 100644
--- a/AMOEBAonAMAK/src/agents/context/Context.java
+++ b/AMOEBAonAMAK/src/agents/context/Context.java
@@ -150,8 +150,7 @@ public class Context extends AmoebaAgent {
 		// world.trace(new ArrayList<String>(Arrays.asList(this.getName(),"NEW EXP",
 		// firstPoint.toString())));
 
-		localModel.updateModel(this.getCurrentExperiment(), getAmas().data.learningSpeed,
-				getAmas().data.numberOfPointsForRegression);
+		localModel.updateModel(this.getCurrentExperiment(), getAmas().data.learningSpeed);
 		getAmas().addAlteredContext(this);
 		this.setName(String.valueOf(this.hashCode()));
 
@@ -212,7 +211,7 @@ public class Context extends AmoebaAgent {
 			Double[] coef = ((LocalModelMillerRegression) fatherContext.localModel).getCoef();
 			((LocalModelMillerRegression) this.localModel).setCoef(coef);
 			this.actionProposition = ((LocalModelMillerRegression) fatherContext.localModel)
-					.getProposition(fatherContext);
+					.getProposition();
 		}
 
 		getAmas().addAlteredContext(this);
@@ -274,13 +273,12 @@ public class Context extends AmoebaAgent {
 			Double[] coef = ((LocalModelMillerRegression) bestNearestContext.localModel).getCoef();
 			((LocalModelMillerRegression) this.localModel).setCoef(coef);
 			this.actionProposition = ((LocalModelMillerRegression) bestNearestContext.localModel)
-					.getProposition(bestNearestContext);
+					.getProposition();
 		}
 		
 		localModel.setFirstExperiments(new ArrayList<Experiment>(bestNearestContext.getLocalModel().getFirstExperiments()));
 
-		localModel.updateModel(this.getCurrentExperiment(), getAmas().data.learningSpeed,
-				getAmas().data.numberOfPointsForRegression);
+		localModel.updateModel(this.getCurrentExperiment(), getAmas().data.learningSpeed);
 
 		getAmas().addAlteredContext(this);
 		this.setName(String.valueOf(this.hashCode()));
@@ -543,7 +541,7 @@ public class Context extends AmoebaAgent {
 		((LocalModelMillerRegression) this.localModel).setCoef(coef);
 
 		this.actionProposition = ((LocalModelMillerRegression) betterContext.getLocalModel())
-				.getProposition(betterContext);
+				.getProposition();
 	}
 
 	public void analyzeResults3(Head head, Context closestContextToOracle) {
@@ -959,14 +957,6 @@ public class Context extends AmoebaAgent {
 		return exp;
 	}
 
-	private boolean tryNewExperiment2() {
-		if (localModel.distance(getCurrentExperiment()) < 10.0) {
-			localModel.updateModelWithExperimentAndWeight(getCurrentExperiment(), 0.5, 100);
-			return true;
-		}
-		return false;
-	}
-
 	public double sumOfRangesLengths() {
 		double sum = 0;
 
@@ -1910,8 +1900,8 @@ public class Context extends AmoebaAgent {
 		s += "Context : " + getName() + "\n";
 		s += "Model : ";
 		s += this.localModel.getCoefsFormula() + "\n";	
-		s += "Max Prediction " + getLocalModel().getMaxProposition(this) + "\n";
-		s += "Min Prediction " + getLocalModel().getMinProposition(this) + "\n";
+		s += "Max Prediction " + getLocalModel().getMaxProposition() + "\n";
+		s += "Min Prediction " + getLocalModel().getMinProposition() + "\n";
 		return s;
 	}
 	
@@ -1922,8 +1912,8 @@ public class Context extends AmoebaAgent {
 		for(int i =1;i<localModel.getCoef().length;i++) {
 			array.add(""+localModel.getCoef()[i]);
 		}
-		array.add(""+ getLocalModel().getMinProposition(this));
-		array.add(""+ getLocalModel().getMaxProposition(this));
+		array.add(""+ getLocalModel().getMinProposition());
+		array.add(""+ getLocalModel().getMaxProposition());
 
 		return array;
 	}
@@ -1951,8 +1941,8 @@ public class Context extends AmoebaAgent {
 		s += "Mean Distance To Regression " + criticalities.getCriticalityMean("distanceToRegression") + "\n";
 		s += "Distance To Regression Allowed " + regressionPerformance.getPerformanceIndicator() +"\n\n";
 		
-		s += "Max Prediction " + getLocalModel().getMaxProposition(this) + "\n";
-		s += "Min Prediction " + getLocalModel().getMinProposition(this) + "\n\n";
+		s += "Max Prediction " + getLocalModel().getMaxProposition() + "\n";
+		s += "Min Prediction " + getLocalModel().getMinProposition() + "\n\n";
 		
 		s += "ASKED REQUEST " + waitingRequests.size() + "\n";
 		for(EndogenousRequest rqt : waitingRequests) {
@@ -2076,7 +2066,7 @@ public class Context extends AmoebaAgent {
 	}
 
 	public double getActionProposal() {
-		return localModel.getProposition(this);
+		return localModel.getProposition();
 	}
 
 	public double getCenterByPercept(Percept pct) {
@@ -2133,7 +2123,7 @@ public class Context extends AmoebaAgent {
 	 */
 	public void setLocalModel(LocalModel localModel) {
 		this.localModel = localModel;
-		this.localModel.context = this;
+		this.localModel.setContext(this);
 	}
 	
 	
diff --git a/AMOEBAonAMAK/src/agents/context/localModel/LocalModel.java b/AMOEBAonAMAK/src/agents/context/localModel/LocalModel.java
index bb2bec7d..91d1f1da 100644
--- a/AMOEBAonAMAK/src/agents/context/localModel/LocalModel.java
+++ b/AMOEBAonAMAK/src/agents/context/localModel/LocalModel.java
@@ -5,53 +5,106 @@ import java.util.HashMap;
 
 import agents.context.Context;
 import agents.context.Experiment;
-import agents.percept.Percept;
 
 /**
- * The abstract class of all agents in charge of the generation of the output
- * from Context Agent. For the sake of simplicity, it's not scheduled as agent
- * like other of the system.
+ * A LocalModel is used by a Context to store information and generate prediction.
  */
-public abstract class LocalModel {
-
-	public Context context;
+public interface LocalModel {
 
 	/**
-	 * Instantiates a new local model agent.
+	 * Sets the context that use the LocalModel
+	 * @param context
 	 */
-	public LocalModel(Context associatedContext) {
-		context = associatedContext;
-	}
-
+	public void setContext(Context context);
+	
+	/**
+	 * gets the context that use the LocalModel
+	 * @return
+	 */
+	public Context getContext();
+	
 	/**
 	 * Gets the proposition.
 	 *
-	 * @param context the context
 	 * @return the proposition
 	 */
-	public abstract double getProposition(Context context);
-	public abstract double getProposition(Experiment experiment);
-	public abstract double getMaxProposition(Context context);
-	public abstract HashMap<String, Double> getMax(Context context);
-	public abstract double getMinProposition(Context context);
+	public double getProposition();
 	
-
+	/**
+	 * Gets the proposition with the highest value possible
+	 * @return
+	 */
+	public double getMaxProposition();
+	
+	/**
+	 * Return the point (percept value) that produce the max proposition
+	 * @return a HashMap with percept names as key, and their corresponding value. The oracle is the max proposition
+	 * @see LocalModel#getMaxProposition(Context)  
+	 */
+	public HashMap<String, Double> getMax();
 	
-	public abstract double getProposition(ArrayList<Experiment> experimentsList, Experiment experiment);
+	/**
+	 * Gets the proposition with the lowest value possible
+	 * @return
+	 */
+	public double getMinProposition();
 
-	public abstract String getCoefsFormula();
-	
-	public abstract void updateModelWithExperiments(ArrayList<Experiment> experimentsList);
-	public abstract void updateModelWithExperimentAndWeight(Experiment newExperiment, double weight, int numberOfPointsForRegression);
-	public abstract void updateModel(Experiment newExperiment, double weight, int numberOfPointsForRegression);
-	public abstract String coefsToString();
-	public abstract double distance(Experiment experiment);
-	public abstract ArrayList<Experiment> getFirstExperiments();
-	public abstract void setFirstExperiments( ArrayList<Experiment> frstExp);
-	public abstract boolean finishedFirstExperiments();
-	
-	public abstract Double[] getCoef();
-	public abstract void setCoef(Double[] coef);
+	/**
+	 * Gets the formula of the model
+	 * @return
+	 */
+	public String getCoefsFormula();
+	
+	/**
+	 * Update the model with a new experiment.
+	 * @param newExperiment
+	 * @param weight the weight of the new experiment in the compute of the model
+	 */
+	public void updateModel(Experiment newExperiment, double weight);
+	
+	public String coefsToString();
+	
+	/**
+	 * The distance between an experiment and the model.
+	 * @param experiment
+	 * @return
+	 */
+	public double distance(Experiment experiment);
+	
+	/**
+	 * Gets the experiments used to properly initialize the model.
+	 * @return
+	 */
+	public ArrayList<Experiment> getFirstExperiments();
+	
+	/**
+	 * Sets the experiments used to properly initialize the model.
+	 * This may not trigger an update of the model.
+	 * @param frstExp
+	 */
+	public void setFirstExperiments( ArrayList<Experiment> frstExp);
+	
+	/**
+	 * Tells if the model has enough experiments to produce a good prediction.
+	 * For example, a regression need a number of experiments equals or superior to the number of dimension.
+	 * @return
+	 */
+	public boolean finishedFirstExperiments();
+	
+	/**
+	 * Gets coefficients of the model
+	 * @return
+	 */
+	public Double[] getCoef();
+	
+	/**
+	 * Sets coefficients of the model
+	 * @return
+	 */
+	public void setCoef(Double[] coef);
 
-	public abstract TypeLocalModel getType();
+	/**
+	 * Gets the {@link TypeLocalModel} corresponding to this LocalModel
+	 */
+	public TypeLocalModel getType();
 }
diff --git a/AMOEBAonAMAK/src/agents/context/localModel/LocalModelMillerRegression.java b/AMOEBAonAMAK/src/agents/context/localModel/LocalModelMillerRegression.java
index a27ec497..24c73fc0 100644
--- a/AMOEBAonAMAK/src/agents/context/localModel/LocalModelMillerRegression.java
+++ b/AMOEBAonAMAK/src/agents/context/localModel/LocalModelMillerRegression.java
@@ -15,7 +15,9 @@ import utils.TRACE_LEVEL;
 /**
  * The Class LocalModelMillerRegression.
  */
-public class LocalModelMillerRegression extends LocalModel{
+public class LocalModelMillerRegression implements LocalModel{
+	
+	private Context context;
 	
 	/** The n parameters. */
 	private int nParameters;
@@ -35,7 +37,7 @@ public class LocalModelMillerRegression extends LocalModel{
 	 * @param world the world
 	 */
 	public LocalModelMillerRegression(Context associatedContext) {
-		super(associatedContext);
+		context = associatedContext;
 		ArrayList<Percept> var = associatedContext.getAmas().getPercepts();
 		this.nParameters = var.size();
 		regression = new Regression(nParameters,true);
@@ -43,7 +45,7 @@ public class LocalModelMillerRegression extends LocalModel{
 	}
 	
 	public LocalModelMillerRegression(Context associatedContext, Double[] coefsCopy, List<Experiment> fstExperiments) {
-		super(associatedContext);
+		context = associatedContext;
 		ArrayList<Percept> var = associatedContext.getAmas().getPercepts();
 		this.nParameters = var.size();
 		regression = new Regression(nParameters,true);
@@ -51,6 +53,16 @@ public class LocalModelMillerRegression extends LocalModel{
 		firstExperiments = new ArrayList<Experiment>(fstExperiments);
 	}
 	
+	@Override
+	public void setContext(Context context) {
+		this.context = context;
+	}
+	
+	@Override
+	public Context getContext() {
+		return context;
+	}
+	
 	/**
 	 * Sets the coef.
 	 *
@@ -71,7 +83,8 @@ public class LocalModelMillerRegression extends LocalModel{
 		return coefs;
 	}
 
-	public double getProposition(Context context) {
+	@Override
+	public double getProposition() {
 			
 		ArrayList<Percept> percepts = context.getAmas().getPercepts();
 		
@@ -93,11 +106,8 @@ public class LocalModelMillerRegression extends LocalModel{
 	
 	
 	
-	public double getProposition(Context context, double[] situation) {
-		
-		ArrayList<Percept> percepts = context.getAmas().getPercepts();
+	private double getProposition(Context context, double[] situation) {
 		
-			
 		double result = coefs[0];
 
 		if (coefs[0] == Double.NaN) System.exit(0);
@@ -112,7 +122,8 @@ public class LocalModelMillerRegression extends LocalModel{
 		return result;
 	}
 	
-	public double getMaxProposition(Context context) {
+	@Override
+	public double getMaxProposition() {
 		
 		ArrayList<Percept> percepts = context.getAmas().getPercepts();			
 		double result = coefs[0];
@@ -133,7 +144,8 @@ public class LocalModelMillerRegression extends LocalModel{
 		return result;
 	}
 	
-	public HashMap<String, Double> getMax(Context context){
+	@Override
+	public HashMap<String, Double> getMax(){
 		ArrayList<Percept> percepts = context.getAmas().getPercepts();
 		
 		HashMap<String, Double> result = new HashMap<String, Double>();
@@ -162,7 +174,8 @@ public class LocalModelMillerRegression extends LocalModel{
 		return result;
 	}
 	
-	public double getMinProposition(Context context) {
+	@Override
+	public double getMinProposition() {
 		
 		ArrayList<Percept> percepts = context.getAmas().getPercepts();			
 		double result = coefs[0];
@@ -183,31 +196,6 @@ public class LocalModelMillerRegression extends LocalModel{
 		return result;
 	}
 	
-	public double getProposition(ArrayList<Experiment> experimentsList, Experiment experiment) {
-		
-
-		
-		if (experimentsList.size() == 1) {
-			return experimentsList.get(0).getOracleProposition();
-		}
-		else {
-			double result = coefs[0];
-
-			if (coefs[0] == Double.NaN) System.exit(0);
-			
-			for (int i = 1 ; i < coefs.length ; i++) {
-				
-				if (Double.isNaN(coefs[i])) coefs[i] = 0.0;
-				result += coefs[i] * experiment.getValuesAsArray()[i-1];
-
-			}
-		
-			return result;
-		}
-			
-		
-	}
-	
 	public double getProposition(Experiment experiment) {
 		
 		if (coefs[0] == Double.NaN) System.exit(0);
@@ -224,6 +212,7 @@ public class LocalModelMillerRegression extends LocalModel{
 			
 	}
 	
+	@Override
 	public String getCoefsFormula() {
 		String result = "" +coefs[0];
 	//	//System.out.println("Result 0" + " : " + result);
@@ -239,47 +228,8 @@ public class LocalModelMillerRegression extends LocalModel{
 		return result;
 
 }
-	
 	@Override
-	public void updateModelWithExperiments(ArrayList<Experiment> experimentsList) {
-		
-		regression = new Regression(nParameters,true);
-	
-		for (Experiment exp : experimentsList) {
-			
-			regression.addObservation(exp.getValuesAsArray(), exp.getOracleProposition());
-			
-	
-		}
-		
-			
-		
-		while (regression.getN() < experimentsList.get(0).getValuesAsLinkedHashMap().size() + 2) { //TODO : to improve
-			
-			regression.addObservation(experimentsList.get(0).getValuesAsArray(), experimentsList.get(0).getOracleProposition());
-			
-			System.out.println("Observations " + regression.getN());
-			
-			System.out.println(experimentsList.get(0).getValuesAsLinkedHashMap().toString());
-			for (int i = 0 ; i < experimentsList.get(0).getValuesAsArray().length ; i++ ) {
-				System.out.print(experimentsList.get(0).getValuesAsArray()[i] + "   " );
-			}
-			System.out.println(experimentsList.get(0).getOracleProposition() + "   " );
-		}
-		
-
-		
-		double[] coef = regression.regress().getParameterEstimates();
-		coefs = new Double[coef.length];
-		for(int i = 0; i < coef.length; i++) {
-			coefs[i] = coef[i];
-		}
-		
-		
-	}
-	
-	
-	public void updateModel(Experiment newExperiment, double weight, int numberOfPointsForRegression) {
+	public void updateModel(Experiment newExperiment, double weight) {
 		context.getAmas().getEnvironment().trace(TRACE_LEVEL.INFORM, new ArrayList<String>(Arrays.asList(context.getName(),"NEW POINT REGRESSION", "FIRST POINTS :", ""+firstExperiments.size(), "OLD MODEL :", coefsToString()))); 
 		
 		if(firstExperiments.size()< (nParameters + 2)) {
@@ -287,7 +237,7 @@ public class LocalModelMillerRegression extends LocalModel{
 			updateModel();
 			
 		}else {
-			updateModelWithExperimentAndWeight(newExperiment, weight, numberOfPointsForRegression);
+			updateModelWithExperimentAndWeight(newExperiment, weight, context.getAmas().data.numberOfPointsForRegression);
 		}
 		
 		context.getAmas().addSpatiallyAlteredContextForUnityUI(context);
@@ -490,12 +440,8 @@ public class LocalModelMillerRegression extends LocalModel{
 		
 		return new Pair<double[][], double[]>(artificalExperiments, artificalResults);
 	}
-
-	
-	
-
-	
 	
+	@Override
 	public double distance(Experiment experiment) {
 		
 		if (coefs[0] == Double.NaN) System.exit(0);
@@ -521,14 +467,17 @@ public class LocalModelMillerRegression extends LocalModel{
 			
 	}
 	
+	@Override
 	public ArrayList<Experiment> getFirstExperiments() {
 		return firstExperiments;
 	}
 	
+	@Override
 	public void setFirstExperiments( ArrayList<Experiment> frstExp) {
 		firstExperiments = frstExp;
 	}
 	
+	@Override
 	public String coefsToString() {
 		String coefsString = "";
 		if(coefs != null) {
@@ -539,6 +488,7 @@ public class LocalModelMillerRegression extends LocalModel{
 		return coefsString;
 	}
 	
+	@Override
 	public boolean finishedFirstExperiments() {
 		return firstExperiments.size()>= (nParameters + 2);
 	}
diff --git a/AMOEBAonAMAK/src/agents/head/Head.java b/AMOEBAonAMAK/src/agents/head/Head.java
index c3070c57..390b1281 100644
--- a/AMOEBAonAMAK/src/agents/head/Head.java
+++ b/AMOEBAonAMAK/src/agents/head/Head.java
@@ -1111,15 +1111,13 @@ public class Head extends AmoebaAgent {
 			getEnvironment().trace(TRACE_LEVEL.DEBUG, new ArrayList<String>(Arrays.asList("MODEL DISTANCE", activatedContext.getName(),
 					"" + activatedContext.getLocalModel().distance(activatedContext.getCurrentExperiment()))));
 			if (!activatedContext.getLocalModel().finishedFirstExperiments()) {
-				activatedContext.getLocalModel().updateModel(activatedContext.getCurrentExperiment(), getAmas().data.learningSpeed,
-						getAmas().data.numberOfPointsForRegression);
+				activatedContext.getLocalModel().updateModel(activatedContext.getCurrentExperiment(), getAmas().data.learningSpeed);
 				getAmas().data.contextNotFinished = true;
 			}
 
 			else if (currentDistanceToOraclePrediction < getAverageRegressionPerformanceIndicator()) {
 			//else if (currentDistanceToOraclePrediction < regressionPerformance.getPerformanceIndicator()) {
-				activatedContext.getLocalModel().updateModel(activatedContext.getCurrentExperiment(), getAmas().data.learningSpeed,
-						getAmas().data.numberOfPointsForRegression);
+				activatedContext.getLocalModel().updateModel(activatedContext.getCurrentExperiment(), getAmas().data.learningSpeed);
 
 			}
 
@@ -1181,7 +1179,7 @@ public class Head extends AmoebaAgent {
 				getEnvironment().trace(TRACE_LEVEL.DEBUG, new ArrayList<String>(Arrays.asList("MODEL DISTANCE",
 						activatedContexts.get(0).getName(), "" + distanceToOracleForActivatedContext)));
 				activatedContexts.get(0).getLocalModel().updateModel(activatedContexts.get(0).getCurrentExperiment(),
-						getAmas().data.learningSpeed, getAmas().data.numberOfPointsForRegression);
+						getAmas().data.learningSpeed);
 
 			}
 		} else {
@@ -1189,7 +1187,7 @@ public class Head extends AmoebaAgent {
 					Arrays.asList("MODEL DISTANCE", activatedContexts.get(0).getName(), "" + activatedContexts.get(0)
 							.getLocalModel().distance(activatedContexts.get(0).getCurrentExperiment()))));
 			activatedContexts.get(0).getLocalModel().updateModel(activatedContexts.get(0).getCurrentExperiment(),
-					getAmas().data.learningSpeed, getAmas().data.numberOfPointsForRegression);
+					getAmas().data.learningSpeed);
 		}
 
 		// world.trace(new ArrayList<String>(Arrays.asList("MODEL
@@ -1284,8 +1282,7 @@ public class Head extends AmoebaAgent {
 
 		}
 
-		closestContextToOracle.getLocalModel().updateModel(closestContextToOracle.getCurrentExperiment(), getAmas().data.learningSpeed,
-				getAmas().data.numberOfPointsForRegression);
+		closestContextToOracle.getLocalModel().updateModel(closestContextToOracle.getCurrentExperiment(), getAmas().data.learningSpeed);
 
 		activatedContextsCopyForUpdates = new ArrayList<Context>(activatedContexts);
 		for (Context activatedContext : activatedContexts) {
diff --git a/AMOEBAonAMAK/src/kernel/AMOEBA.java b/AMOEBAonAMAK/src/kernel/AMOEBA.java
index 4da9804e..ef405f38 100644
--- a/AMOEBAonAMAK/src/kernel/AMOEBA.java
+++ b/AMOEBAonAMAK/src/kernel/AMOEBA.java
@@ -431,7 +431,7 @@ public class AMOEBA extends Amas<World> implements IAMOEBA {
 		
 		ArrayList<HashMap<String, Double>> sol = new ArrayList<>();
 		for(Context c : pac) {
-			sol.add(c.getLocalModel().getMax(c));
+			sol.add(c.getLocalModel().getMax());
 		}
 		HashMap<String, Double> max = new HashMap<>();
 
-- 
GitLab