private int GetEstimatedValue(KnapsackItem[] ksItems)
        {
            var collectedWeight = 0;
            var estimatedValue = 0;
            var itemsByRatio = ksItems.OrderByDescending(k => Convert.ToDouble(k.Value) / Convert.ToDouble(k.Weight));

            foreach (var item in ksItems) item.EstimatedValue = item.Value;

            foreach (var item in itemsByRatio)
            {
                if (collectedWeight + item.Weight <= _capacity)
                {
                    collectedWeight += item.Weight;
                    estimatedValue += item.Value;
                    if (collectedWeight == _capacity) break;
                }
                else
                {
                    var percentOfItem = (_capacity - collectedWeight) / Convert.ToDouble(item.Weight);
                    var partialValue = Convert.ToInt32(percentOfItem*item.Value);
                    estimatedValue += partialValue;
                    item.EstimatedValue = partialValue;
                    break;
                }
            }
            return estimatedValue;
        }
        private void BuildTree(KnapsackNode node, KnapsackItem[] ksItems)
        {
            //if possible add contents of next ksitem to node
            //  if so recruse with remaining items
            //  if not determine if best and set if so

            //also, recurse with unchanged node items and remaining items

            if (ksItems.Length == 0) return;

            var item = ksItems.First();
            var newValue = node.AccumulatedValue + item.Value;
            var newWeight = node.AccumulatedWeight + item.Weight;
            var remainingCapacity = _capacity - newWeight;

            var rest = ksItems.Skip(1).ToArray();

            //if i was able to add something
            if (remainingCapacity >= 0)
            {
                var newNode = new KnapsackNode(newValue, newWeight);
                newNode.SelectedItems.AddRange(node.SelectedItems);
                newNode.SelectedItems.Add(item.Id);

                if (remainingCapacity > 0) BuildTree(newNode, rest);
                if (newNode.AccumulatedValue > _bestNode.AccumulatedValue) _bestNode = newNode;
            }

            //this is to use first node but not adding current item
            if (rest.Any(k => k.Weight + node.AccumulatedWeight <= _capacity) && (rest.Sum(k => k.Value) + node.AccumulatedValue) > _bestNode.AccumulatedValue)
            {
                BuildTree(node, rest);
            }
        }
        public void Execute(int capacity, KnapsackItem[] ksItems)
        {
            _capacity = capacity;

            for (var i = 0; i < ksItems.Length; i++)
            {
                var itemsToProcess = ksItems.Skip(i).ToArray();
                var estimatedValue = GetEstimatedValue(itemsToProcess);
                var firstItem = itemsToProcess.First();

                var firstNode = new KnapsackNode(firstItem.Value, firstItem.Weight, estimatedValue);
                firstNode.SelectedItems.Add(firstItem.Id);
                if (_bestNode == null) _bestNode = firstNode;

                if (estimatedValue <= _bestNode.AccumulatedValue) continue;

                var remaining = itemsToProcess.Skip(1).ToArray();
                BuildTree(firstNode, remaining);
            }

            foreach (var i in _bestNode.SelectedItems)
            {
                var ksItem = ksItems.Single(p => p.Id == i);
                ksItem.Selected = 1;
            }
        }
        public void Execute(int capacity, KnapsackItem[] ksItems)
        {
            var collectedWeight = 0;
            var itemsToUpdate = ksItems.OrderByDescending(k => Convert.ToDouble(k.Value) / Convert.ToDouble(k.Weight))
                                       .ToArray();

            foreach (var itemToUpdate in itemsToUpdate)
            {
                if (itemToUpdate.Weight + collectedWeight <= capacity)
                {
                    collectedWeight += itemToUpdate.Weight;
                    itemToUpdate.Selected = 1;
                }
                if (collectedWeight == capacity) break;
            }
        }
        public void Execute(int capacity, KnapsackItem[] ksItems)
        {
            _bestNode = new KnapsackNode(0, 0);
            _capacity = capacity;

            for (var i = 0; i < ksItems.Length; i++)
            {
                var itemsToProcess = ksItems.Skip(i).ToArray();
                var firstItem = itemsToProcess.First();

                var firstNode = new KnapsackNode(firstItem.Value, firstItem.Weight);
                firstNode.SelectedItems.Add(firstItem.Id);

                var remaining = itemsToProcess.Skip(1).ToArray();
                BuildTree(firstNode, remaining);
            }

            foreach (var i in _bestNode.SelectedItems)
            {
                var ksItem = ksItems.Single(p => p.Id == i);
                ksItem.Selected = 1;
            }
        }