示例#1
0
        public override void Start(CancellationToken token, Action <double> action)
        {
            double minPathLength = double.MaxValue;

            int[]     minSequence = null;
            const int selected    = 2;

            GeneralRepresentation representation  = new GeneralRepresentation(_startPermutation.Length, selected);
            IndexEnumerator       indexEnumerator = new IndexEnumerator(representation);

            int[] currentSequence = _startPermutation.ToArray();

            while (!token.IsCancellationRequested)
            {
                // One local ring
                do
                {
                    // Forcing delay for visualization
                    if (_config.UseDelay)
                    {
                        Thread.Sleep(_config.DelayTime);
                    }

                    Helper.SwapPositions(currentSequence, indexEnumerator.CurrentCombination.Elements);
                    var currentPathLength = _euclideanPath.GetPathLength(currentSequence, ClosedPath);

                    if (currentPathLength < minPathLength)
                    {
                        minPathLength = currentPathLength;
                        action?.Invoke(minPathLength);
                        minSequence = currentSequence.ToArray();
                        _optimalSequence.OnNext(minSequence);

                        // Stop on first optimum, something like greedy strategy
                        break;
                    }
                    else
                    {
                        Helper.SwapPositions(currentSequence, indexEnumerator.CurrentCombination.Elements);
                    }
                } while (indexEnumerator.SetNext());

                // Continue on new ring starting from minimum path length of ancestor ring
                representation  = new GeneralRepresentation(_startPermutation.Length, selected);
                indexEnumerator = new IndexEnumerator(representation);
            }

            _optimalSequence.OnCompleted();
        }
