using System.Collections.ObjectModel;
using System.Globalization;
using System.Security.AccessControl;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Documents;
using System.Windows.Media;
using System.Xml.Serialization;
using Evaluation.ViewModel;
using HeuristicLab.Algorithms.Bandits;
using HeuristicLab.Algorithms.Bandits.BanditPolicies;
using HeuristicLab.Algorithms.GeneticProgramming;
using HeuristicLab.Algorithms.GrammaticalOptimization;
using HeuristicLab.Algorithms.MonteCarloTreeSearch;
using HeuristicLab.Algorithms.MonteCarloTreeSearch.Simulation;
using HeuristicLab.Problems.GrammaticalOptimization;
using Microsoft.Research.DynamicDataDisplay;
using Microsoft.Research.DynamicDataDisplay.DataSources;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Threading;
using Microsoft.Win32;
using WpfTestSvgSample;
namespace Evaluation
{
///
/// Interaction logic for MainWindow.xaml
///
public partial class MainWindow : Window
{
private EvaluationViewModel vm;
private DrawingPage treeDrawingPage;
public MainWindow()
{
InitializeComponent();
CenterWindowOnScreen();
this.DataContext = vm = new EvaluationViewModel();
vm.MaxLen = 17;
vm.MaxIterations = 300000;
vm.NrRuns = 20;
vm.MaxThreads = 10;
}
private void CenterWindowOnScreen()
{
double screenWidth = System.Windows.SystemParameters.PrimaryScreenWidth;
double screenHeight = System.Windows.SystemParameters.PrimaryScreenHeight;
double windowWidth = this.Width;
double windowHeight = this.Height;
this.Left = (screenWidth / 2) - (windowWidth / 2);
this.Top = (screenHeight / 2) - (windowHeight / 2);
}
private void DrawQualityChart(Run run)
{
List solutions = new List(run.FoundSolutions);
if (run.BestSolutionFoundAt < run.Evaluations)
{
solutions.Add(new FoundSolution(run.EndTime, run.Evaluations, run.BestQuality, run.BestSolution));
}
// insert point between two solutions, with the result that there is no direct line from solutionpoint to solutionpoint
for (int i = 1; i < solutions.Count; i++)
{
FoundSolution previousSolution = solutions[i - 1];
FoundSolution currentSolution = solutions[i];
// insert point
solutions.Insert(i, new FoundSolution(currentSolution.Time, currentSolution.Iteration, previousSolution.Quality, "placeholder"));
i++;
}
var ds = new EnumerableDataSource(solutions);
ds.SetXMapping(x => x.Iteration);
ds.SetYMapping(y => y.Quality / run.BestKnownQuality);
LineGraph graph = new LineGraph(ds);
graph.StrokeThickness = 2;
graph.AddToPlotter(QualityChartPlotter);
}
private void DrawSelectionChart(Run run)
{
// quality line
List solutions = new List(run.FoundSolutions);
if (run.BestSolutionFoundAt < run.Evaluations)
{
solutions.Add(new FoundSolution(run.EndTime, run.Evaluations, run.BestQuality, run.BestSolution));
}
// insert point between two solutions, with the result that there is no direct line from solutionpoint to solutionpoint
for (int i = 1; i < solutions.Count; i++)
{
FoundSolution previousSolution = solutions[i - 1];
FoundSolution currentSolution = solutions[i];
// insert point
solutions.Insert(i, new FoundSolution(currentSolution.Time, currentSolution.Iteration, previousSolution.Quality, "placeholder"));
i++;
}
var ds = new EnumerableDataSource(solutions);
ds.SetXMapping(x => x.Iteration);
ds.SetYMapping(y => y.Quality / run.BestKnownQuality);
LineGraph graph = new LineGraph(ds);
graph.StrokeThickness = 2;
graph.AddToPlotter(SelectionChartPlotter);
// selection indicator line
List selectionIndicators = new List(run.SelectionIndicators);
var dssi = new EnumerableDataSource(selectionIndicators);
dssi.SetXMapping(x => x.Evaluation);
dssi.SetYMapping(y => y.Indicator);
graph = new LineGraph(dssi);
graph.StrokeThickness = 2;
graph.Stroke = Brushes.Red;
graph.AddToPlotter(SelectionChartPlotter);
}
private void DrawTreeChart(Run run)
{
if (!string.IsNullOrEmpty(run.SvgFile))
{
treeDrawingPage.LoadDocument(run.SvgFile);
}
}
private void DoRun(Object threadContext)
{
Run run = (Run)threadContext;
run.RunState = RunState.Running;
run.StartTime = DateTime.Now;
run.Solver.Run(run.MaxIterations);
run.EndTime = DateTime.Now;
run.RunState = RunState.Analyzing;
if (run.FoundSolutions.Count > 0)
{
if (run.Solver is MonteCarloTreeSearch)
{
MonteCarloTreeSearch mctsSolver = (MonteCarloTreeSearch)run.Solver;
run.TreeInfos = mctsSolver.GetTreeInfos();
// svg-tree ->
//byte[] output = mctsSolver.GenerateSvg();
//if (output != null && output.Length > 0)
//{
// run.SvgFile = string.Format("MCTS_SVG_#{0}_{1}.svg", run.RunNumber, DateTime.Now.Ticks);
// File.WriteAllBytes(run.SvgFile, output);
//}
mctsSolver.FreeAll();
}
}
run.RunState = RunState.Finished;
lock (vm.CompletedRuns)
{
int completed = 0;
foreach (Run r in vm.Runs)
{
if (r.RunState == RunState.Finished)
{
completed++;
}
}
vm.CompletedRuns = string.Format("{0}/{1}", completed, vm.Runs.Count);
if (completed == vm.NrRuns)
{
Dispatcher.Invoke(AllRunsFinished);
}
}
}
private void AllRunsFinished()
{
ButtonRun.IsEnabled = true;
TextBoxMaxIterations.IsEnabled = true;
TextBoxMaxLen.IsEnabled = true;
TextBoxRuns.IsEnabled = true;
TextBoxMaxThreads.IsEnabled = true;
}
private void StartRuns()
{
vm.CompletedRuns = string.Format("0/{0}", vm.NrRuns);
Type algorithmType = vm.SelectedAlgorithm;
ISymbolicExpressionTreeProblem problem = vm.SelectedProblem;
Type policy = vm.SelectedPolicy;
IBanditPolicy policyInstance = null;
if (policy == typeof(UCTPolicy))
{
policyInstance = new UCTPolicy(vm.PolicyParameter);
}
else if (policy == typeof(ThresholdAscentPolicy))
{
policyInstance = new ThresholdAscentPolicy();
}
else if (policy == typeof(BoltzmannExplorationPolicy))
{
policyInstance = new BoltzmannExplorationPolicy(2);
}
else if (policy == typeof(EpsGreedyPolicy))
{
policyInstance = new EpsGreedyPolicy(vm.PolicyParameter);
}
else
{
policyInstance = (IBanditPolicy)Activator.CreateInstance(policy);
}
for (int i = 0; i < vm.NrRuns; i++)
{
ISolver solver = null;
Random random = new Random(Guid.NewGuid().GetHashCode());
if (algorithmType == typeof(MonteCarloTreeSearch_PruneLeaves))
{
solver = new MonteCarloTreeSearch_PruneLeaves(problem, vm.MaxLen, random, policyInstance, new RandomSimulation(problem, random, vm.MaxLen));
}
else if (algorithmType == typeof(MonteCarloTreeSearch))
{
solver = new MonteCarloTreeSearch(problem, vm.MaxLen, random, policyInstance, new RandomSimulation(problem, random, vm.MaxLen));
}
else if (algorithmType == typeof(SequentialSearch))
{
solver = new SequentialSearch(problem, vm.MaxLen, random, 0,
new HeuristicLab.Algorithms.Bandits.GrammarPolicies.GenericGrammarPolicy(problem, policyInstance));
}
else if (algorithmType == typeof(RandomSearch))
{
solver = new RandomSearch(problem, random, vm.MaxLen);
}
else if (algorithmType == typeof(StandardGP))
{
solver = new StandardGP(problem, random);
}
else if (algorithmType == typeof(OffspringSelectionGP))
{
solver = new OffspringSelectionGP(problem, random);
}
Run run = new Run(problem, policyInstance, solver, i + 1, vm.MaxIterations, vm.MaxLen);
vm.Runs.Add(run);
}
Task.Run(() =>
Parallel.For(0, vm.NrRuns, new ParallelOptions { MaxDegreeOfParallelism = vm.MaxThreads },
i => DoRun(vm.Runs[i])));
}
private void ClearQualityChart()
{
QualityChartPlotter.Children.RemoveAll();
}
private void ClearComparisonChart()
{
ComparisonChartPlotter.Children.RemoveAll();
}
private void ClearSelectionChart()
{
SelectionChartPlotter.Children.RemoveAll();
}
private void ButtonRun_OnClick(object sender, RoutedEventArgs e)
{
ClearQualityChart();
ClearComparisonChart();
ClearSelectionChart();
vm.Runs.Clear();
vm.SelectedRun = null;
ButtonRun.IsEnabled = false;
TextBoxMaxIterations.IsEnabled = false;
TextBoxMaxLen.IsEnabled = false;
TextBoxRuns.IsEnabled = false;
StartRuns();
}
private void ButtonPause_OnClick(object sender, RoutedEventArgs e)
{
//if (vm.SelectedAlgorithm == typeof(MonteCarloTreeSearch))
//{
// MonteCarloTreeSearch mcts = (MonteCarloTreeSearch)solver;
// mcts.PauseContinue();
// if (mcts.IsPaused)
// {
// ButtonPause.Content = "Continue";
// }
// else
// {
// ButtonPause.Content = "Pause";
// }
//}
}
private void ButtonStop_OnClick(object sender, RoutedEventArgs e)
{
//worker.CancelAsync();
}
private void ComboBoxAlgorithms_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (vm.SelectedAlgorithm == typeof(MonteCarloTreeSearch) || vm.SelectedAlgorithm == typeof(MonteCarloTreeSearch_PruneLeaves))
{
ComboBoxPolicies.IsEnabled = true;
TabItemTree.IsEnabled = true;
}
else if (vm.SelectedAlgorithm == typeof(SequentialSearch))
{
ComboBoxPolicies.IsEnabled = true;
TabItemTree.IsEnabled = false;
}
else
{
ComboBoxPolicies.IsEnabled = false;
TabItemTree.IsEnabled = false;
}
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
treeDrawingPage = treeDrawing.Content as DrawingPage;
}
private void ListBoxRuns_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (vm.SelectedRun != null)
{
vm.SelectedRun.Solver.FoundNewBestSolution -= SelectedRun_FoundNewBestSolution;
}
if (ListBoxRuns.SelectedItem != null)
{
vm.SelectedRun = (Run)ListBoxRuns.SelectedItem;
vm.SelectedRun.Solver.FoundNewBestSolution += SelectedRun_FoundNewBestSolution;
ClearQualityChart();
DrawQualityChart(vm.SelectedRun);
if (vm.SelectedRun.RunState == RunState.Finished)
{
ClearSelectionChart();
DrawSelectionChart(vm.SelectedRun);
}
//DrawTreeChart(vm.SelectedRun);
}
else
{
vm.SelectedRun = null;
}
}
void SelectedRun_FoundNewBestSolution(string arg1, double arg2)
{
Dispatcher.BeginInvoke(new Action(() =>
{
ClearQualityChart();
DrawQualityChart(vm.SelectedRun);
}));
}
public void SaveToFile()
{
SaveFileDialog dlg = new SaveFileDialog();
dlg.FileName = "runs"; // Default file name
dlg.DefaultExt = ".xml"; // Default file extension
// Show save file dialog box
Nullable result = dlg.ShowDialog();
// Process save file dialog box results
if (result == true)
{
// Save document
string filename = dlg.FileName;
XmlSerializer serializer = new XmlSerializer(typeof(ObservableCollection));
using (TextWriter writer = new StreamWriter(filename))
{
serializer.Serialize(writer, vm.Runs);
}
}
}
public void LoadFromFile()
{
OpenFileDialog dlg = new OpenFileDialog();
// Show save file dialog box
Nullable result = dlg.ShowDialog();
// Process save file dialog box results
if (result == true)
{
// Load document
string filename = dlg.FileName;
XmlSerializer deserializer = new XmlSerializer(typeof(ObservableCollection));
using (TextReader reader = new StreamReader(filename))
{
object obj = deserializer.Deserialize(reader);
vm.Runs = (ObservableCollection)obj;
}
}
}
private void LoadButton_OnClick(object sender, RoutedEventArgs e)
{
LoadFromFile();
}
private void SaveButton_OnClick(object sender, RoutedEventArgs e)
{
SaveToFile();
}
private void MenuItemCopyToClipboard_OnClick(object sender, RoutedEventArgs e)
{
StringBuilder tableExport = new StringBuilder();
tableExport.Append(
"Run\tMaxIterations\tEvaluations\tBestKnownQuality\tQuality\tQuality %\tFoundAt\tTotalTime\tSolutionTime\tEvaluationsPerSecond\tSolution");
if (ListViewRuns.Items.Count > 0 && ((Run)ListViewRuns.Items[0]).TreeInfos != null)
{
tableExport.Append("\tTotalNodes\tUnexpandedNodes\tExpandedNodes\tLeaveNodes\tDeepestLevel");
}
tableExport.AppendLine();
for (int i = 0; i < ListViewRuns.Items.Count; i++)
{
Run run = (Run)ListViewRuns.Items[i];
tableExport.Append(string.Format("{0}\t{1}\t{2}\t{3}\t{4}\t{5}\t{6}\t{7}\t{8}\t{9}\t{10}", run.RunNumber,
run.MaxIterations, run.Evaluations, run.BestKnownQuality, run.BestQuality,
run.BestQuality / run.BestKnownQuality, run.BestSolutionFoundAt, run.TotalTime, run.BestSolutionTime,
run.EvaluationsPerSecond, run.BestSolution));
if (run.TreeInfos != null)
{
tableExport.Append(string.Format("\t{0}\t{1}\t{2}\t{3}\t{4}", run.TreeInfos.TotalNodes,
run.TreeInfos.UnexpandedNodes, run.TreeInfos.ExpandedNodes, run.TreeInfos.LeaveNodes,
run.TreeInfos.DeepestLevel));
}
tableExport.AppendLine();
}
Clipboard.SetData(DataFormats.Text, tableExport.ToString());
}
private void ComboBoxPolicies_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (vm.SelectedPolicy == typeof(EpsGreedyPolicy))
{
TextBoxEpsylon.Visibility = Visibility.Visible;
vm.PolicyParameter = 0.5;
TextBlockEpsylon.Text = "Epsilon";
TextBlockEpsylon.Visibility = Visibility.Visible;
}
else if (vm.SelectedPolicy == typeof(UCTPolicy))
{
TextBoxEpsylon.Visibility = Visibility.Visible;
vm.PolicyParameter = Math.Sqrt(2);
TextBlockEpsylon.Text = "c";
TextBlockEpsylon.Visibility = Visibility.Visible;
}
else
{
TextBoxEpsylon.Visibility = Visibility.Hidden;
TextBlockEpsylon.Visibility = Visibility.Hidden;
}
}
private void Selector_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (vm.SelectedRun != null && vm.SelectedRun.RunState == RunState.Finished)
{
if (ChartSelector.SelectedItem == TabSelectionIndicator)
{
ClearSelectionChart();
DrawSelectionChart(vm.SelectedRun);
}
else if (ChartSelector.SelectedItem == TabQualityChart)
{
ClearQualityChart();
DrawQualityChart(vm.SelectedRun);
}
else if (ChartSelector.SelectedItem == TabItemTree)
{
DrawTreeChart(vm.SelectedRun);
}
}
}
}
}