Optimization Plugin Complete
The following code corresponds to the full optimization plugin example written based on the scaffolding from the Optimization Plugin Template page.
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
namespace OptimPluginSample
{
public class PluginSample
{
private double _incrementValue = 0;
private int _iterationNumber = 0;
private IDictionary<string, string> _variableNames = new Dictionary<string, string>();
private IDictionary<string, double> _variableValues = new Dictionary<string, double>();
private IDictionary<string, string> _targetNames = new Dictionary<string, string>();
private IDictionary<string, double> _targetValues = new Dictionary<string, double>();
private IList<IDictionary<string,double>> _iterationResults = new List<IDictionary<string,double>>();
private string _simulationName = string.Empty;
private string _reportPath = string.Empty;
public PluginSample(string arguments)
{
// splint the list of parameters
var argumentsList= arguments.Split(',');
// check that the argument list represents the number of arguments that we need
if(argumentsList.Length != 2)
{
throw new ArgumentException("We should only have two arguments");
}
// try to read the first argument as the increment value
if (double.TryParse(argumentsList[0], out var incrementValue))
{
_incrementValue = incrementValue;
}
else
{
throw new ArgumentException("first argument cannot be read as a double for increment value");
}
// try the read the second argument as the iteration number
if (int.TryParse(argumentsList[1], out var iterationNumber))
{
_iterationNumber = iterationNumber;
}
else
{
throw new ArgumentException("second argument cannot be read as a int for iteration number");
}
}
/// <summary>
/// Callback called upon starting the optimization loop (optional)
/// </summary>
public void StartRun()
{
}
/// <summary>
/// Callback called upon starting a new iteration in the optimization loop
/// </summary>
/// <param name="iteration">the iteration that is starting</param>
/// <returns> whether we should continue on this iteration or not</returns>
public bool StartIteration(int iteration)
{
if(iteration >= _iterationNumber)
{
WriteReport();
return false;
}
var keys = _variableValues.Keys.ToArray();
foreach (var key in keys)
{
_variableValues[key] = _variableValues[key] + _incrementValue;
}
return true; // we want to continue looping on this iteration
}
/// <summary>
/// Callback called upon ending an iteration (optional)
/// </summary>
/// <param name="iteration">the iteration that is ending</param>
public void EndIteration(int iteration)
{
_iterationResults.Add(_targetValues.ToDictionary(entry => entry.Key, entry => entry.Value));
}
/// <summary>
/// Called to return the new value to set for this parameter
/// </summary>
public double GetNewValue(string parameterId)
{
return _variableValues[parameterId];
}
/// <summary>
/// Called to register a new variable as input
/// </summary>
public void AddVariable(string parameterId, string parameterUserName, double startingValue, double min, double max)
{
_variableNames.Add(parameterId, parameterUserName);
_variableValues.Add(parameterId, startingValue);
}
/// <summary>
/// Called to register a new target as output (optional)
/// </summary>
public void AddTarget(string parameterId, string parameterUserName, double startingValue, double targetValue, double weight)
{
_targetNames.Add(parameterId, parameterUserName);
_targetValues.Add(parameterId, startingValue);
}
/// <summary>
/// Callback called after the simulation's update to update the values of the targets
/// </summary>
/// <param name="parameterId"></param>
/// <param name="value"></param>
public void SetMeasures(string parameterId, double value)
{
_targetValues[parameterId] = value;
}
/// <summary>
/// Callback called to inform the simulation details
/// </summary>
/// <param name="simulationName"></param>
/// <param name="reportPath"></param>
public void SetSimulationInfos(string simulationName, string reportPath)
{
_reportPath = reportPath ?? string.Empty;
_simulationName= simulationName ?? string.Empty;
}
private void WriteReport()
{
var stringBuilder = new StringBuilder();
stringBuilder.AppendLine("<html><body><table>");
stringBuilder.AppendLine("<tr><th>Iteration Number</th>");
var parameterIdOrder = new string[_targetNames.Count];
var idx = 0;
foreach(var names in _targetNames)
{
stringBuilder.AppendLine($"<th>{names.Value}</th>");
parameterIdOrder[idx] = names.Key;
idx++;
}
stringBuilder.AppendLine("<tr/>");
idx = 0;
foreach (var iterationResult in _iterationResults)
{
stringBuilder.AppendLine("<tr>");
stringBuilder.AppendLine($"<td>{idx}</td>");
foreach(var id in parameterIdOrder)
{
stringBuilder.AppendLine($"<td>{iterationResult[id]}</td>");
}
stringBuilder.AppendLine("<tr/>");
idx++;
}
stringBuilder.AppendLine("</table></body></html>");
File.WriteAllText(_reportPath, stringBuilder.ToString());
}
}
}