Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.Problems.GrammaticalOptimization/HeuristicLab.Problems.GrammaticalOptimization/SantaFeAntProblem.cs @ 11708

Last change on this file since 11708 was 11708, checked in by gkronber, 9 years ago

#2283: worked on bandits for grammatical optimization

File size: 6.9 KB
Line 
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using System.Runtime.Remoting.Messaging;
5using System.Text;
6
7namespace HeuristicLab.Problems.GrammaticalOptimization {
8  public class SantaFeAntProblem : IProblem {
9    private const string grammarString = @"
10G(A):
11A -> l | r | m | ?(A)(A) | lA | rA | mA
12";
13    // original koza grammar
14    // Ant -> left | right | move | if-food-ahead Ant Ant | Ant Ant | Ant Ant Ant
15    //
16    // here we use a modified grammar which has only one syntax tree for each sentence
17
18
19    private readonly IGrammar grammar;
20
21    public SantaFeAntProblem() {
22      this.grammar = new Grammar(grammarString);
23    }
24
25    public double GetBestKnownQuality(int maxLen) {
26      // for now only an upper bound is returned, ideally all food pellets are discovered
27      return 89;
28    }
29
30    public IGrammar Grammar {
31      get { return grammar; }
32    }
33
34    public double Evaluate(string sentence) {
35      var ant = new Ant();
36      int p = 0;
37      Run(ant, sentence, ref p);
38      return ant.FoodEaten;
39    }
40
41    private void Run(Ant ant, string sentence, ref int p) {
42      while (!ant.Done()) {
43        if (p >= sentence.Length) p = 0; // restart
44        switch (sentence[p]) {
45          case 'r': {
46              ant.TurnRight();
47              p++;
48              break;
49            }
50          case 'l': {
51              ant.TurnLeft();
52              p++;
53              break;
54            }
55          case 'm': {
56              ant.Move();
57              p++;
58              break;
59            }
60          case '?': {
61              p++; // skip p
62              if (ant.IsFoodAhead()) {
63                if (sentence[p] != '(') throw new ArgumentException();
64                p++;
65                Run(ant, sentence, ref p);      // it cannot happen that we run over the the end of the sentence here
66                if (ant.Done()) return;
67                if (sentence[p] != '(') throw new ArgumentException();
68                p++;
69                Skip(sentence, ref p);
70              } else {
71                if (sentence[p] != '(') throw new ArgumentException();
72                p++;
73                Skip(sentence, ref p);
74                if (sentence[p] != '(') throw new ArgumentException();
75                p++;
76                Run(ant, sentence, ref p);    // it cannot happen that we run over the the end of the sentence here
77              }
78              break;
79            }
80          case ')': {
81              p++; // skip
82              return;     // caller must continue processing
83            }
84          default: {
85              throw new ArgumentException();
86            }
87        }
88      }
89    }
90
91    private void Skip(string sentence, ref int p) {
92      int openCount = 1;
93      while (openCount > 0) {
94        if (sentence[p] == '(') openCount++;
95        else if (sentence[p] == ')') openCount--;
96        p++;
97      }
98    }
99  }
100
101  public class Ant {
102    private const int maxSteps = 600;
103    public enum HeadingEnum { North, East, South, West };
104    public int FoodEaten { get; private set; }
105    private readonly char[][] world = new char[32][];
106    private int posX;
107    private int posY;
108    private int steps;
109    private HeadingEnum heading;
110
111    public Ant() {
112      world[00] = " ###                            ".ToCharArray();
113      world[01] = "   #                            ".ToCharArray();
114      world[02] = "   #                    .###..  ".ToCharArray();
115      world[03] = "   #                    #    #  ".ToCharArray();
116      world[04] = "   #                    #    #  ".ToCharArray();
117      world[05] = "   ####.#####       .##..    .  ".ToCharArray();
118      world[06] = "            #       .        #  ".ToCharArray();
119      world[07] = "            #       #        .  ".ToCharArray();
120      world[08] = "            #       #        .  ".ToCharArray();
121      world[09] = "            #       #        #  ".ToCharArray();
122      world[10] = "            .       #        .  ".ToCharArray();
123      world[11] = "            #       .        .  ".ToCharArray();
124      world[12] = "            #       .        #  ".ToCharArray();
125      world[13] = "            #       #        .  ".ToCharArray();
126      world[14] = "            #       #  ...###.  ".ToCharArray();
127      world[15] = "            .   .#...  #        ".ToCharArray();
128      world[16] = "            .   .      .        ".ToCharArray();
129      world[17] = "            #   .      .        ".ToCharArray();
130      world[18] = "            #   #      .#...    ".ToCharArray();
131      world[19] = "            #   #          #    ".ToCharArray();
132      world[20] = "            #   #          .    ".ToCharArray();
133      world[21] = "            #   #          .    ".ToCharArray();
134      world[22] = "            #   .      ...#.    ".ToCharArray();
135      world[23] = "            #   .      #        ".ToCharArray();
136      world[24] = " ..##..#####.   #               ".ToCharArray();
137      world[25] = " #              #               ".ToCharArray();
138      world[26] = " #              #               ".ToCharArray();
139      world[27] = " #     .#######..               ".ToCharArray();
140      world[28] = " #     #                        ".ToCharArray();
141      world[29] = " .     #                        ".ToCharArray();
142      world[30] = " .####..                        ".ToCharArray();
143      world[31] = "                                ".ToCharArray();
144
145      posX = 0;
146      posY = 0;
147      heading = HeadingEnum.East;
148      FoodEaten = 0;
149      steps = 0;
150    }
151
152    public bool Done() {
153      return steps > maxSteps;
154    }
155
156    public void TurnRight() {
157      if (steps <= maxSteps) {
158        steps++;
159        if (heading == HeadingEnum.West) heading = HeadingEnum.North;
160        else heading++;
161      }
162    }
163
164    public void TurnLeft() {
165      if (steps <= maxSteps) {
166        steps++;
167        if (heading == HeadingEnum.North) heading = HeadingEnum.West;
168        else heading--;
169      }
170    }
171
172    public void Move() {
173      if (steps <= maxSteps) {
174        steps++;
175        MoveInternal(ref posX, ref posY);
176        if (world[posY][posX] == '#') {
177          FoodEaten++;
178          world[posY][posX] = '.';
179        }
180      }
181    }
182
183    private void MoveInternal(ref int posX, ref int posY) {
184      switch (heading) {
185        case HeadingEnum.North:
186          posY = (posY + 31) % 32;
187          break;
188        case HeadingEnum.East:
189          posX = (posX + 1) % 32;
190          break;
191        case HeadingEnum.South:
192          posY = (posY + 1) % 32;
193          break;
194        case HeadingEnum.West:
195          posX = (posX + 31) % 32;
196          break;
197      }
198    }
199
200    public bool IsFoodAhead() {
201      int nextPosX = posX;
202      int nextPosY = posY;
203      MoveInternal(ref nextPosX, ref nextPosY);
204      return world[nextPosY][nextPosX] == '#';
205    }
206  }
207}
Note: See TracBrowser for help on using the repository browser.