public object GridValue(ParSetting p, float proportion) { object temp = p.par.GetValue(p.owner); if (temp is int) { return((int)((int)((float)((int)p.maxValue - (int)p.minValue)) * proportion) + (int)p.minValue); } else if (temp is float) { return((float)(((float)p.maxValue - (float)p.minValue) * proportion) + (float)p.minValue); } else if (temp is bool) { if (proportion <= 0.5f) { return(false); } else { return(true); } } return(null); }
public void Pop() { for (int i = 0; i < values.Count; i++) { ParSetting p = settings[i]; p.par.SetValue(p.owner, values[i]); } }
public object RandomValue(ParSetting p) { object temp = p.par.GetValue(p.owner); if (temp is int) { return(Random.Range((int)p.minValue, ((int)p.maxValue) + 1)); } else if (temp is float) { return(Random.Range((float)p.minValue, (float)p.maxValue)); } else if (temp is bool) { return(Random.Range(0, 2) == 0); } return(null); }
public void SetupTuningUI(MonoBehaviour generator) { this.generator = generator; TunableParameterInputList = new List <TunableParameter>(); //Find all the fields with tunable attributes and add them to the UI foreach (FieldInfo field in generator.GetType().GetFields()) { foreach (Attribute attr in field.GetCustomAttributes(false)) { if (attr is TunableAttribute) { TunableAttribute t = (TunableAttribute)attr; TunableParameter tpi; if (t.MinValue is bool) { GameObject tpp = Instantiate(TunableBoolUIPrefab); tpp.transform.parent = TunableParameterPanel.transform; tpi = tpp.GetComponent <TunableParameterToggleField>(); } else { GameObject tpp = Instantiate(TunableParameterUIPrefab); tpp.transform.parent = TunableParameterPanel.transform; tpi = tpp.GetComponent <TunableParameterInput>(); } tpi.Setup(this); //Set the field's name up tpi.targetParameter = field; tpi.tuneMin = t.MinValue; tpi.tuneMax = t.MaxValue; tpi.SetValue(field.GetValue(generator)); if (t.Name == "") { tpi.label.text = field.Name; } else { tpi.label.text = t.Name; } //Add the TPIs to the corresponding list TunableParameterInputList.Add(tpi); //Also add them to the ERAnalyser as parameter setting objects ParSetting p = new ParSetting(field, generator, t.MinValue, t.MaxValue); tuner.AddParameter(p); } } } MetricReportTexts = new List <Text>(); MetricDelegateList = new List <TargetSetting.MetricDelegate>(); MetricInputFieldList = new List <InputField>(); List <string> metricNames = new List <string>(); foreach (MonoBehaviour b in generator.GetComponents <MonoBehaviour>()) { foreach (MethodInfo method in b.GetType().GetMethods()) { foreach (Attribute attr in method.GetCustomAttributes(false)) { if (attr is Metric) { GameObject metricPanel = Instantiate(TargetMetricPanelUIPrefab); metricPanel.transform.parent = TargetMetricPanel.transform; metricPanel.transform.Find("TargetLabel").GetComponent <Text>().text = "Calculate " + ((Metric)attr).Name; //This line creates a MetricDelegate from the MethodInfo object. //MetricDelegates take a Tile[,] and return a float. //Note that we pass in the MonoBehaviour because it needs an object to invoke the delegate on. MetricDelegateList.Add((TargetSetting.MetricDelegate)Delegate.CreateDelegate(typeof(TargetSetting.MetricDelegate), b, method)); MetricInputFieldList.Add(metricPanel.transform.Find("TargetInput").GetComponent <InputField>()); //We also create a report in the top left GameObject metricReport = Instantiate(MetricReportUIPrefab); metricReport.transform.parent = MetricReportPanel.transform; metricReport.name = "MetricReport" + ((Metric)attr).Name; metricReport.transform.Find("MetricName").GetComponent <Text>().text = "" + ((Metric)attr).Name; MetricReportTexts.Add(metricReport.transform.Find("MetricValue").GetComponent <Text>()); metricNames.Add(method.Name); } } } } if (MetricInputFieldList.Count == 0 || DAN.Instance.AddDefaultMetrics) { LevelAnalyser la = DAN.Instance.analyser; foreach (MethodInfo method in la.GetType().GetMethods()) { foreach (Attribute attr in method.GetCustomAttributes(false)) { if (attr is Metric) { GameObject metricPanel = Instantiate(TargetMetricPanelUIPrefab); metricPanel.transform.parent = TargetMetricPanel.transform; metricPanel.transform.Find("TargetLabel").GetComponent <Text>().text = ((Metric)attr).Name; //This line creates a MetricDelegate from the MethodInfo object. //MetricDelegates take a Tile[,] and return a float. //Note that we pass in the MonoBehaviour because it needs an object to invoke the delegate on. MetricDelegateList.Add((TargetSetting.MetricDelegate)Delegate.CreateDelegate(typeof(TargetSetting.MetricDelegate), la, method)); MetricInputFieldList.Add(metricPanel.transform.Find("TargetInput").GetComponent <InputField>()); //We also create a report in the top left GameObject metricReport = Instantiate(MetricReportUIPrefab); metricReport.transform.parent = MetricReportPanel.transform; metricReport.name = "MetricReport" + ((Metric)attr).Name; metricReport.transform.Find("MetricName").GetComponent <Text>().text = "" + ((Metric)attr).Name; MetricReportTexts.Add(metricReport.transform.Find("MetricValue").GetComponent <Text>()); metricNames.Add(method.Name); } } } } //Update the ERA Buttons with the first two metrics GameObject.Find("MetricName1").GetComponent <InputField>().text = metricNames[0]; GameObject.Find("MetricName2").GetComponent <InputField>().text = metricNames[1]; }
IEnumerator TuneCR(int popsize, int generations, int numberOfRunsPerInstance) { population = new List <ParValue[]>(); float time = Time.realtimeSinceStartup; Debug.Log(Time.realtimeSinceStartup + " - start"); //Initialise the population, using random values between the parameter settings for (int i = 0; i < popsize; i++) { ParValue[] geno = new ParValue[settings.Count]; for (int j = 0; j < settings.Count; j++) { ParSetting p = settings[j]; geno[j] = new ParValue(p.par, RandomValue(p)); } population.Add(geno); } Debug.Log("Population generated."); yield return(0); for (int g = 0; g < generations; g++) { Debug.Log("Generation " + g); Dictionary <ParValue[], float> fitnessDic = new Dictionary <ParValue[], float>(); float max = 0f; float min = 1f; float avg = 0f; float num = 0; foreach (ParValue[] pv in population) { fitnessDic[pv] = Evaluate(pv, numberOfRunsPerInstance); if (fitnessDic[pv] > max) { max = fitnessDic[pv]; } if (fitnessDic[pv] < min) { min = fitnessDic[pv]; } avg += fitnessDic[pv]; num += 1; } //Evaluate the population according to the given targets population.Sort(delegate(ParValue[] p1, ParValue[] p2) { return(-(fitnessDic[p1].CompareTo(fitnessDic[p2]))); }); // population.Sort(delegate(ParValue[] p1, ParValue[] p2) { return -(Evaluate(p1, numberOfRunsPerInstance).CompareTo(Evaluate(p2, numberOfRunsPerInstance))); }); // Debug.Log("Lowest fitness: "+min); // Debug.Log("Average fitness: "+(avg/num)); // Debug.Log("Highest fitness: "+max); yield return(0); //Take the top members and build a new population through recombination List <ParValue[]> newpop = new List <ParValue[]>(); while (newpop.Count < population.Count) { ParValue[] p1 = population[0]; population.RemoveAt(0); ParValue[] p2 = population[0]; population.RemoveAt(0); newpop.Add(p1); newpop.Add(p2); newpop.Add(Crossover(p1, p2)); newpop.Add(Crossover(p1, p2)); ParValue[] geno = new ParValue[settings.Count]; for (int j = 0; j < settings.Count; j++) { ParSetting p = settings[j]; geno[j] = new ParValue(p.par, RandomValue(p)); } newpop.Add(geno); geno = new ParValue[settings.Count]; for (int j = 0; j < settings.Count; j++) { ParSetting p = settings[j]; geno[j] = new ParValue(p.par, RandomValue(p)); } newpop.Add(geno); // newpop.Add(Crossover(p1, p2)); // newpop.Add(Crossover(p1, p2)); } // Debug.Log("New population generated."); GameObject.Find("AutoTuneProgress").GetComponent <UnityEngine.UI.Text>().text = (100 * g / generations) + " percent complete"; // Debug.Log(GameObject.Find("AutoTuneProgress").GetComponent<UnityEngine.UI.Text>().text); yield return(0); //New pop, same as the old pop population = newpop; } //Evaluate the population according to the given targets, one last time population.Sort(delegate(ParValue[] p1, ParValue[] p2) { return(-(Evaluate(p1, numberOfRunsPerInstance).CompareTo(Evaluate(p2, numberOfRunsPerInstance)))); }); GameObject.Find("AutoTuneProgress").GetComponent <UnityEngine.UI.Text>().text = ""; // Debug.Log(Time.realtimeSinceStartup+" - finish"); // Debug.Log("Time taken: "+(Time.realtimeSinceStartup - time)); // Debug.Log("Highest fitness: "+Evaluate(population[0], numberOfRunsPerInstance)); //Apply the parameters ParValue[] pvs = population[0]; for (int i = 0; i < pvs.Length; i++) { settings[i].par.SetValue(settings[i].owner, pvs[i].val); } DAN.Instance.GenerateMap(); OnTuningComplete(); OnTuningComplete = DoNothing; }
public void AddParameter(ParSetting p) { settings.Add(p); }