Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
07/14/15 20:42:55 (9 years ago)
Author:
aballeit
Message:

#2283 GUI updates, Tree-chart, MCTS Version 2 (prune leaves)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/HeuristicLab.Problems.GrammaticalOptimization/HeuristicLab.Algorithms.MonteCarloTreeSearch/MonteCarloTreeSearch.cs

    r12503 r12762  
    11using System;
    22using System.Collections.Generic;
     3using System.Drawing;
    34using System.Linq;
     5using System.Net.Mail;
     6using System.Text;
     7using System.Threading;
     8using GraphVizWrapper;
     9using GraphVizWrapper.Commands;
     10using GraphVizWrapper.Queries;
    411using HeuristicLab.Algorithms.Bandits;
    512using HeuristicLab.Algorithms.GrammaticalOptimization;
     
    2027        private readonly ISimulation simulation;
    2128        private TreeNode rootNode;
    22 
    23         public MonteCarloTreeSearch(IProblem problem, int maxLen, Random random, IBanditPolicy behaviourPolicy, ISimulation simulationPolicy)
     29        private bool isPaused = false;
     30        private object pauseLock = new object();
     31
     32        public MonteCarloTreeSearch(IProblem problem, int maxLen, Random random, IBanditPolicy behaviourPolicy,
     33            ISimulation simulationPolicy)
    2434        {
    2535            this.problem = problem;
     
    3141        }
    3242
    33         public bool StopRequested
    34         {
    35             get;
    36             set;
     43        public bool StopRequested { get; set; }
     44
     45        public bool IsPaused
     46        {
     47            get { return this.isPaused; }
    3748        }
    3849
     
    4253            for (int i = 0; !StopRequested && i < maxIterations; i++)
    4354            {
     55                lock (pauseLock)
     56                {
     57                    if (isPaused)
     58                    {
     59                        Monitor.Wait(pauseLock);
     60                    }
     61                }
    4462                TreeNode currentNode = rootNode;
    4563
     
    5371                string phrase = currentNode.phrase;
    5472
    55                 if (!grammar.IsTerminal(phrase) && phrase.Length <= maxLen)
    56                 {
     73                if (phrase.Length <= maxLen)
     74                {
     75                    // Version 2:
     76                    if (currentNode.children != null && !currentNode.children.Any())
     77                    {
     78                        // already removed all child nodes so remove it too..
     79                        currentNode.parent.children.Remove(currentNode);
     80                        continue;
     81                    }
    5782                    ExpandTreeNode(currentNode);
    58 
    59                     currentNode =
    60                         currentNode.children[behaviourPolicy.SelectAction(random, currentNode.GetChildActionInfos())];
     83                    if (currentNode.children.Any())
     84                    {
     85                        currentNode =
     86                            currentNode.children[behaviourPolicy.SelectAction(random, currentNode.GetChildActionInfos())
     87                                ];
     88                    }
     89                    else
     90                    {
     91                        // Version 2:
     92                        // remove currentNode from tree..
     93                        currentNode.parent.children.Remove(currentNode);
     94                    }
    6195                }
    6296                if (currentNode.phrase.Length <= maxLen)
    6397                {
    64                     double quality = simulation.Simulate(currentNode);
    65                     OnSolutionEvaluated(phrase, quality);
     98                    string simulatedPhrase;
     99                    double quality = simulation.Simulate(currentNode, out simulatedPhrase);
     100                    OnSolutionEvaluated(simulatedPhrase, quality);
    66101
    67102                    Propagate(currentNode, quality);
    68                 }
    69             }
     103
     104                }
     105            }
     106        }
     107
     108        private bool HasNonTerminal(string phrase)
     109        {
     110            foreach (char symbol in phrase)
     111            {
     112                if (grammar.IsNonTerminal(symbol))
     113                {
     114                    return true;
     115                }
     116            }
     117
     118            return false;
    70119        }
    71120
     
    91140                            if (newSequence.Length <= maxLen)
    92141                            {
    93                                 TreeNode childNode = new TreeNode(treeNode, newSequence.ToString(), behaviourPolicy.CreateActionInfo());
     142                                TreeNode childNode = new TreeNode(treeNode, newSequence.ToString(),
     143                                    behaviourPolicy.CreateActionInfo(), treeNode.level + 1);
    94144                                treeNode.children.Add(childNode);
    95145                            }
     
    104154            StopRequested = false;
    105155            bestQuality = 0.0;
    106             rootNode = new TreeNode(null, grammar.SentenceSymbol.ToString(), behaviourPolicy.CreateActionInfo());
     156            rootNode = new TreeNode(null, grammar.SentenceSymbol.ToString(), behaviourPolicy.CreateActionInfo(), 0);
    107157        }
    108158
     
    117167        }
    118168
    119         public void PrintStats()
    120         {
    121             //Console.WriteLine("depth: {0,5} tries: {1,5} best phrase {2,50} bestQ {3:F3}", maxSearchDepth, tries, bestPhrase, bestQuality);
    122 
    123             //// use behaviour strategy to generate the currently prefered sentence
    124             //var policy = behaviourPolicy;
    125 
    126             //var n = rootNode;
    127 
    128             //while (n != null)
    129             //{
    130             //    var phrase = n.phrase;
    131             //    Console.ForegroundColor = ConsoleColor.White;
    132             //    Console.WriteLine("{0,-30}", phrase);
    133             //    var children = n.children;
    134             //    if (children == null || !children.Any()) break;
    135             //    var values = children.Select(ch => policy.GetValue(ch.phrase));
    136             //    var maxValue = values.Max();
    137             //    if (maxValue == 0) maxValue = 1.0;
    138 
    139             //    // write phrases
    140             //    foreach (var ch in children)
    141             //    {
    142             //        SetColorForValue(policy.GetValue(ch.phrase) / maxValue);
    143             //        Console.Write(" {0,-4}", ch.phrase.Substring(Math.Max(0, ch.phrase.Length - 3), Math.Min(3, ch.phrase.Length)));
    144             //    }
    145             //    Console.WriteLine();
    146 
    147             //    // write values
    148             //    foreach (var ch in children)
    149             //    {
    150             //        SetColorForValue(policy.GetValue(ch.phrase) / maxValue);
    151             //        Console.Write(" {0:F2}", policy.GetValue(ch.phrase) * 10.0);
    152             //    }
    153             //    Console.WriteLine();
    154 
    155             //    // write tries
    156             //    foreach (var ch in children)
    157             //    {
    158             //        SetColorForValue(policy.GetValue(ch.phrase) / maxValue);
    159             //        Console.Write(" {0,4}", policy.GetTries(ch.phrase));
    160             //    }
    161             //    Console.WriteLine();
    162             //    int selectedChildIdx;
    163             //    if (!policy.TrySelect(random, phrase, children.Select(ch => ch.phrase), out selectedChildIdx))
    164             //    {
    165             //        break;
    166             //    }
    167             //    n = n.children[selectedChildIdx];
    168             //}
    169 
    170             //Console.ForegroundColor = ConsoleColor.White;
    171             //Console.WriteLine("-------------------");
    172         }
    173 
    174         private void SetColorForValue(double v)
    175         {
    176             Console.ForegroundColor = ConsoleEx.ColorForValue(v);
     169        public TreeInfos GetTreeInfos()
     170        {
     171            int totalNodes = 0;
     172            int unexpandedNodes = 0;
     173            int expandedNodes = 0;
     174            int leaveNodes = 0;
     175            int deepestLevel = 0;
     176            int totalLevel = 0;
     177            int totalChildren = 0;
     178
     179            List<TreeNode> toDoNodes = new List<TreeNode>();
     180            if (rootNode != null)
     181            {
     182                toDoNodes.Add(rootNode);
     183            }
     184            while (toDoNodes.Any())
     185            {
     186                TreeNode currentNode = toDoNodes[0];
     187                toDoNodes.RemoveAt(0);
     188                totalNodes++;
     189                if (currentNode.level > deepestLevel)
     190                {
     191                    deepestLevel = currentNode.level;
     192                }
     193                totalLevel += currentNode.level;
     194
     195                if (currentNode.children != null)
     196                {
     197                    totalChildren += currentNode.children.Count;
     198                    toDoNodes.AddRange(currentNode.children);
     199                    expandedNodes++;
     200                }
     201                else
     202                {
     203                    if (!HasNonTerminal(currentNode.phrase))
     204                    {
     205                        leaveNodes++;
     206                    }
     207                    else
     208                    {
     209                        unexpandedNodes++;
     210                    }
     211                }
     212            }
     213            return new TreeInfos(totalNodes, unexpandedNodes, expandedNodes, leaveNodes, deepestLevel,
     214                totalLevel / totalNodes, totalChildren / expandedNodes);
     215        }
     216
     217        public byte[] GenerateSvg()
     218        {
     219            IGetStartProcessQuery getStartProcessQuery = new GetStartProcessQuery();
     220            IGetProcessStartInfoQuery getProcessStartInfoQuery = new GetProcessStartInfoQuery();
     221            IRegisterLayoutPluginCommand registerLayoutPluginCommand =
     222                new RegisterLayoutPluginCommand(getProcessStartInfoQuery, getStartProcessQuery);
     223
     224            GraphGeneration wrapper = new GraphGeneration(getStartProcessQuery,
     225                getProcessStartInfoQuery,
     226                registerLayoutPluginCommand);
     227            wrapper.GraphvizPath = @"../../../Graphviz2.38/bin";
     228            StringBuilder dotFile = new StringBuilder("digraph {");
     229            dotFile.AppendLine();
     230            dotFile.AppendLine("splines=ortho;");
     231            dotFile.AppendLine("concentrate=true;");
     232            dotFile.AppendLine("ranksep=1.2;");
     233
     234            List<TreeNode> toDoNodes = new List<TreeNode>();
     235            if (rootNode != null)
     236            {
     237                toDoNodes.Add(rootNode);
     238                // declare node
     239                string hexColor = GetHexNodeColor(Color.White, Color.OrangeRed, rootNode.actionInfo.Value);
     240
     241                dotFile.AppendLine(string.Format("{0} [label=\"{1}\\n{2:0.00}/{3}\", style=filled, fillcolor=\"{4}\"]",
     242                    rootNode.GetHashCode(),
     243                    rootNode.phrase, rootNode.actionInfo.Value, rootNode.actionInfo.Tries, hexColor));
     244            }
     245
     246            // to put nodes on the same level in graph
     247            Dictionary<int, List<TreeNode>> levelMap = new Dictionary<int, List<TreeNode>>();
     248
     249            List<TreeNode> sameLevelNodes;
     250
     251            while (toDoNodes.Any())
     252            {
     253                TreeNode currentNode = toDoNodes[0];
     254                toDoNodes.RemoveAt(0);
     255                // put currentNode into levelMap
     256                if (levelMap.TryGetValue(currentNode.level, out sameLevelNodes))
     257                {
     258                    sameLevelNodes.Add(currentNode);
     259                }
     260                else
     261                {
     262                    sameLevelNodes = new List<TreeNode>();
     263                    sameLevelNodes.Add(currentNode);
     264                    levelMap.Add(currentNode.level, sameLevelNodes);
     265                }
     266
     267                // draw line from current node to all its children
     268                if (currentNode.children != null)
     269                {
     270                    foreach (TreeNode childNode in currentNode.children)
     271                    {
     272                        toDoNodes.Add(childNode);
     273                        // declare node
     274
     275                        string hexColor = GetHexNodeColor(Color.White, Color.OrangeRed, childNode.actionInfo.Value);
     276                        dotFile.AppendLine(
     277                            string.Format("{0} [label=\"{1}\\n{2:0.00}/{3}\", style=filled, fillcolor=\"{4}\"]",
     278                                childNode.GetHashCode(),
     279                                childNode.phrase, childNode.actionInfo.Value, childNode.actionInfo.Tries, hexColor));
     280                        // add edge
     281                        dotFile.AppendLine(string.Format("{0} -> {1}", currentNode.GetHashCode(),
     282                            childNode.GetHashCode()));
     283                    }
     284                }
     285            }
     286
     287            // set same level ranks..
     288            foreach (KeyValuePair<int, List<TreeNode>> entry in levelMap)
     289            {
     290                dotFile.Append("{rank = same;");
     291                foreach (TreeNode node in entry.Value)
     292                {
     293                    dotFile.Append(string.Format(" {0};", node.GetHashCode()));
     294                }
     295                dotFile.AppendLine("}");
     296            }
     297
     298            dotFile.Append(" }");
     299            byte[] output = wrapper.GenerateGraph(dotFile.ToString(), Enums.GraphReturnType.Svg);
     300            return output;
     301        }
     302
     303        private String HexConverter(Color c)
     304        {
     305            return "#" + c.R.ToString("X2") + c.G.ToString("X2") + c.B.ToString("X2");
     306        }
     307
     308        private String GetHexNodeColor(Color weakColor, Color strongColor, double quality)
     309        {
     310            // convert quality to value between 0 and 1
     311            double bestKnownQuality = problem.BestKnownQuality(this.maxLen);
     312            double q = quality / bestKnownQuality;
     313
     314            // calculate difference between colors
     315            byte rDiff = (byte)Math.Abs(weakColor.R - strongColor.R);
     316            byte bDiff = (byte)Math.Abs(weakColor.B - strongColor.B);
     317            byte gDiff = (byte)Math.Abs(weakColor.G - strongColor.G);
     318
     319            byte newR = weakColor.R > strongColor.R
     320                ? Convert.ToByte(weakColor.R - Math.Round(rDiff * q))
     321                : Convert.ToByte(weakColor.R + Math.Round(rDiff * q));
     322
     323            byte newB = weakColor.B > strongColor.B
     324                ? Convert.ToByte(weakColor.B - Math.Round(bDiff * q))
     325                : Convert.ToByte(weakColor.B + Math.Round(bDiff * q));
     326
     327            byte newG = weakColor.G > strongColor.G
     328                ? Convert.ToByte(weakColor.G - Math.Round(gDiff * q))
     329                : Convert.ToByte(weakColor.G + Math.Round(gDiff * q));
     330
     331            return HexConverter(Color.FromArgb(newR, newG, newB));
     332        }
     333
     334        public void PauseContinue()
     335        {
     336            lock (pauseLock)
     337            {
     338                if (isPaused)
     339                {
     340                    isPaused = false;
     341                    Monitor.Pulse(pauseLock);
     342                }
     343                else
     344                {
     345                    isPaused = true;
     346                }
     347            }
    177348        }
    178349    }
Note: See TracChangeset for help on using the changeset viewer.