Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.VariableInteractionNetworks/HeuristicLab.VariableInteractionNetworks/3.3/TinySet.cs @ 13788

Last change on this file since 13788 was 13788, checked in by bburlacu, 8 years ago

#2288: Improve the CreateTargetVariationExperimentDialog to produce combinations of inputs and target according to a user-provided binomial coefficient.

File size: 3.7 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2016 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;
24using System.Collections.Generic;
25using System.Linq;
26
27namespace HeuristicLab.VariableInteractionNetworks {
28  internal static class Util {
29    public static IEnumerable<IEnumerable<T>> Combinations<T>(IList<T> items, int k) {
30      if (k < 0)
31        throw new InvalidOperationException();
32      if (items == null)
33        throw new ArgumentNullException("items");
34      int n = items.Count;
35      if (n > TinySet.Maximum)
36        throw new InvalidOperationException();
37      return
38        from combination in Combinations(n, k)
39        select (from index in combination select items[index]);
40    }
41
42    // Takes integers n and k, both non-negative.
43    // Produces all sets of exactly k elements consisting only of
44    // integers from 0 through n - 1.
45    private static IEnumerable<TinySet> Combinations(int n, int k) {
46      // Base case: if k is zero then there can be only one set
47      // regardless of the value of n: the empty set is the only set
48      // with zero elements.
49      if (k == 0) {
50        yield return TinySet.Empty;
51        yield break;
52      }
53
54      // Base case: if n < k then there can be no set of exactly
55      // k elements containing values from 0 to n - 1, because sets
56      // do not contain repeated elements.
57
58      if (n < k)
59        yield break;
60
61      // A set containing k elements where each is an integer from
62      // 0 to n - 2 is also a set of k elements where each is an
63      // integer from 0 to n - 1, so yield all of those.
64
65      foreach (var r in Combinations(n - 1, k))
66        yield return r;
67
68      // If we add n - 1 to all the sets of k - 1 elements where each
69      // is an integer from 0 to n - 2, then we get a set of k elements
70      // where each is an integer from 0 to n - 1.
71
72      foreach (var r in Combinations(n - 1, k - 1))
73        yield return r.Add(n - 1);
74    }
75  }
76
77  internal struct TinySet : IEnumerable<int> {
78    public static readonly TinySet Empty = new TinySet(0);
79    public const int Minimum = 0;
80    public const int Maximum = 31;
81    private readonly int bits;
82    private TinySet(int bits) { this.bits = bits; }
83    public bool Contains(int item) {
84      if (item < Minimum || item > Maximum)
85        return false;
86      return (bits & (1 << item)) != 0;
87    }
88    public TinySet Add(int item) {
89      if (item < Minimum || item > Maximum)
90        throw new InvalidOperationException();
91      return new TinySet(bits | (1 << item));
92    }
93    public TinySet Remove(int item) {
94      if (item < Minimum || item > Maximum)
95        return this;
96      return new TinySet(bits & ~(1 << item));
97    }
98    IEnumerator IEnumerable.GetEnumerator() {
99      return this.GetEnumerator();
100    }
101    public IEnumerator<int> GetEnumerator() {
102      for (int item = Minimum; item <= Maximum; ++item)
103        if (Contains(item))
104          yield return item;
105    }
106  }
107}
Note: See TracBrowser for help on using the repository browser.