示例#2
0
        protected override void DoInference()
        {
            var matrix = Param;

            var sizes1 = matrix.Sizes.ToList();
            var sizes2 = matrix.Vectors[0].Sizes.ToList();

            var             c = 0;
            List <int>      enumSize;
            IndexEnumerator enumerator;
            Matrix <T>      result;

            switch (Mode)
            {
            case UnwrapMode.Discrete:

                enumSize = sizes1.ToList();
                enumSize.AddRange(sizes2);

                result     = new Matrix <T>(enumSize);
                enumerator = new IndexEnumerator(enumSize);

                while (enumerator.MoveNext())
                {
                    var subMatrix = matrix[enumerator.Current.Take(matrix.DimensionCount)];
                    var vector    = subMatrix[enumerator.Current.Skip(matrix.DimensionCount)];
                    result.Vectors[c] = vector;
                    c++;
                }

                Output = result;

                break;

            case UnwrapMode.Expand:

                enumSize = sizes1.ToList();
                var finalSizes = sizes1.ToList();

                while (finalSizes.Count < sizes2.Count)
                {
                    finalSizes.Add(1);
                }

                for (var i = 0; i < sizes2.Count; i++)
                {
                    finalSizes[finalSizes.Count - sizes2.Count + i] *= sizes2[i];
                }

                result = new Matrix <T>(finalSizes);

                for (var i = 0; i < sizes2.Count; i++)
                {
                    var size1Index = Math.Max(0, enumSize.Count - sizes2.Count) + i;
                    enumSize.Insert(size1Index + 1, sizes2[i]);
                }

                enumerator = new IndexEnumerator(enumSize);

                while (enumerator.MoveNext())
                {
                    List <int> topIndex;
                    List <int> subIndex;

                    if (sizes1.Count > sizes2.Count)
                    {
                        topIndex = enumerator.Current.Take(sizes1.Count - sizes2.Count).ToList();

                        topIndex.AddRange(enumerator.Current.Skip(sizes1.Count - sizes2.Count)
                                          .Where((element, index) => index % 2 == 0));

                        subIndex = enumerator.Current.Skip(sizes1.Count - sizes2.Count)
                                   .Where((element, index) => index % 2 == 1).ToList();
                    }
                    else
                    {
                        topIndex = enumerator.Current.Where((element, index) => index % 2 == 0).Take(sizes1.Count).ToList();
                        subIndex = enumerator.Current.Where((element, index) => index % 2 == 1).ToList();

                        subIndex.AddRange(enumerator.Current.Skip(sizes1.Count * 2));
                    }



                    var subMatrix = matrix[topIndex];
                    var vector    = subMatrix[subIndex];
                    result.Vectors[c] = vector;
                    c++;
                }

                Output = result;


                break;

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
示例#3
0
        protected override void DoInference()
        {
            var matrix = Left;
            var other  = Right;

            // Checks that two matrices have the same number of dimensions
            if (matrix.DimensionCount != other.DimensionCount)
            {
                throw new InvalidOperationException("The two matrixes must have the same number of dimensions");
            }

            // Gets the sizes of the dimensions (other than the concatenated dimension)
            // And checks that they're all of the same size

            var sizeA = matrix.Sizes.Where((element, index) => index != DimensionIndex);
            var sizeB = other.Sizes.Where((element, index) => index != DimensionIndex);

            if (!sizeA.SequenceEqual(sizeB))
            {
                throw new InvalidOperationException(
                          $"The arrays must be of same size in all other dimensions than {DimensionIndex}");
            }

            if (matrix.DimensionCount < DimensionIndex)
            {
                throw new InvalidOperationException(
                          $"The matrixes are of dimension {matrix.DimensionCount}, cannot concatenate on dimension {DimensionIndex}. Max possible value is {matrix.DimensionCount}");
            }

            // The resulting matrix size
            var resultSizes = matrix.Sizes.ToList();

            // DimensionIndex < 0
            if (DimensionIndex < 0)
            {
                // In this case, we add dimensions "before"
                var intermediarySizes = Enumerable.Repeat(1, DimensionIndex * -1 - 1).ToList();
                intermediarySizes.Insert(0, 2);

                intermediarySizes.AddRange(resultSizes);
                resultSizes = intermediarySizes;
            }

            else
            // Otherwise, we add the two dimension sizes for the corresponding index
            {
                resultSizes[DimensionIndex] = resultSizes[DimensionIndex] + other.Sizes.ElementAt(DimensionIndex);
            }


            // The resulting matrix
            var result = new Matrix <T>(resultSizes);

            // We create an enumerator to iterate through our indices
            var indexEnumerator = new IndexEnumerator(resultSizes);

            if (DimensionIndex < 0)
            {
                for (var i = 0; i < matrix.VectorCount; i++)
                {
                    result.Vectors[i] = matrix.Vectors[i];
                }

                for (var i = matrix.VectorCount; i < matrix.VectorCount + other.VectorCount; i++)
                {
                    result.Vectors[i] = other.Vectors[i - matrix.VectorCount];
                }

                Output = result;
                return;
            }

            while (indexEnumerator.MoveNext())
            {
                var currentIndexes  = indexEnumerator.Current.ToList();
                var fromMatrixIndex = currentIndexes.ToList();

                Matrix <T> fromMatrix;

                if (DimensionIndex == -1)
                {
                    switch (currentIndexes[0])
                    {
                    case 0:
                        fromMatrix = matrix;
                        fromMatrixIndex.RemoveAt(0);
                        break;

                    case 1:
                        fromMatrix = other;
                        fromMatrixIndex.RemoveAt(0);
                        break;

                    default:
                        throw new ArgumentOutOfRangeException();
                    }
                }
                else if (currentIndexes.ElementAt(DimensionIndex) >= matrix.Sizes.ElementAt(DimensionIndex))
                {
                    fromMatrix = other;
                    fromMatrixIndex[DimensionIndex] =
                        currentIndexes[DimensionIndex] - matrix.Sizes.ElementAt(DimensionIndex);
                }
                else
                {
                    fromMatrix = matrix;
                }

                result[currentIndexes] = fromMatrix[fromMatrixIndex];
            }

            Output = result;
        }
示例#4
0
 internal ElementEnumerator(ref NativeArray <T> slice)
 {
     Slice           = slice;
     IndexEnumerator = new IndexEnumerator <T>(ref slice);
 }
示例#5
0
        protected override void DoInference()
        {
            var matrix = Param;

            // The size of the "from" dimension
            var sizeFrom = matrix.Sizes.ElementAt(DimensionFrom);

            // The size of the "to" dimension
            var sizeTo = matrix.Sizes.ElementAt(DimensionTo);

            // The final size of the "to" dimension, after flattening
            var finalSizeTo = sizeTo * sizeFrom;

            // The final size of the resulting matrix
            var finalSizes = new List <int>(matrix.Sizes)
            {
                [DimensionTo] = finalSizeTo
            };

            finalSizes.RemoveAt(DimensionFrom);

            // The strategy here is quite simple.
            //
            // Our goal is to provide a new matrix that corresponds to the given
            // matrix with the "from" dimension flattened into the "two" dimension.
            //
            // Examples of flattening on a 3x3x3 matrix (read cube)
            // We can flatten the 3rd dimension into the 1st (lose width, gain depth)
            // We can flatten the 3rd dimension into the 2nd (lose width, gain height)
            // We can flatten the 2nd dimension into the 1st (lose height, gain depth)
            // We can flatten the 2nd dimension into the 3rd (lose height, gain width)
            // We can flatten the 1st dimension into the 1st (lose depth, gain width)
            // We can flatten the 1st dimension into the 3rd (lose depth, gain height)
            //
            // So we will have to do some kind of loop through our vectors. But in what order?
            //
            // Normally, when we iterate through a matrix, we do it
            // from the innermost dimension, towards the outermost dimension.
            // Eg. 000 -> 001 -> 010 -> 011 ...
            //
            // We will use the same strategy, but we will reorder the dimensions first.
            // Then we will iterate in the same way, but with our reordered dimensions.
            // So our initial dimensions are 0,1,2,3, ...
            //
            // If we want to flatten the 3rd dimension into the 1st dimension, our
            // ordering will be like so : 0,1,2,3 => 2,0,1,3 (or 0,2,1,3 depending on the flattening mode)
            //
            // We will create an iterator that will iterate through those indices like
            // they were normal indices, but we will then use a map between our reordered index
            // and our actual index to access the vectors in the desired order.

            // This will contain the reordered indexes
            var reorderedIndexes = new List <int>();

            for (var i = 0; i < matrix.DimensionCount; i++)
            {
                reorderedIndexes.Add(i);
            }
            reorderedIndexes.RemoveAt(DimensionFrom);

            // This contains the index of the "to" dimension in our reordered index list
            var toOrderIndex = reorderedIndexes.IndexOf(DimensionTo);

            // Double dispatch, depending on mode
            switch (Mode)
            {
            case FlattenMode.Interpose:
                reorderedIndexes.Insert(toOrderIndex + 1, DimensionFrom);
                break;

            case FlattenMode.Extend:
                reorderedIndexes.Insert(toOrderIndex, DimensionFrom);
                break;

            default:
                throw new ArgumentOutOfRangeException(nameof(Mode), Mode, null);
            }

            // This contains the sizes of the dimension, in respect to our reordered indices
            var reorderedSizes = reorderedIndexes.Select(i => matrix.Sizes.ElementAt(i)).ToList();

            // The enumartor that will iterate through these reordered indices
            var reorderedIndexEnumerator = new IndexEnumerator(reorderedSizes);

            // The resulting matrix
            var result = new Matrix <T>(finalSizes);

            // A counter, will help update the result matrix
            var c = 0;

            while (reorderedIndexEnumerator.MoveNext())
            {
                // We select both the index of the reordered dimension, as well as
                // it's current step within that dimension
                var normalized = reorderedIndexEnumerator.Current.ToList()
                                 .Select((element, index) => new { element, index })
                                 .ToList();

                // We sort in respect to the initial order of the dimensions
                normalized.Sort((left, right) => Comparer <int> .Default.Compare(reorderedIndexes[left.index], reorderedIndexes[right.index]));

                // We set the resulting matrix vector to this current vector
                result.Vectors[c] = matrix[normalized.Select(arg => arg.element)];

                c++;
            }

            Output = result;
        }