コード例 #1
0
        /// <summary>
        /// Find the closest collection more than ValueThreshold.
        /// </summary>
        /// <param name="Items"></param>
        /// <param name="WeightThreshold"></param>
        /// <returns></returns>
        public static WeightNode FindItemCollectionWithMostMatchValue(IEnumerable <Item> Items, double WeightThreshold)
        {
            int        i;
            int        numOfMoreThanThreshold = 0;
            const int  BEST_SOLUTION_NUM      = 3;
            double     maxWeight = 0.0;
            WeightNode dummy     = new WeightNode()
            {
                _Value = 0.0, _Weight = 0.0
            };
            LinkedList <WeightNode>     retList       = new LinkedList <WeightNode>();
            LinkedListNode <WeightNode> node          = null;
            LinkedListNode <WeightNode> moreWeighNode = null;

            retList.AddLast(dummy);
            foreach (Item g in Items)
            {
                for (i = 0; i < g.Number; i++)
                {
                    node          = retList.Last;
                    moreWeighNode = retList.Last;
                    maxWeight     = retList.Last.Value._Weight;
                    while (node != null)
                    {
                        double totalWeight = node.Value._Weight + g.Weight;
                        while (moreWeighNode != null)
                        {
                            if (Math.Abs(totalWeight - moreWeighNode.Value._Weight) < 0.001)
                            {
                                if (node.Value._Value + g.Value > moreWeighNode.Value._Value)
                                {
                                    // employ the current node + the current grocery
                                    WeightNode wn = new WeightNode(node.Value);
                                    wn.AddItem(g);
                                    moreWeighNode.Value = wn;
                                }
                                break;
                            }
                            else if (totalWeight < moreWeighNode.Value._Weight)
                            {
                                moreWeighNode = moreWeighNode.Previous;
                            }
                            else if (totalWeight > moreWeighNode.Value._Weight)
                            {
                                if ((totalWeight < maxWeight) || (totalWeight < WeightThreshold) ||
                                    ((totalWeight > WeightThreshold) && (numOfMoreThanThreshold < BEST_SOLUTION_NUM)))
                                {
                                    WeightNode wn = new WeightNode(node.Value);
                                    wn.AddItem(g);
                                    retList.AddAfter(moreWeighNode, new LinkedListNode <WeightNode>(wn));
                                    moreWeighNode = moreWeighNode.Next;
                                    if (totalWeight > WeightThreshold)
                                    {
                                        if (numOfMoreThanThreshold > BEST_SOLUTION_NUM)
                                        {
                                            retList.RemoveLast();
                                        }
                                        else
                                        {
                                            numOfMoreThanThreshold++;
                                        }
                                    }
                                    maxWeight = retList.Last.Value._Weight;
                                }
                                break;
                            }
                        }
                        node = node.Previous;
                    }
                }
            }
            return(retList.First(o => (o._Weight >= WeightThreshold)));
        }
コード例 #2
0
        /// <summary>
        /// Select some grocery from Groceries and make sure
        /// 1. the total weight is less than MaxWeight
        /// 2. the total value is highest.
        ///
        /// </summary>
        /// <param name="Groceries"></param>
        /// <param name="MaxWeight"></param>
        /// <returns></returns>
        public static WeightNode Process(IEnumerable <Item> Groceries, double MaxWeight)
        {
            /*
             * (Value/Weight)
             *
             * retList
             * |
             * +- dummy (0.0/0.0)
             * |
             * +- WeightNode (V/W) --> Item0 -> Item1 -> ... -> ItemN
             * |
             * + ...
             * |
             * +- WeightNode (V/Capacity) -> Item0 -> Item1 -> ... ItemN
             *
             */
            int        i;
            WeightNode dummy = new WeightNode()
            {
                _Value = 0.0, _Weight = 0.0
            };
            LinkedList <WeightNode>     retList       = new LinkedList <WeightNode>();
            LinkedListNode <WeightNode> node          = null;
            LinkedListNode <WeightNode> moreWeighNode = null;

            retList.AddLast(dummy);
            foreach (Item g in Groceries)
            {
                for (i = 0; i < g.Number; i++)
                {
                    node          = retList.Last;
                    moreWeighNode = retList.Last;
                    while (node != null)
                    {
                        double totalWeight = node.Value._Weight + g.Weight;
                        if (totalWeight <= MaxWeight)
                        {
                            while (moreWeighNode != null)
                            {
                                if (Math.Abs(totalWeight - moreWeighNode.Value._Weight) < 0.001)
                                {
                                    if (node.Value._Value + g.Value > moreWeighNode.Value._Value)
                                    {
                                        // employ the current node + the current grocery
                                        WeightNode wn = new WeightNode(node.Value);
                                        wn.AddItem(g);
                                        moreWeighNode.Value = wn;
                                    }
                                    break;
                                }
                                else if (totalWeight < moreWeighNode.Value._Weight)
                                {
                                    moreWeighNode = moreWeighNode.Previous;
                                }
                                else if (totalWeight > moreWeighNode.Value._Weight)
                                {
                                    WeightNode wn = new WeightNode(node.Value);
                                    wn.AddItem(g);
                                    //moreWeighNode.AddGrocery(g);
                                    retList.AddAfter(moreWeighNode, new LinkedListNode <WeightNode>(wn));
                                    moreWeighNode = moreWeighNode.Next;
                                    break;
                                }
                            }
                        }
                        node = node.Previous;
                    }
                }
            }
            double maxValue = retList.Max(o => o._Value);

            return(retList.Last(o => (o._Value == maxValue)));
        }