private static int GetEstimatedNumberOfLinks_Final(int brainCount, int ioCount, ItemLinker_ExtraArgs extra)
 {
     return -1;
 }
Esempio n. 2
0
        private static Tuple<int, int>[] Link12_Extra(Tuple<int, int>[] initial, LinkItem[] items1, LinkItem[] items2, DistributeDistances distances, ItemLinker_ExtraArgs extraArgs)
        {
            Random rand = StaticRandom.GetRandomForThread();

            int wholePercent = extraArgs.Percent.ToInt_Floor();

            List<int> addOrder = new List<int>();

            if (extraArgs.BySize)
            {
                double totalSize = items2.Sum(o => o.Size);
                double maxSize = extraArgs.Percent * totalSize;
                double usedSize = 0;

                if (extraArgs.EvenlyDistribute)
                {
                    #region by size, evenly distribute

                    // Add some complete passes if over 100% percent
                    for (int cntr = 0; cntr < wholePercent; cntr++)
                    {
                        addOrder.AddRange(UtilityCore.RandomRange(0, items2.Length));
                    }

                    usedSize = wholePercent * totalSize;

                    #endregion
                }

                #region by size, distribute the rest

                //NOTE: Building this list by size so that larger items have a higher chance of being chosen
                var bySize = items2.
                    Select((o, i) => Tuple.Create(i, o.Size / totalSize)).
                    OrderByDescending(o => o.Item2).
                    ToArray();

                // Keep selecting items unti the extra size is consumed (or if no more can be added)
                while (true)
                {
                    bool foundOne = false;

                    for (int cntr = 0; cntr < 1000; cntr++)     // this is an infinite loop detector
                    {
                        int attemptIndex = UtilityCore.GetIndexIntoList(rand.NextDouble(), bySize);     // get the index into the list that the rand percent represents
                        attemptIndex = bySize[attemptIndex].Item1;      // get the index into items2

                        if (items2[attemptIndex].Size + usedSize <= maxSize)
                        {
                            foundOne = true;
                            usedSize += items2[attemptIndex].Size;
                            addOrder.Add(attemptIndex);
                            break;
                        }
                    }

                    if (!foundOne)
                    {
                        // No more will fit
                        break;
                    }
                }

                #endregion
            }
            else
            {
                if (extraArgs.EvenlyDistribute)
                {
                    #region ignore size, evenly distribute

                    // Add some complete passes if over 100% percent
                    for (int cntr = 0; cntr < wholePercent; cntr++)
                    {
                        addOrder.AddRange(UtilityCore.RandomRange(0, items2.Length));
                    }

                    // Add some items based on the portion of percent that is less than 100%
                    int remainder = (items2.Length * (extraArgs.Percent - wholePercent)).
                        ToInt_Round();

                    addOrder.AddRange(UtilityCore.RandomRange(0, items2.Length, remainder));

                    #endregion
                }
                else
                {
                    #region ignore size, randomly distribute

                    int totalCount = (items2.Length * extraArgs.Percent).
                        ToInt_Round();

                    //NOTE: UtilityCore.RandomRange stops when the list is exhausted, and makes sure not to have dupes.  That's not what is wanted
                    //here.  Just randomly pick X times
                    addOrder.AddRange(Enumerable.Range(0, totalCount).Select(o => rand.Next(items2.Length)));

                    #endregion
                }
            }

            return AddLinks(items1, items2, distances, addOrder, initial);
        }
        private void btn3DLinksBrainIO_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                PrepFor3D();
                ClearTempVisuals();

                LinkItem[] brains = _brains3D.
                    Select(o => new LinkItem(o.Position.Value, o.Size)).
                    ToArray();

                LinkItem[] io = _inputs3D.
                    Concat(_outputs3D).
                    Select(o => new LinkItem(o.Position.Value, o.Size)).
                    ToArray();

                ItemLinker_OverflowArgs overflowArgs = new ItemLinker_OverflowArgs()
                {
                    LinkResistanceMult = trk3DLinkResistMult.Value,
                };

                ItemLinker_ExtraArgs extraArgs = null;
                if (!trk3DExtraLinkPercent.Value.IsNearZero())
                {
                    extraArgs = new ItemLinker_ExtraArgs()
                    {
                        Percent = trk3DExtraLinkPercent.Value / 100d,
                        BySize = chk3DExtraLinkBySize.IsChecked.Value,
                        EvenlyDistribute = chk3DExtraLinkEvenDistribute.IsChecked.Value,
                    };
                }

                Tuple<int, int>[] links = ItemLinker.Link_1_2(brains, io, overflowArgs, extraArgs);

                // Draw
                _linksIO3D.AddRange(DrawBrainIOLinks3D(_viewportFull, links, _brains3D.ToArray(), _inputs3D.Concat(_outputs3D).ToArray(), _ioLinkColor, chk3DRainbowLinks.IsChecked.Value));
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString(), this.Title, MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }
Esempio n. 4
0
        /// <summary>
        /// Every item in 2 will have at least one link to a 1.  There could be some item1s that don't have a link
        /// </summary>
        /// <param name="overflowArgs">
        /// Item2s get matched to the nearest Item1.
        /// If this args is null then, it stays that way.
        /// If this is populated, then links will move from burdened item1s to less burdened
        /// </param>
        /// <returns>
        /// Item1=index into item1 list
        /// Item2=index into item2 list
        /// </returns>
        public static Tuple<int, int>[] Link_1_2(LinkItem[] items1, LinkItem[] items2, ItemLinker_OverflowArgs overflowArgs = null, ItemLinker_ExtraArgs extraArgs = null)
        {
            if (items1 == null || items2 == null || items1.Length == 0 || items2.Length == 0)
            {
                return new Tuple<int, int>[0];
            }

            Tuple<int, int>[] retVal = null;

            if (overflowArgs == null)
            {
                // Just link to the closest
                retVal = Link12_Closest(items1, items2);
            }

            if (overflowArgs == null && extraArgs == null)
            {
                // Nothing special to do, exit early
                return retVal;
            }

            DistributeDistances distances = GetDistances(items1, items2, overflowArgs);

            if (overflowArgs != null)
            {
                // Consider item1s burden when linking them
                retVal = Link12_Distribute(items1, items2, distances);
            }

            if (extraArgs != null)
            {
                // Add more links
                retVal = Link12_Extra(retVal, items1, items2, distances, extraArgs);
            }

            return retVal;
        }