Пример #1
0
        private GroupBoundsLeastEnlarged pickNext(IList <IBoundable <IExtents> > entries,
                                                  ComputationExtents group1Bounds,
                                                  ComputationExtents group2Bounds,
                                                  out IBoundable <IExtents> entry)
        {
            Double maxArealDifference          = -1;
            GroupBoundsLeastEnlarged group     = GroupBoundsLeastEnlarged.Tie;
            IBoundable <IExtents>    nextEntry = null;

            foreach (IBoundable <IExtents> e in entries)
            {
                ComputationExtents bounds     = new ComputationExtents(e.Bounds);
                ComputationExtents group1Join = bounds.Union(group1Bounds);
                ComputationExtents group2Join = bounds.Union(group2Bounds);

                Double arealDifferenceGroup1 = Math.Abs(
                    group1Join.Area - group1Bounds.Area);

                Double arealDifferenceGroup2 = Math.Abs(
                    group2Join.Area - group2Bounds.Area);

                Double differenceInAreas = Math.Abs(arealDifferenceGroup1 - arealDifferenceGroup2);

                if (differenceInAreas > maxArealDifference)
                {
                    maxArealDifference = differenceInAreas;
                    nextEntry          = e;

                    if (arealDifferenceGroup1 < arealDifferenceGroup2)
                    {
                        group = GroupBoundsLeastEnlarged.Group1;
                    }
                    else if (arealDifferenceGroup2 < arealDifferenceGroup1)
                    {
                        group = GroupBoundsLeastEnlarged.Group2;
                    }
                }
            }

            entries.Remove(nextEntry);
            entry = nextEntry;
            return(group);
        }
Пример #2
0
            private GroupBoundsLeastEnlarged pickNext(IList <IBoundable <TBounds> > entries,
                                                      TBounds group1Bounds,
                                                      TBounds group2Bounds,
                                                      out TItem entry)
            {
                Double maxArealDifference      = -1;
                GroupBoundsLeastEnlarged group = GroupBoundsLeastEnlarged.Tie;
                TItem nextEntry = default(TItem);

                foreach (TItem e in entries)
                {
                    TBounds bounds     = (TBounds)e.Bounds.Clone();
                    TBounds group1Join = (TBounds)bounds.Union(group1Bounds);
                    TBounds group2Join = (TBounds)bounds.Union(group2Bounds);

                    Double arealDifferenceGroup1 = Math.Abs(
                        Area(group1Join) - Area(group1Bounds));

                    Double arealDifferenceGroup2 = Math.Abs(
                        Area(group2Join) - Area(group2Bounds));

                    Double differenceInAreas = Math.Abs(arealDifferenceGroup1 - arealDifferenceGroup2);

                    if (differenceInAreas > maxArealDifference)
                    {
                        maxArealDifference = differenceInAreas;
                        nextEntry          = e;

                        if (arealDifferenceGroup1 < arealDifferenceGroup2)
                        {
                            group = GroupBoundsLeastEnlarged.Group1;
                        }
                        else if (arealDifferenceGroup2 < arealDifferenceGroup1)
                        {
                            group = GroupBoundsLeastEnlarged.Group2;
                        }
                    }
                }

                entries.Remove(nextEntry);
                entry = nextEntry;
                return(group);
            }
Пример #3
0
        private void distribute(IList <IBoundable <IExtents> > entries,
                                IBoundable <IExtents>[] group1,
                                IBoundable <IExtents>[] group2,
                                IndexBalanceHeuristic heuristic,
                                ref Int32 group1Count,
                                ref Int32 group2Count)
        {
            // recursion halting case #1
            if (entries.Count == 0)
            {
                return;
            }

            // recursion halting case #2
            if (group1Count == heuristic.TargetNodeCount ||
                group2Count == heuristic.TargetNodeCount)
            {
                return;
            }

            IBoundable <IExtents> entry;
            ComputationExtents    group1Bounds = computeBounds(group1, group1Count);
            ComputationExtents    group2Bounds = computeBounds(group2, group2Count);

            GroupBoundsLeastEnlarged group = pickNext(entries, group1Bounds,
                                                      group2Bounds, out entry);

            switch (group)
            {
            case GroupBoundsLeastEnlarged.Group1:
                group1[group1Count++] = entry;
                break;

            case GroupBoundsLeastEnlarged.Group2:
                group2[group2Count++] = entry;
                break;

            case GroupBoundsLeastEnlarged.Tie:
                Double group1BoundsArea = group1Bounds.Area;
                Double group2BoundsArea = group2Bounds.Area;

                if (group1BoundsArea < group2BoundsArea)
                {
                    group1[group1Count++] = entry;
                }
                else if (group2BoundsArea < group1BoundsArea)
                {
                    group2[group2Count++] = entry;
                }
                else if (group1Count < group2Count)
                {
                    group1[group1Count++] = entry;
                }
                else if (group2Count < group1Count)
                {
                    group2[group2Count++] = entry;
                }
                else if (_random.Next(0, 2) == 0)     // generates 0 or 1 randomly
                {
                    group1[group1Count++] = entry;
                }
                else
                {
                    group2[group2Count++] = entry;
                }

                break;

            default:
                throw new InvalidOperationException("Unknown group.");
            }

            distribute(entries, group1, group2, heuristic, ref group1Count, ref group2Count);
        }