Free cookie consent management tool by TermsFeed Policy Generator

source: branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment.Common/3.3/ExtensionMethods.cs @ 7407

Last change on this file since 7407 was 7407, checked in by abeham, 12 years ago

#1614: worked on GQAP

File size: 6.2 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using System;
23using System.Collections.Generic;
24using System.Linq;
25using HeuristicLab.Core;
26
27namespace HeuristicLab.Problems.GeneralizedQuadraticAssignment.Common {
28  public static class ExtensionMethods {
29
30    /// <summary>
31    /// Simply enumerates the sequence by moving over all elements.
32    /// </summary>
33    /// <typeparam name="T">The type of the items that are to be enumerated.</typeparam>
34    /// <param name="source">The enumerable that contains the items.</param>
35    public static void Enumerate<T>(this IEnumerable<T> source) {
36      var enumerator = source.GetEnumerator();
37      while (enumerator.MoveNext()) ;
38    }
39
40    /// <summary>
41    /// Selects an element from an enumerable randomly with equal probability for each element. If the sequence is empty, selected will be false and default(T) will be returned.
42    /// </summary>
43    /// <typeparam name="T">The type of the items that are to be selected.</typeparam>
44    /// <param name="source">The enumerable that contains the items.</param>
45    /// <param name="random">The random number generator, its NextDouble() method must return a value in the range [0;1).</param>
46    /// <param name="selected">True if an element was selected, false otherwise (only because of an empty sequence).</param>
47    /// <returns>The selected item.</returns>
48    public static T ChooseRandomOrDefault<T>(this IEnumerable<T> source, IRandom random, out bool selected) {
49      if (source == null) throw new ArgumentNullException("SelectRandomOrDefault: source is null");
50      uint counter = 1;
51      selected = false;
52      T selectedItem = default(T);
53      foreach (T item in source) {
54        if (counter * random.NextDouble() < 1.0) { // use multiplication instead of division
55          selectedItem = item;
56          selected = true;
57        }
58        counter++;
59      }
60      return selectedItem;
61    }
62
63    /// <summary>
64    /// Selects an element from an enumerable randomly with equal probability for each element.
65    /// </summary>
66    /// <typeparam name="T">The type of the items that are to be selected.</typeparam>
67    /// <param name="source">The enumerable that contains the items.</param>
68    /// <param name="random">The random number generator, its NextDouble() method must return a value in the range [0;1).</param>
69    /// <returns>The selected item.</returns>
70    public static T ChooseRandom<T>(this IEnumerable<T> source, IRandom random) {
71      if (source == null) throw new ArgumentNullException("SelectRandom: source is null");
72      if (!source.Any()) throw new ArgumentException("SelectRandom: sequence is empty.");
73      uint counter = 1;
74      T selectedItem = default(T);
75      foreach (T item in source) {
76        if (counter * random.NextDouble() < 1.0) // use multiplication instead of division
77          selectedItem = item;
78        counter++;
79      }
80      return selectedItem;
81    }
82
83    /// <summary>
84    /// Shuffles an enumerable and returns an new enumerable according to the Fisher-Yates shuffle.
85    /// </summary>
86    /// <remarks>
87    /// Source code taken from http://stackoverflow.com/questions/1287567/c-is-using-random-and-orderby-a-good-shuffle-algorithm.
88    /// Note that this is an online shuffle, but the source enumerable is transformed into an array.
89    /// </remarks>
90    /// <typeparam name="T">The type of the items that are to be shuffled.</typeparam>
91    /// <param name="source">The enumerable that contains the items.</param>
92    /// <param name="random">The random number generator, its Next(int) method must deliver uniformly distributed random numbers.</param>
93    /// <returns>An enumerable with the elements shuffled.</returns>
94    public static IEnumerable<T> Shuffle<T>(this IEnumerable<T> source, IRandom random) {
95      T[] elements = source.ToArray();
96      // Note i > 0 to avoid final pointless iteration
97      for (int i = elements.Length - 1; i > 0; i--) {
98        // Swap element "i" with a random earlier element it (or itself)
99        int swapIndex = random.Next(i + 1);
100        yield return elements[swapIndex];
101        elements[swapIndex] = elements[i];
102        // we don't actually perform the swap, we can forget about the
103        // swapped element because we already returned it.
104      }
105
106      // there is one item remaining that was not returned - we return it now
107      yield return elements[0];
108    }
109
110    /// <summary>
111    /// Walks an operator graph in that it jumps from one operator to all its operator parameters and yields each operator it touches.
112    /// Cycles are detected and not walked twice.
113    /// </summary>
114    /// <param name="initial">The operator where the walk starts (is also yielded).</param>
115    /// <returns>An enumeration of all the operators that could be found.</returns>
116    public static IEnumerable<IOperator> Walk(this IOperator initial) {
117      var open = new Stack<IOperator>();
118      var visited = new HashSet<IOperator>();
119      open.Push(initial);
120
121      while (open.Any()) {
122        IOperator current = open.Pop();
123        if (visited.Contains(current)) continue;
124        visited.Add(current);
125
126        foreach (var parameter in current.Parameters.OfType<IValueParameter>()) {
127          if (typeof(IOperator).IsAssignableFrom(parameter.DataType)) {
128            if (parameter.Value != null)
129              open.Push((IOperator)parameter.Value);
130          }
131        }
132
133        yield return current;
134      }
135    }
136
137  }
138}
Note: See TracBrowser for help on using the repository browser.