/// <summary> /// Initialise agent and prey positions. The prey is positioned randomly with at least 4 empty squares between it and a wall (in all directions). /// The agent is positioned randomly but such that the prey is within sensor range (distance 2 or less). /// </summary> public void InitPositions() { // Random position at least 4 units away from any wall. _preyPos.X = 4 + _rng.Next(__gridSize - 8); _preyPos.Y = 4 + _rng.Next(__gridSize - 8); // Agent position. The angle from the prey is chosen at random, and the distance from the prey is randomly chosen between 2 and 4. float t = 2f * MathF.PI * _rng.NextFloat(); // Random angle. float r = MathF.FusedMultiplyAdd(2f, _rng.NextFloat(), 2f); // A distance between 2 and 4. _agentPos.X = _preyPos.X + (int)MathF.Truncate(MathF.Cos(t) * r); _agentPos.Y = _preyPos.Y + (int)MathF.Truncate(MathF.Sin(t) * r); }
public void CreateGenome() { var metaNeatGenome = new MetaNeatGenome <double>( inputNodeCount: 10, outputNodeCount: 20, isAcyclic: true, activationFn: new NeuralNets.Double.ActivationFunctions.ReLU()); var genomeBuilder = NeatGenomeBuilderFactory <double> .Create(metaNeatGenome); int count = 100; NeatPopulation <double> pop = NeatPopulationFactory <double> .CreatePopulation(metaNeatGenome, 0.1, count, RandomDefaults.CreateRandomSource()); var generationSeq = new Int32Sequence(); var strategy = new UniformCrossoverReproductionStrategy <double>( pop.MetaNeatGenome.IsAcyclic, 0.02, genomeBuilder, pop.GenomeIdSeq, generationSeq); IRandomSource rng = RandomDefaults.CreateRandomSource(0); var cyclicGraphCheck = new CyclicGraphCheck(); for (int i = 0; i < 1000; i++) { // Randomly select two parents from the population. var genome1 = pop.GenomeList[rng.Next(count)]; var genome2 = pop.GenomeList[rng.Next(count)]; var childGenome = strategy.CreateGenome(genome1, genome2, rng); // The connection genes should be sorted. Assert.True(SortUtils.IsSortedAscending <DirectedConnection>(childGenome.ConnectionGenes._connArr)); // The child genome should describe an acyclic graph, i.e. the new connection should not have // formed a cycle in the graph. var digraph = childGenome.DirectedGraph; Assert.False(cyclicGraphCheck.IsCyclic(digraph)); // The child genome node IDs should be a superset of those from parent1 + parent2. var childNodeIdSet = GetNodeIdSet(childGenome); var parentIdSet = GetNodeIdSet(genome1); parentIdSet.IntersectWith(GetNodeIdSet(genome2)); Assert.True(childNodeIdSet.IsSupersetOf(parentIdSet)); } }
/// <summary> /// Gets the next 64 random bits. /// </summary> public void Next(ref ValueUnion value) { lock (syncRoot) { source.Next(ref value); } }
/// <summary> /// Initialise an array with random integers. /// </summary> /// <param name="keys">The array to initialise.</param> /// <param name="rng">Random number generator.</param> public static void InitRandom(Span <int> keys, IRandomSource rng) { for (int i = 0; i < keys.Length; i++) { keys[i] = rng.Next(); } }
/// <summary> /// Take multiple samples from a set of possible outcomes with equal probability, i.e. a uniform discrete distribution, /// with replacement, i.e. any given value will only occur once at most in the set of samples /// </summary> /// <param name="numberOfOutcomes">The number of possible outcomes per sample.</param> /// <param name="sampleArr">An array to fill with samples.</param> /// <param name="rng">A source of randomness.</param> public static void SampleUniformWithoutReplacement(int numberOfOutcomes, int[] sampleArr, IRandomSource rng) { if (sampleArr.Length > numberOfOutcomes) { throw new ArgumentException("sampleArr length must be less then or equal to numberOfOutcomes."); } // Create an array of indexes, one index per possible choice. int[] indexArr = new int[numberOfOutcomes]; for (int i = 0; i < numberOfOutcomes; i++) { indexArr[i] = i; } // Sample loop. for (int i = 0; i < sampleArr.Length; i++) { // Select an index at random. int idx = rng.Next(i, numberOfOutcomes); // Swap elements i and idx. Swap(indexArr, i, idx); } // Copy the samples into the result array. for (int i = 0; i < sampleArr.Length; i++) { sampleArr[i] = indexArr[i]; } }
private static string Encode_WriteFragments(byte[] buf, int count, IRandomSource rng) { using (MemoryStream ms = new(buf.Length)) { using (Base64EncodingOutputStream base64Strm = new(ms, Encoding.UTF8)) { int idx = 0; int remain = count; while (remain > 0) { int len = Math.Min(rng.Next(256), remain); base64Strm.Write(buf, idx, len); idx += len; remain -= len; } } ms.Position = 0; using StreamReader sr = new(ms, Encoding.UTF8); string base64Str = sr.ReadToEnd(); return(base64Str); } }
private static void InitRandomValues(Span <int> span, IRandomSource rng) { for (int i = 0; i < span.Length; i++) { span[i] = rng.Next(); } }
/// <summary> /// Initialise an array with random integers. /// </summary> /// <param name="arr">The array to initialise.</param> /// <param name="rng">Random number generator.</param> public static void InitRandom(int[] arr, IRandomSource rng) { for (int i = 0; i < arr.Length; i++) { arr[i] = rng.Next(); } }
/// <summary>Generates a sequence of integral numbers within a specified range and in random order.</summary> /// <param name="start">The value of the first integer in the sequence.</param> /// <param name="count">The number of sequential integers to generate.</param> /// <returns>A new IEnumerable{int}.</returns> public static IEnumerable <int> RangeRandomOrder(int start, int count, IRandomSource rng) { long numl = (long)start + (long)count - 1L; if (count < 0 || numl > int.MaxValue) { throw new ArgumentOutOfRangeException("count"); } // Create an array of all indexes to be yielded. int[] arr = new int[count]; for (int i = 0; i < count; i++) { arr[i] = start + i; } // Yield all values in turn, applying a Fisher–Yates shuffle as we go in order to randomize the yield order. // See https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle for (int i = count - 1; i > 0; i--) { int swapIdx = rng.Next(i + 1); int tmp = arr[swapIdx]; arr[swapIdx] = arr[i]; arr[i] = tmp; yield return(arr[i]); } // Yield final value. yield return(arr[0]); }
/// <summary> /// Construct with the given distribution and a random source. /// </summary> /// <param name="max">Maximum absolute value.</param> /// <param name="signed">Indicates if the distribution interval includes negative values.</param> /// <param name="rng">Random source.</param> public Int32UniformDistributionSampler(int max, bool signed, IRandomSource rng) { _max = max; _signed = signed; _rng = rng; // Note. We predetermine which of these two function variants to use at construction time, // thus avoiding a branch on each invocation of Sample() (i.e. this is a micro-optimization). if (signed) { _sampleFn = (r) => _rng.Next(-max, max); } else { _sampleFn = (r) => _rng.Next(max); } }
private static int[] CreateRandomConnectionIdArray(int length, IRandomSource rng) { int[] arr = new int[length]; for (int i = 0; i < length; i++) { arr[i] = rng.Next(length); } return(arr); }
public void LongRandomArrays() { IRandomSource rng = RandomDefaults.CreateRandomSource(0); for (int i = 0; i < 100; i++) { int length = rng.Next(200000); LongRandomArraysInner(length, rng); } }
private static int[] CreateRandomArray(int len, IRandomSource rng) { var arr = new int[len]; for (int i = 0; i < len; i++) { arr[i] = rng.Next(int.MinValue, int.MaxValue); } return(arr); }
public Species <T>[] InitialiseSpecies( IList <NeatGenome <T> > genomeList, int speciesCount, IRandomSource rng) { // Create an array of seed genomes, i.e. each of these genomes will become the initial // seed/centroid of one species. var seedGenomeList = new List <NeatGenome <T> >(speciesCount); // Create a list of genomes to select and remove seed genomes from. var remainingGenomes = new List <NeatGenome <T> >(genomeList); // Select first genome at random. seedGenomeList.Add(GetAndRemove(remainingGenomes, rng.Next(remainingGenomes.Count))); // Select all other seed genomes using k-means++ method. for (int i = 1; i < speciesCount; i++) { var seedGenome = GetSeedGenome(seedGenomeList, remainingGenomes, rng); seedGenomeList.Add(seedGenome); } // Create an array of species initialised with the chosen seed genomes. // Each species is created with an initial capacity that will reduce the need for memory // reallocation but that isn't too wasteful of memory. int initialCapacity = (genomeList.Count * 2) / speciesCount; var speciesArr = new Species <T> [speciesCount]; for (int i = 0; i < speciesCount; i++) { var seedGenome = seedGenomeList[i]; speciesArr[i] = new Species <T>(i, seedGenome.ConnectionGenes, initialCapacity); speciesArr[i].GenomeList.Add(seedGenome); } // Allocate all other genomes to the species centroid they are nearest too. Parallel.ForEach(remainingGenomes, _parallelOptions, genome => { var nearestSpeciesIdx = GetNearestSpecies(_distanceMetric, genome, speciesArr); var nearestSpecies = speciesArr[nearestSpeciesIdx]; lock (nearestSpecies.GenomeList) { nearestSpecies.GenomeList.Add(genome); } }); // Recalc species centroids. Parallel.ForEach(speciesArr, _parallelOptions, species => { species.Centroid = _distanceMetric.CalculateCentroid(species.GenomeList.Select(genome => genome.ConnectionGenes)); }); return(speciesArr); }
static double BuildDouble(IRandomSource source) { double value; do { value = BitConverter.ToDouble(source.Next(8), 0); }while(double.IsNaN(value) || double.IsInfinity(value)); return(value); }
static float BuildFloat(IRandomSource source) { float value; do { value = BitConverter.ToSingle(source.Next(4), 0); }while(float.IsNaN(value) || float.IsInfinity(value)); return(value); }
static decimal BuildDecimal(IRandomSource source) { byte scale = (byte)(source.Next(1)[0] % 29); bool sign = BuildBoolean(source); return(new decimal( BuildInt(source), BuildInt(source), BuildInt(source), sign, scale)); }
/// <summary> /// Randomly shuffles a sub-span of items within a list. /// </summary> /// <param name="list">The list to shuffle.</param> /// <param name="rng">Random number generator.</param> /// <param name="startIdx">The index of the first item in the segment.</param> /// <param name="endIdx">The index of the last item in the segment, i.e. endIdx is inclusive; the item at endIdx will participate in the shuffle.</param> public static void Shuffle <T>(IList <T> list, IRandomSource rng, int startIdx, int endIdx) { // Fisher–Yates shuffle. // https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle for (int i = endIdx; i > startIdx; i--) { int swapIdx = startIdx + rng.Next((i - startIdx) + 1); T tmp = list[swapIdx]; list[swapIdx] = list[i]; list[i] = tmp; } }
/// <summary> /// Randomly shuffles the items of a span. /// </summary> /// <param name="span">The span to shuffle.</param> /// <param name="rng">Random number generator.</param> /// <typeparam name="T">The span element type.</typeparam> public static void Shuffle <T>(Span <T> span, IRandomSource rng) { // Fisher–Yates shuffle. // https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle for (int i = span.Length - 1; i > 0; i--) { int swapIdx = rng.Next(i + 1); T tmp = span[swapIdx]; span[swapIdx] = span[i]; span[i] = tmp; } }
/// <summary> /// Randomly shuffles items within a list. /// </summary> /// <param name="list">The list to shuffle.</param> /// <param name="rng">Random number generator.</param> public static void Shuffle <T>(IList <T> list, IRandomSource rng) { // Fisher–Yates shuffle. // https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle for (int i = list.Count - 1; i > 0; i--) { int swapIdx = rng.Next(i + 1); T tmp = list[swapIdx]; list[swapIdx] = list[i]; list[i] = tmp; } }
/// <summary> /// Randomly shuffles items within a list. /// </summary> /// <param name="list">The list to shuffle.</param> /// <param name="rng">Random number generator.</param> public static void Shuffle <T>(IList <T> list, IRandomSource rng) { // This approach was suggested by Jon Skeet in a dotNet newsgroup post and // is also the technique used by the OpenJDK. The use of rnd.Next(i+1) introduces // the possibility of swapping an item with itself, I suspect the reasoning behind this // has to do with ensuring the probability of each possible permutation is approximately equal. for (int i = list.Count - 1; i > 0; i--) { int swapIndex = rng.Next(i + 1); T tmp = list[swapIndex]; list[swapIndex] = list[i]; list[i] = tmp; } }
private bool TryGetConnectionInner( NeatGenome <T> parent, IRandomSource rng, out DirectedConnection conn, out int insertIdx) { int inputCount = _metaNeatGenome.InputNodeCount; int outputCount = _metaNeatGenome.OutputNodeCount; int hiddenCount = parent.HiddenNodeIdArray.Length; // Select a source node at random. // Note. this can be any node (input, output or hidden). int totalNodeCount = parent.MetaNeatGenome.InputOutputNodeCount + hiddenCount; int srcId = GetNodeIdFromIndex(parent, rng.Next(totalNodeCount)); // Select a target node at random. // Note. This cannot be an input node (so must be a hidden or output node). int outputHiddenCount = outputCount + hiddenCount; int tgtId = GetNodeIdFromIndex(parent, inputCount + rng.Next(outputHiddenCount)); // Test if the chosen connection already exists. // Note. Connection genes are always sorted by sourceId then targetId, so we can use a binary search to // find an existing connection in O(log(n)) time. conn = new DirectedConnection(srcId, tgtId); if ((insertIdx = Array.BinarySearch(parent.ConnectionGenes._connArr, conn)) < 0) { // The proposed new connection does not already exist, therefore we can use it. // Get the position in parent.ConnectionGeneArray that the new connection should be inserted at (to maintain sort order). insertIdx = ~insertIdx; return(true); } conn = default; insertIdx = default; return(false); }
public static void CloneTest(IRandomSource source) { new Generator(source, "CloneTest").UInt64(); var clone = source.Clone(); Assert.IsNotNull(source); var sourceNext = new ValueUnion(); var cloneNext = new ValueUnion(); for (int i = 0; i < 100; i++) { source.Next(ref sourceNext); clone.Next(ref cloneNext); Assert.AreEqual(sourceNext.UInt64_0, cloneNext.UInt64_0); } }
/// <summary> /// Randomly shuffles a sub-span of items within a list. /// </summary> /// <param name="list">The list to shuffle.</param> /// <param name="rng">Random number generator.</param> /// <param name="startIdx">The index of the first item in the segment.</param> /// <param name="endIdx">The index of the last item in the segment, i.e. endIdx is inclusive; the item at endIdx will participate in the shuffle.</param> public static void Shuffle <T>(IList <T> list, IRandomSource rng, int startIdx, int endIdx) { // Fisher–Yates shuffle. // https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle // Determine how many items in the list will be being shuffled int itemCount = (endIdx - startIdx); for (int i = endIdx; i > startIdx; i--) { int swapIdx = startIdx + rng.Next((i - startIdx) + 1); T tmp = list[swapIdx]; list[swapIdx] = list[i]; list[i] = tmp; } }
/// <summary> /// Randomly shuffles a sub-span of items within a list. /// </summary> /// <param name="list">The list to shuffle.</param> /// <param name="rng">Random number generator.</param> /// <param name="startIdx">The index of the first item in the segment.</param> /// <param name="endIdx">The index of the last item in the segment, i.e. endIdx is inclusive; the item at endIdx will participate in the shuffle.</param> public static void Shuffle <T>(IList <T> list, IRandomSource rng, int startIdx, int endIdx) { // Determine how many items in the list will be being shuffled int itemCount = (endIdx - startIdx); // This approach was suggested by Jon Skeet in a dotNet newsgroup post and // is also the technique used by the OpenJDK. The use of rnd.Next(i+1) introduces // the possibility of swapping an item with itself, I suspect the reasoning behind this // has to do with ensuring the probability of each possible permutation is approximately equal. for (int i = endIdx; i > startIdx; i--) { int swapIndex = startIdx + rng.Next((i - startIdx) + 1); T tmp = list[swapIndex]; list[swapIndex] = list[i]; list[i] = tmp; } }
public static void TestSpeciateAdd( int popSize, int inputNodeCount, int outputNodeCount, double connectionsProportion, IDistanceMetric <double> distanceMetric, ISpeciationStrategy <NeatGenome <double>, double> speciationStrategy, IRandomSource rng, bool validateNearestSpecies = true) { // Create population. NeatPopulation <double> neatPop = CreateNeatPopulation(popSize, inputNodeCount, outputNodeCount, connectionsProportion); // Split the population into three. int popSize1 = popSize / 3; int popSize2 = popSize / 3; int popSize3 = popSize - (popSize1 + popSize2); var genomeList1 = neatPop.GenomeList.GetRange(0, popSize1); var genomeList2 = neatPop.GenomeList.GetRange(popSize1, popSize2); var genomeList3 = neatPop.GenomeList.GetRange(popSize1 + popSize2, popSize3); for (int i = 0; i < 6; i++) { int speciesCount = rng.Next(1, (neatPop.GenomeList.Count / 4) + 1); var fullGenomeList = new List <NeatGenome <double> >(genomeList1); // Invoke speciation strategy, and run tests var speciesArr = speciationStrategy.SpeciateAll(genomeList1, speciesCount, rng); ValidationTests(speciesArr, distanceMetric, speciesCount, fullGenomeList, validateNearestSpecies); // Add second batch of genomes, and re-run tests. speciationStrategy.SpeciateAdd(genomeList2, speciesArr, rng); fullGenomeList.AddRange(genomeList2); ValidationTests(speciesArr, distanceMetric, speciesCount, fullGenomeList, validateNearestSpecies); // Add third batch of genomes, and re-run tests. speciationStrategy.SpeciateAdd(genomeList3, speciesArr, rng); fullGenomeList.AddRange(genomeList3); ValidationTests(speciesArr, distanceMetric, speciesCount, fullGenomeList, validateNearestSpecies); } }
/// <summary>Generates a sequence of integral numbers within a specified range and in random order.</summary> /// <param name="start">The value of the first integer in the sequence.</param> /// <param name="count">The number of sequential integers to generate.</param> /// <param name="rng">Random source.</param> /// <returns>A new IEnumerable{int}.</returns> public static IEnumerable <int> RangeRandomOrder(int start, int count, IRandomSource rng) { if (count < 0 || (((long)start + count) - 1L) > int.MaxValue) { throw new ArgumentOutOfRangeException(nameof(count)); } // Initialise an array of all indexes to be yielded. int[] arr = ArrayPool <int> .Shared.Rent(count); try { for (int i = 0; i < count; i++) { arr[i] = start + i; } // Yield all values in turn, applying a Fisher–Yates shuffle as we go in order to randomize the yield order. // See https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle for (int i = count - 1; i > 0; i--) { // Select at random from the remaining available slots. int selectIdx = rng.Next(i + 1); // Store the yield value. int tmp = arr[selectIdx]; // Replace the selected slot value with a value that has not yet been selected. // This is half of the Fisher–Yates swap, but since we don't need the final // shuffled array we can omit moving the yielded value into its new slot. arr[selectIdx] = arr[i]; // Yield the value from the randomly selected slot. yield return(tmp); } // Yield final value. yield return(arr[0]); } finally { ArrayPool <int> .Shared.Return(arr); } }
/// <summary> /// Randomly shuffles a sub-span of items within a list. /// </summary> /// <param name="list">The list to shuffle.</param> /// <param name="rng">Random number generator.</param> /// <param name="startIdx">The index of the first item in the segment.</param> /// <param name="endIdx">The index of the last item in the segment, i.e. endIdx is inclusive; the item at endIdx will participate in the shuffle.</param> /// <typeparam name="T">The list element type.</typeparam> public static void Shuffle <T>(IList <T> list, IRandomSource rng, int startIdx, int endIdx) { // Invoke the faster Span overload if the IList is an array. if (list is T[] arr) { SortUtils.Shuffle(arr.AsSpan().Slice(startIdx, (endIdx - startIdx) + 1), rng); return; } // Fisher–Yates shuffle. // https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle for (int i = endIdx; i > startIdx; i--) { int swapIdx = startIdx + rng.Next((i - startIdx) + 1); T tmp = list[swapIdx]; list[swapIdx] = list[i]; list[i] = tmp; } }
/// <summary> /// Randomly shuffles the items of a list. /// </summary> /// <param name="list">The list to shuffle.</param> /// <param name="rng">Random number generator.</param> /// <typeparam name="T">The list element type.</typeparam> public static void Shuffle <T>(IList <T> list, IRandomSource rng) { // Invoke the faster Span overload if the IList is an array. if (list is T[] arr) { SortUtils.Shuffle <T>(arr, rng); return; } // Fisher–Yates shuffle. // https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle for (int i = list.Count - 1; i > 0; i--) { int swapIdx = rng.Next(i + 1); T tmp = list[swapIdx]; list[swapIdx] = list[i]; list[i] = tmp; } }
/// <summary> /// Create a new child genome from a given parent genome. /// </summary> /// <param name="parent">The parent genome.</param> /// <param name="rng">Random source.</param> /// <returns>A new child genome.</returns> public NeatGenome <T>?CreateChildGenome(NeatGenome <T> parent, IRandomSource rng) { // We require at least two connections in the parent, i.e. we avoid creating genomes with // no connections, which would be pointless. if (parent.ConnectionGenes.Length < 2) { return(null); } // Select a gene at random to delete. var parentConnArr = parent.ConnectionGenes._connArr; var parentWeightArr = parent.ConnectionGenes._weightArr; int parentLen = parentConnArr.Length; int deleteIdx = rng.Next(parentLen); // Create the child genome's ConnectionGenes object. int childLen = parentLen - 1; var connGenes = new ConnectionGenes <T>(childLen); var connArr = connGenes._connArr; var weightArr = connGenes._weightArr; // Copy genes up to deleteIdx. Array.Copy(parentConnArr, connArr, deleteIdx); Array.Copy(parentWeightArr, weightArr, deleteIdx); // Copy remaining genes (if any). Array.Copy(parentConnArr, deleteIdx + 1, connArr, deleteIdx, childLen - deleteIdx); Array.Copy(parentWeightArr, deleteIdx + 1, weightArr, deleteIdx, childLen - deleteIdx); // Get an array of hidden node IDs. var hiddenNodeIdArr = GetHiddenNodeIdArray(parent, deleteIdx, connArr); // Create and return a new genome. return(_genomeBuilder.Create( _genomeIdSeq.Next(), _generationSeq.Peek, connGenes, hiddenNodeIdArr)); }