private void btnRefresh_Click(object sender, EventArgs e)
        {
            try
            {
                for (int objectIndex = 0; objectIndex < table.TableObjects.Count; objectIndex++)
                {
                    DynamicTableObject tableObject = table.TableObjects[objectIndex];
                    tableObject.Value = int.Parse(gridVC.Rows[0].Cells[objectIndex + 1].Value.ToString());
                    tableObject.Cost  = int.Parse(gridVC.Rows[1].Cells[objectIndex + 1].Value.ToString());
                    table.CostList[objectIndex].Clear();
                }
                for (int i = 0; i < table.GroupMaxValues.Count; i++)
                {
                    table.GroupMaxValues[i].Clear();
                    table.GroupMaxIndices[i].Clear();
                }

                table.TargetCost = int.Parse(tbTarget.Text.Trim());

                PopulateMainGrid();
            }
            catch (Exception)
            {
                MessageBox.Show("Dopušteni su isključivo nenegativni cijeli brojevi.");
            }
        }
 static void Main(string[] args)
 {
     if (args.Length != 1)
     {
         Console.WriteLine("Potreban je jedan argument, put do datoteke s vrijednostima i cijenama!");
     }
     else
     {
         KnapsackGroupsCore core = new KnapsackGroupsCore();
         try
         {
             Stopwatch    stopwatch = Stopwatch.StartNew();
             DynamicTable table     = core.ParseInitialTableFromFile(args[0]);
             core.SolveProblem(false);
             Console.WriteLine("Traženi zbroj cijena: " + table.TargetCost);
             Console.WriteLine("Odabrani:");
             table.BestTableObjects.Reverse();
             foreach (int tableObjectIndex in table.BestTableObjects)
             {
                 DynamicTableObject tableObject = table.TableObjects[tableObjectIndex];
                 Console.WriteLine(table.GroupNames[tableObject.GroupIndex] + ": " + tableObject);
             }
             Console.WriteLine("---------");
             Console.WriteLine("Ukupna vrijednost: " + table.BestValue);
             Console.WriteLine("Ukupna cijena: " + table.BestCost);
             stopwatch.Stop();
             Console.WriteLine("Vrijeme izvrsavanja: " + ((float)stopwatch.ElapsedMilliseconds / 1000) + " s");
         }
         catch (Exception)
         {
             Console.WriteLine("Datoteka ne postoji ili nije ispravno formatirana!");
         }
     }
 }
        internal void SolveProblem(Boolean allValuesNeeded)
        {
            for (int currentCost = 0; currentCost <= targetCost; currentCost++)
            {
                for (int i = 0; i < groupMaxValues.Count; i++)
                {
                    groupMaxValues[i].Add(0);
                }
                for (int objectIndex = 0; objectIndex < tableObjects.Count; objectIndex++)
                {
                    DynamicTableObject tableObject = tableObjects[objectIndex];
                    int groupIndex = tableObject.GroupIndex;
                    if (groupMaxIndices[groupIndex].Count != groupMaxValues[groupIndex].Count)
                    {
                        groupMaxIndices[groupIndex].Add(objectIndex);
                    }

                    int maxValue;
                    if (groupIndex == 0)
                    {
                        if (tableObject.Cost <= currentCost)
                        {
                            maxValue = tableObject.Value;
                        }
                        else
                        {
                            maxValue = 0;
                        }
                    }
                    else
                    {
                        if (tableObject.Cost <= currentCost)
                        {
                            int previousMaxValue      = groupMaxValues[groupIndex - 1].Last();
                            int currentPlusAboveValue = tableObject.Value + groupMaxValues[groupIndex - 1][currentCost - tableObject.Cost];
                            maxValue = Math.Max(previousMaxValue, currentPlusAboveValue);
                        }
                        else
                        {
                            maxValue = groupMaxValues[groupIndex - 1].Last();
                        }
                    }
                    if (allValuesNeeded) // for populating table grid in GUI version:
                    {
                        costList[objectIndex].Add(maxValue);
                    }

                    if (maxValue > groupMaxValues[groupIndex].Last())
                    {
                        groupMaxValues[groupIndex][currentCost]  = maxValue;
                        groupMaxIndices[groupIndex][currentCost] = objectIndex;
                    }
                }
            }
        }
        public List <int> FindBest()
        {
            List <int> rows = new List <int>();

            int beginIndex = groupMaxIndices.Count - 1;
            int maximum    = groupMaxValues[beginIndex].Last();


            for (int i = 0; i < groupMaxValues.Count; i++)
            {
                if (groupMaxValues[i].Last() == maximum)
                {
                    beginIndex = i;
                    break;
                }
            }

            int currentCost = targetCost;
            DynamicTableObject tableObject = null;

            for (int currentList = beginIndex; currentList >= 0; currentList--)
            {
                if (currentList == beginIndex)
                {
                    int tableObjectIndex = groupMaxIndices[beginIndex].Last();
                    tableObject = tableObjects[tableObjectIndex];
                    // if none fit in the 'bag':
                    if (tableObject.Cost > currentCost)
                    {
                        break;
                    }
                    rows.Add(currentCost);

                    bestTableObjects.Add(tableObjectIndex);
                    bestCost  += tableObject.Cost;
                    bestValue += tableObject.Value;
                }
                else
                {
                    int rowIndex = currentCost - tableObject.Cost;

                    while (currentList != 0)
                    {
                        if (groupMaxValues[currentList][rowIndex] == groupMaxValues[currentList - 1][rowIndex])
                        {
                            int colIndexMiddle = groupMaxIndices[currentList][rowIndex];

                            currentList--;
                        }
                        else
                        {
                            break;
                        }
                    }


                    int colIndex = groupMaxIndices[currentList][rowIndex];
                    tableObject = tableObjects[colIndex];
                    if (tableObject.Cost <= rowIndex)
                    {
                        rows.Add(rowIndex);
                        bestTableObjects.Add(colIndex);
                        bestCost  += tableObject.Cost;
                        bestValue += tableObject.Value;
                    }

                    currentCost = rowIndex;
                }
            }



            return(rows);
        }
        private void MarkKeyCells()
        {
            rows.Reverse();
            table.BestTableObjects.Reverse();
            DynamicTableObject firstTableObject = null;
            DynamicTableObject lastTableObject  = null;
            int previousGroup = -1;
            int row           = 0;

            for (int rowIndex = 0; rowIndex < rows.Count; rowIndex++)
            {
                int col = table.BestTableObjects[rowIndex];
                DynamicTableObject tableObject = table.TableObjects[col];
                if (firstTableObject == null)
                {
                    firstTableObject = tableObject;
                }
                if (rowIndex == rows.Count - 1)
                {
                    lastTableObject = tableObject;
                }
                lbBest.Items.Add(table.GroupNames[tableObject.GroupIndex] + ": " + tableObject.ToString());

                if (previousGroup == -1)
                {
                    previousGroup = tableObject.GroupIndex;
                }
                else
                {
                    for (int previousIndex = previousGroup + 1; previousIndex < tableObject.GroupIndex; previousIndex++)
                    {
                        int previousCol = table.GroupMaxIndices[previousIndex][row];
                        gridMain.Rows[row].Cells[previousCol + 1].Style.BackColor = Color.Yellow;
                    }
                    previousGroup = tableObject.GroupIndex;
                }
                row = rows[rowIndex];
                Color color;
                if (rowIndex != rows.Count - 1)
                {
                    color = Color.Green;
                }
                else
                {
                    color = Color.Red;
                }

                gridMain.Rows[row].Cells[col + 1].Style.BackColor = color;
            }

            if (firstTableObject != null && firstTableObject.GroupIndex != 0)
            {
                for (int previousGroupIndex = 0; previousGroupIndex < firstTableObject.GroupIndex; previousGroupIndex++)
                {
                    int previousCol = table.GroupMaxIndices[previousGroupIndex][0];
                    gridMain.Rows[0].Cells[previousCol + 1].Style.BackColor = Color.Yellow;
                }
            }

            if (lastTableObject != null && lastTableObject.GroupIndex != table.GroupNames.Count - 1)
            {
                for (int afterGroupIndex = lastTableObject.GroupIndex + 1; afterGroupIndex < table.GroupNames.Count; afterGroupIndex++)
                {
                    int afterCol = table.GroupMaxIndices[afterGroupIndex][row];
                    gridMain.Rows[row].Cells[afterCol + 1].Style.BackColor = Color.Yellow;
                }
            }

            tbBestValue.Text = table.BestValue.ToString();
            tbBestCost.Text  = table.BestCost.ToString();
        }