public static double[] Evaluate(List <List <Guid> > keys, IEnumerable <int> distribution, int iterations = 100000) { int[] results = distribution.Select(i => 0).ToArray(); ConsistentHash <Guid, int> hash = new ConsistentHash <Guid, int>(); keys.Select((group, i) => { group.ForEach(key => { hash.Add(key, i); }); return(group.Count()); }).ToArray(); hash.Commit(); int idx = 0; double ii = 0; for (; ii < iterations; ii++) { idx = hash[Guid.NewGuid()]; results[idx] = results.ElementAt(idx) + 1; } return(results.Select(i => ((i / ii) * 100)).ToArray()); }
public MonteCarloDistribution(IEnumerable <int> distribution) { var keys = Evaluate(distribution); keys.Select((group, i) => { group.ForEach(key => { hash.Add(key, distribution.ElementAt(i)); }); return(group.Count()); }).ToArray(); hash.Commit(); }
public static List <List <Guid> > Evaluate(IEnumerable <int> distribution, int iterations = 10000, int retry = 10000) { int[] ring = new int[100]; List <List <Guid> > hypothesis = new List <List <Guid> >(distribution.Select(i => { return(new List <Guid>()); })); for (int y = 0; y < retry; y++) { int idx = 0; int count = distribution.ElementAt(idx); ConsistentHash <Guid, int> hash = new ConsistentHash <Guid, int>(); int[] results = distribution.Select(i => 0).ToArray(); ring.Select((u, i) => { if (count > 0) { if (hypothesis.ElementAt(idx).Count() < distribution.ElementAt(idx)) { Guid guid = Guid.NewGuid(); hash.Add(guid, idx); hypothesis.ElementAt(idx).Add(guid); } else { hash.Add(hypothesis.ElementAt(idx).ElementAt(count - 1), idx); } } else { if (++idx < distribution.Count()) { count = distribution.ElementAt(idx); if (hypothesis.ElementAt(idx).Count() < distribution.ElementAt(idx)) { Guid g = Guid.NewGuid(); hash.Add(g, idx); hypothesis.ElementAt(idx).Add(g); } else { hash.Add(hypothesis.ElementAt(idx).ElementAt(count - 1), idx); } } } return(--count); }).ToArray(); hash.Commit(); double ii = 0; for (; ii < iterations; ii++) { idx = hash[Guid.NewGuid()]; results[idx] = results.ElementAt(idx) + 1; } results = results.Select(i => (int)((i / ii) * 100)).ToArray(); hypothesis = results.Select((result, i) => { if (Math.Abs((int)result - distribution.ElementAt(i)) <= 1) { return(hypothesis.ElementAt(i)); } else { hypothesis.ElementAt(i).Clear(); return(hypothesis.ElementAt(i)); } }).ToList(); if (hypothesis.Where(h => h.Count() == 0).Count() == 0) { break; } } return(hypothesis); }