Beispiel #1
0
        /// <summary>
        /// Test closest more than value threshold problem.
        /// </summary>
        public void TestCase2()
        {
            const double KNAPSACK_CAPACITY = 300;

            const int ITEM_NUM = 16;

            double[] weight = new double[ITEM_NUM] {
                355, 367, 192, 100, 228, 456, 2714, 157, 151.9, 53, 98, 210, 111, 266, 276, 94
            };
            double[] price = new double[ITEM_NUM] {
                1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0
            };

            int i = 0;

            foreach (double w in weight)
            {
                if ((i++ % 4) == 0)
                {
                    Console.Write("\n");
                }
                Console.Write("  {0,7},", w.ToString("F2"));
            }
            List <Item> l = KnapsackSol.GenerateItems(weight, price);

            do
            {
                Console.WriteLine("\nPlease input a number as capacity ('Q' to quit):");
                string str = Console.ReadLine();

                double capacity;
                if (false == double.TryParse(str, out capacity))
                {
                    if (str.CompareTo("Q") == 0)
                    {
                        Console.WriteLine("You quit the program!");
                        break;
                    }
                    else
                    {
                        Console.WriteLine("Can't recognize the input number: {0}", str);
                        continue;
                    }
                }
                else
                {
                    WeightNode wn = KnapsackSol.FindItemCollectionWithMostMatchValue(l, capacity);
                    if (wn != null)
                    {
                        Console.WriteLine(wn.ToString());
                    }
                    else
                    {
                        Console.WriteLine("No solution!");
                    }
                }
            } while (true);
        }
Beispiel #2
0
        /// <summary>
        /// Test 0-1 knapsack problem with random values and weights.
        /// </summary>
        public void TestCase0()
        {
            const int    TOTAL_ITEMS_NUM = 20;
            const double WEIGHT_MEAN     = 4.0;
            const double VALUE_MEAN      = 10.0;
            const double CAPACITY        = 40.0;

            var        v  = KnapsackSol.GenerateGroceries(TOTAL_ITEMS_NUM, WEIGHT_MEAN, VALUE_MEAN, 1);
            WeightNode wn = KnapsackSol.Process(v, CAPACITY);

            Console.WriteLine(wn.ToString());
        }
Beispiel #3
0
        /// <summary>
        /// Test 0-1 knapsack problem with fixed values and weights.
        /// </summary>
        public void TestCase1()
        {
            const int    ITEM_NUM          = 10;
            const double KNAPSACK_CAPACITY = 30;

            double[] weight = new double[ITEM_NUM] {
                1, 9, 3, 6, 5, 4, 7, 2, 8, 10
            };
            double[] price = new double[ITEM_NUM] {
                2, 8, 9, 4, 7, 3, 1, 6, 5, 10
            };
            List <Item> l  = KnapsackSol.GenerateItems(weight, price);
            WeightNode  wn = KnapsackSol.Process(l, KNAPSACK_CAPACITY);

            Console.Write(wn.ToString());
        }
Beispiel #4
0
 public WeightNode(WeightNode node)
 {
     _Value  = node._Value;
     _Weight = node._Weight;
     ItemsList.AddRange(node.ItemsList);
 }
Beispiel #5
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)));
        }
Beispiel #6
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)));
        }