private double CalcDifference(Variation solution, double sumWeightItem)
        {
            double difference = 0;
            foreach (Knapsack knapsack in solution.Knapsacks)
            {
                double knapsackWeightSum = knapsack.Items.Sum(i => i.Weight);
                difference += Math.Abs(knapsackWeightSum - sumWeightItem);
            }

            return difference;
        }
 public void AddKnapsack(Variation currentVariation, List<Knapsack> knapsacks)
 {
     if (currentVariation.Knapsacks == null)
     {
         currentVariation.Knapsacks = new List<Knapsack>();
     }
     foreach (var knapsack in knapsacks)
     {
         currentVariation.Knapsacks.Add(new Knapsack {Capacity = knapsack.Capacity, Items = new List<Item>(), Id = knapsack.Id});
     }
 }
 private static bool IsKnapsackAcceptables(Variation currentVariation)
 {
     bool acceptables = true;
     foreach (Knapsack knapsack in currentVariation.Knapsacks)
     {
         if (knapsack.Capacity < knapsack.Items.Sum(i => i.Weight))
         {
             acceptables = false;
         }
     }
     return acceptables;
 }
        public Variation FillFromSequence(Variation variation, List<Item> items, bool[] sequence)
        {
            int knapsackIndx = 0;
            int itemIndx = 0;

            foreach (var s in sequence)
            {
                if (knapsackIndx == variation.Knapsacks.Count)
                {
                    knapsackIndx = 0;
                    itemIndx++;
                }
                if (s)
                {
                    variation.Knapsacks[knapsackIndx].Items.Add(new Item { Id = items[itemIndx].Id, Weight = items[itemIndx].Weight });
                }
                knapsackIndx++;
            }
            return variation;
        }
        public Result TryCalculate()
        {
            int variationsCount = GetVariationsCount();

            double gMin = Double.MaxValue;
            var result = new Result {Acceptables = new List<Variation>(), ItemsCount = _calculate.Items.Count};
            var dtStart = DateTime.Now;

            for (int i = 0; i < variationsCount; i++)
            {
                var currentVariation = new Variation();
                _variationManager.AddKnapsack(currentVariation, _calculate.Knapsacks);

                _variationManager.FillFromSequence(currentVariation, _calculate.Items, SequenceHelper.GetSequence(i));

                if (IsOneItemInKnapsack(currentVariation, _calculate.Items)
                    && IsKnapsackAcceptables(currentVariation))
                {
                    double sumWeightItem = _calculate.Items.Sum(item => item.Weight) / _calculate.Knapsacks.Count;

                    currentVariation.G = CalcDifference(currentVariation, sumWeightItem);
                    result.Acceptables.Add(currentVariation);

                    if (currentVariation.G < gMin)
                    {
                        result.Optimal = currentVariation;
                        gMin = currentVariation.G;
                    }

                    if (_calculate.CalculateError > 0
                        && IsAcceptablesCalculateError(currentVariation.G, _calculate.CalculateError, sumWeightItem))
                    {
                        break;
                    }
                }
            }
            result.RunTime = new TimeSpan(DateTime.Now.Ticks-dtStart.Ticks).TotalMilliseconds;
            return result;
        }
 private bool IsOneItemInKnapsack(Variation currentVariation, IEnumerable<Item> items)
 {
     foreach (Item item in items)
     {
         int use = 0;
         foreach (Knapsack knapsack in currentVariation.Knapsacks)
         {
             use += knapsack.Items.Count(i => i.Id == item.Id);
         }
         if (use > 1)
         {
             return false;
         }
     }
     return true;
 }