source: branches/StackingProblems/HeuristicLab.Data.MoveVectorData/3.3/StackingArea.cs @ 14278

Last change on this file since 14278 was 14278, checked in by mzehetho, 5 years ago

Initial Commit for ticket #2605

Implemented:

  • Encoding
  • Moves
  • Views
  • Blocks World Problem
  • Blocks Relocation Problem
  • Stacking Problem
File size: 16.6 KB
Line 
1using HeuristicLab.Common;
2using HeuristicLab.Core;
3using HeuristicLab.Data.MoveVectorData.Interfaces;
4using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
5using System;
6using System.Collections;
7using System.Collections.Generic;
8using System.Drawing;
9using System.Linq;
10using System.Text;
11
12namespace HeuristicLab.Data.MoveVectorData
13{
14    [Item("StackingArea", "Represents multiple stacks of containers.")]
15    [StorableClass]
16    public class StackingArea : Item, IEnumerable<Stack>, IStringConvertibleMatrix, IStringConvertibleArray
17    {
18        private const int maximumToStringLength = 100;
19
20        public static new Image StaticItemImage
21        {
22            get { return HeuristicLab.Common.Resources.VSImageLibrary.Class; }
23        }
24
25        [Storable]
26        protected Stack[] array;
27
28        #region Parameters
29        [Storable]
30        protected List<string> elementNames;
31        public virtual IEnumerable<string> ElementNames
32        {
33            get { return this.elementNames; }
34            set
35            {
36                if (ReadOnly) throw new NotSupportedException("ElementNames cannot be set. ValueTypeArray is read-only.");
37                if (value == null || !value.Any())
38                    elementNames = new List<string>();
39                else if (value.Count() > Size)
40                    throw new ArgumentException("The number of element names must not exceed the array length.");
41                else
42                    elementNames = new List<string>(value);
43                OnElementNamesChanged();
44            }
45        }
46
47        [Storable]
48        protected List<string> rowNames;
49        public IEnumerable<string> RowNames
50        {
51            get { return this.rowNames; }
52
53            set
54            {
55                if (ReadOnly) throw new NotSupportedException("RowNames cannot be set. ValueTypeArray is read-only.");
56                if (value == null || !value.Any())
57                    rowNames = new List<string>();
58                else if (value.Count() > Size)
59                    throw new ArgumentException("The number of row names must not exceed the array length.");
60                else
61                    rowNames = new List<string>(value);
62                OnRowNamesChanged();
63            }
64        }
65
66        public virtual int Size
67        {
68            get { return array.Length; }
69            protected set
70            {
71                if (ReadOnly) throw new NotSupportedException("Size cannot be set. StringArray is read-only.");
72                if (value != Size)
73                {
74                    Array.Resize<Stack>(ref array, value);
75                    while (elementNames.Count > value)
76                        elementNames.RemoveAt(elementNames.Count - 1);
77                    OnElementNamesChanged();
78                    OnReset();
79                }
80            }
81        }
82
83        public virtual int MaxHeight
84        {
85            get { return this.Max(x => x.Length); }
86            set
87            {
88                array = new Stack[Size];
89                for (int i = 0; i < array.Length; i++)
90                {
91                    array[i] = new Stack(i, value);
92                    array[i].ItemChanged += StackingArea_ItemChanged;
93                }
94                readOnly = false;
95                elementNames = new List<string>();
96                rowNames = new List<string>();
97            }
98        }
99
100        public virtual int Capacity
101        {
102            get
103            {
104                return array.Sum(stack => stack.Length);
105            }
106        }
107        #endregion
108
109        #region ReadOnly
110        [Storable]
111        protected bool readOnly;
112        public virtual bool ReadOnly
113        {
114            get { return readOnly; }
115        }
116        public virtual StackingArea AsReadOnly()
117        {
118            StackingArea readOnlyStringArray = (StackingArea)this.Clone();
119            readOnlyStringArray.readOnly = true;
120            return readOnlyStringArray;
121        }
122        #endregion
123
124        #region Cloning
125        [StorableHook(HookType.AfterDeserialization)]
126        private void AfterDeserialization()
127        {
128            if (elementNames == null) { elementNames = new List<string>(); }
129            if (rowNames == null) { rowNames = new List<string>(); }
130        }
131
132        [StorableConstructor]
133        protected StackingArea(bool deserializing) : base(deserializing) { }
134        protected StackingArea(StackingArea original, Cloner cloner) : base(original, cloner)
135        {
136            //this.array = (Stack[])original.array.Clone();
137            this.array = new Stack[original.Size];
138            for (int i = 0; i < array.Length; i++)
139            {
140                array[i] = (Stack)original.array[i].Clone();
141            }
142            this.readOnly = original.readOnly;
143            this.elementNames = new List<string>(original.elementNames);
144            this.rowNames = new List<string>(original.rowNames);
145        }
146
147        public override IDeepCloneable Clone(Cloner cloner)
148        {
149            return new StackingArea(this, cloner);
150        }
151        #endregion
152
153        public StackingArea() : this(0) { }
154        public StackingArea(int size)
155        {
156            array = new Stack[size];
157            readOnly = false;
158            elementNames = new List<string>();
159            rowNames = new List<string>();
160       }
161        public StackingArea(int size, int maxHeight) : this(size)
162        {
163            for (int i = 0; i < array.Length; i++)
164            {
165                array[i] = new Stack(i, maxHeight);
166                array[i].ItemChanged += StackingArea_ItemChanged;
167            }
168        }
169
170        public StackingArea(Stack[] elements) : this(elements.Length)
171        {
172            for (int i = 0; i < array.Length; i++)
173            {
174                array[i] = elements[i];
175            }
176        }
177
178        public void Clear()
179        {
180            foreach(var stack in array)
181            {
182                stack.Clear();
183            }
184        }
185
186        public void Randomize(double fillRate, int seed)
187        {
188            if (fillRate > 1 || fillRate < 0)
189            {
190                throw new ArgumentOutOfRangeException("Fill Rate must be between 0 and 1, but is " + fillRate);
191            }
192            Random random = new Random(seed);
193            Clear();
194            int containerCount = Convert.ToInt32(Capacity * fillRate);
195            var range = new List<int>(containerCount + 1);
196            for(int i = 0; i < containerCount; i++)
197            {
198                range.Add(i + 1);
199            }
200            range.Shuffle(random);
201
202            for(int i = 0; i < containerCount; i++)
203            {
204                Stack stack;
205                do
206                {
207                    var stackNr = random.Next(0, Size);
208                    stack = array[stackNr];
209                } while (stack.CurrentHeight >= stack.Length);
210                stack.Push(range[i]);
211            }
212        }
213
214        public override string ToString()
215        {
216            if (array.Length == 0) return "[]";
217
218            StringBuilder sb = new StringBuilder();
219            sb.Append("[");
220            sb.Append(array[0]);
221            for (int i = 1; i < array.Length; i++)
222            {
223                sb.Append(";").Append(array[i]);
224                if (sb.Length > maximumToStringLength)
225                {
226                    sb.Append("...");
227                    break;
228                }
229            }
230            sb.Append("]");
231            return sb.ToString();
232        }
233
234        public virtual IEnumerator<Stack> GetEnumerator()
235        {
236            return array.Cast<Stack>().GetEnumerator();
237        }
238
239        IEnumerator IEnumerable.GetEnumerator()
240        {
241            return GetEnumerator();
242        }
243
244        public static int ApplyMoves(ref StackingArea startArea, ref Stack inputStack, MoveVector moves, out int realMoves)
245        {
246            int quality = 0;
247            int nrMoves = 0;
248            foreach (IMove move in moves)
249            {
250                int real = 0;
251                quality = quality + move.Apply(ref startArea, ref inputStack, out real);
252                nrMoves = nrMoves + real;
253            }
254            realMoves = nrMoves;
255            return quality;
256        }
257
258        public static int ApplyMoves(ref StackingArea startArea, MoveVector moves, out int realMoves)
259        {
260            Stack inputStack = null;
261            return ApplyMoves(ref startArea, ref inputStack, moves, out realMoves);
262        }
263
264        public virtual bool Validate(string value, out string errorMessage)
265        {
266            if (value == null) //TODO
267            {
268                errorMessage = "Invalid Value (string must not be null)";
269                return false;
270            }
271            else {
272                errorMessage = string.Empty;
273                return true;
274            }
275        }
276
277        public virtual Stack this[int index]
278        {
279            get { return array[index]; }
280            set
281            {
282                if (ReadOnly) throw new NotSupportedException("Item cannot be set. StringArray is read-only.");
283                if (value != array[index])
284                {
285                    if (value != null)
286                    {
287                        array[index] = value;
288                        OnItemChanged(index);
289                    }
290                }
291            }
292        }
293
294        public virtual int this[int row, int stack]
295        {
296            get { return array[stack][row]; }
297            set
298            {
299                if (ReadOnly) throw new NotSupportedException("Item cannot be set. StringArray is read-only.");
300                array[stack][row] = value;
301                OnItemInStackChanged(row, stack);
302            }
303        }
304
305        public virtual string GetValue(int index)
306        {
307            return this[index].ToString();
308        }
309
310        public virtual string GetValue(int row, int stack)
311        {
312            return this[row, stack].ToString();
313        }
314
315        public virtual bool SetValue(string value, int index)
316        {
317            if (value != null && value.StartsWith("[") && value.EndsWith("]"))
318            {
319                string[] strings = value.Substring(1, value.Length - 2).Split(';');
320                for (int i = 0; i < Size; i++)
321                {
322                    int result;
323                    if (Int32.TryParse(strings[i], out result))
324                    {
325                        this[index][i] = result;
326                    }
327                    else
328                    {
329                        return false;
330                    }
331                }
332                return true;
333            }
334            else {
335                return false;
336            }
337        }
338        public virtual bool SetValue(string value, int row, int stack)
339        {
340            int result;
341            if (value != null && Int32.TryParse(value, out result))
342            {
343                this[row, stack] = result;
344                return true;
345            }
346            return false;
347        }
348
349        #region Events
350        private void StackingArea_ItemChanged(object sender, EventArgs<int> e)
351        {
352            Stack s = (Stack)sender;
353            OnItemInStackChanged(e.Value, s.Id);
354        }
355        public event EventHandler ElementNamesChanged;
356        protected virtual void OnElementNamesChanged()
357        {
358            EventHandler handler = ElementNamesChanged;
359            if (handler != null)
360                handler(this, EventArgs.Empty);
361        }
362
363        public event EventHandler RowNamesChanged;
364        protected virtual void OnRowNamesChanged()
365        {
366            EventHandler handler = RowNamesChanged;
367            if (handler != null)
368                handler(this, EventArgs.Empty);
369        }
370
371        public event EventHandler<EventArgs<int>> ItemChanged;
372        protected virtual void OnItemChanged(int index)
373        {
374            if (ItemChanged != null)
375                ItemChanged(this, new EventArgs<int>(index));
376            if (index < maximumToStringLength)
377                OnToStringChanged();
378        }
379
380        public event EventHandler<EventArgs<int, int>> ItemInStackChanged;
381        protected virtual void OnItemInStackChanged(int row, int stack)
382        {
383            if (ItemInStackChanged != null)
384                ItemInStackChanged(this, new EventArgs<int, int>(row, stack));
385            if (stack < maximumToStringLength && row < maximumToStringLength)
386                OnToStringChanged();
387        }
388
389        public event EventHandler Reset;
390        protected virtual void OnReset()
391        {
392            if (Reset != null)
393                Reset(this, EventArgs.Empty);
394            OnToStringChanged();
395        }
396
397        public event EventHandler ColumnsChanged;
398        protected virtual void OnColumnsChanged()
399        {
400            if (ColumnsChanged != null)
401                ColumnsChanged(this, EventArgs.Empty);
402            throw new NotImplementedException();
403        }
404
405        public event EventHandler RowsChanged;
406        protected virtual void OnRowsChanged()
407        {
408            if (RowsChanged != null)
409                RowsChanged(this, EventArgs.Empty);
410            throw new NotImplementedException();
411        }
412
413        public event EventHandler ColumnNamesChanged;
414        protected virtual void OnColumnNamesChanged()
415        {
416            if (ColumnNamesChanged != null)
417                ColumnNamesChanged(this, EventArgs.Empty);
418            throw new NotImplementedException();
419        }
420
421        public event EventHandler SortableViewChanged;
422        public event EventHandler ResizableChanged;
423
424        protected virtual void OnSortableViewChanged()
425        {
426            if (SortableViewChanged != null)
427                SortableViewChanged(this, EventArgs.Empty);
428            throw new NotImplementedException();
429        }
430        #endregion
431
432        #region IStringConvertibleMatrix Members
433        event EventHandler<EventArgs<int, int>> IStringConvertibleMatrix.ItemChanged
434        {
435            add { ItemInStackChanged += value; }
436            remove { ItemInStackChanged -= value; }
437        }
438        int IStringConvertibleMatrix.Rows
439        {
440            get { return MaxHeight; }
441            set { MaxHeight = value; }
442        }
443        int IStringConvertibleMatrix.Columns
444        {
445            get { return Size; }
446            set { Size = value; }
447        }
448        public IEnumerable<string> ColumnNames
449        {
450            get { return ElementNames; }
451            set { ElementNames = value; }
452        }
453        public bool SortableView
454        {
455            get { return false; }
456            set { throw new NotImplementedException(); }
457        }
458
459        bool IStringConvertibleMatrix.Validate(string value, out string errorMessage)
460        {
461            return Validate(value, out errorMessage);
462        }
463        string IStringConvertibleMatrix.GetValue(int rowIndex, int columIndex)
464        {
465            return GetValue(rowIndex, columIndex);
466        }
467        bool IStringConvertibleMatrix.SetValue(string value, int rowIndex, int columnIndex)
468        {
469            return SetValue(value, rowIndex, columnIndex);
470        }
471        #endregion
472
473        #region IStringConvertibleArray Members
474        int IValueTypeArray.Length
475        {
476            get { return Size; }
477            set { Size = value; }
478        }
479        bool IValueTypeArray.Resizable
480        {
481            get { return false; }
482            set { }
483        }
484        IValueTypeArray IValueTypeArray.AsReadOnly()
485        {
486            throw new NotImplementedException();
487        }
488        bool IStringConvertibleArray.Validate(string value, out string errorMessage)
489        {
490            return Validate(value, out errorMessage);
491        }
492        string IStringConvertibleArray.GetValue(int index)
493        {
494            return GetValue(index);
495        }
496        bool IStringConvertibleArray.SetValue(string value, int index)
497        {
498            return SetValue(value, index);
499        }
500        #endregion
501
502    }
503
504    static class ListExtentions
505    {
506        public static void Shuffle<T>(this IList<T> list, Random random)
507        {
508            int n = list.Count;
509            while (n > 1)
510            {
511                n--;
512                int k = random.Next(n + 1);
513                T value = list[k];
514                list[k] = list[n];
515                list[n] = value;
516            }
517        }
518    }
519}
Note: See TracBrowser for help on using the repository browser.