C# optymalizacja cięcia kanpsack problem

Optymalizacja cięcia różnych długości z dłużycy 6m


const int BAR_LENGHT = 6000;
List<int> inputs = new() { 3100, 3100, 2800, 2800, 3000, 1200, 1300, 600 };
List<int> cuts = new(inputs);

cuts.Sort();
cuts.Reverse();

CutGroup cutGroup = new();

while (cuts.Count > 0)
{
    CutSet cutSet = new();
    for (int i = 0; i < cuts.Count; i++)
    {
        if (cutSet.GetSumCut() + cuts[i] <= BAR_LENGHT)
        {
            cutSet.AddItem(cuts[i]);
            cuts.RemoveAt(i);
            i--;
        }
    }

    var existingSet = cutGroup.cutSets.FirstOrDefault(set => set.Equals(cutSet));
    if (existingSet != null)
    {
        existingSet.Quantity++;
    }
    else
    {
        cutGroup.AddSet(cutSet);
    }
}

cutGroup.Print();

class CutSet
{
    public List<int> items;
    public int Quantity { get; set; }

    public CutSet()
    {
        items = new();
        Quantity = 1;
    }

    public void AddItem(int i)
    {
        items.Add(i);
    }

    public int GetSumCut()
    {
        return items.Sum();
    }

    public override int GetHashCode()
    {
        var result = 7;
        result *= items.Count;
        result *= GetSumCut() + 2;
        foreach (int i in items)
        {
            result += i * i;
        }
        return result;
    }

    public override bool Equals(object obj)
    {
        if (obj == null || GetType() != obj.GetType())
        {
            return false;
        }

        CutSet other = (CutSet)obj;
        return this.items.SequenceEqual(other.items);
    }
}

class CutGroup
{
    public List<CutSet> cutSets;

    public CutGroup()
    {
        cutSets = new();
    }

    public void AddSet(CutSet i)
    {
        cutSets.Add(i);
    }

    public void Print()
    {
        foreach (CutSet cutSet in cutSets)
        {
            Console.Write(cutSet.Quantity + " x [");
            Console.Write(string.Join(", ", cutSet.items));
            Console.Write("]");
            Console.WriteLine();
        }
    }
}


//Wynik
//2 x [3100, 2800]
//1 x [3000, 1300, 1200]
//1 x [600]

Optymalizacja cięcia w Wpf

using System.Windows;

namespace Cut_optimizer
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {

        List<int> cuts = new();
        CutGroup cutGroup;

        public MainWindow()
        {
            InitializeComponent();

           
        }

        void TakeInputs()
        {
            for (int i=0; i< Int32.Parse(QuantityInput.Text); i++)
            {
                cuts.Add(Int32.Parse(LengthInput.Text));

            }
            CutLbl.Content += QuantityInput.Text + ": ";
            CutLbl.Content += LengthInput.Text + "\n";
            QuantityInput.Text = "";
            LengthInput.Text = "";

        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            TakeInputs();
        }

        private void Button_Click_1(object sender, RoutedEventArgs e)
        {
            cutGroup = new();
            int baseInput = Int32.Parse(BaseInput.Text);
            cuts.Sort();
            cuts.Reverse();
            while (cuts.Count > 0)
            {
                CutSet cutSet = new();
                for (int i = 0; i < cuts.Count; i++)
                {
                    if (cutSet.GetSumCut() + cuts[i] <= Int32.Parse(BaseInput.Text))
                    {
                        cutSet.AddItem(cuts[i]);
                        cuts.RemoveAt(i);
                        i--;
                    }
                }

                var existingSet = cutGroup.cutSets.FirstOrDefault(set => set.Equals(cutSet));
                if (existingSet != null)
                {
                    existingSet.Quantity++;
                }
                else
                {
                    cutGroup.AddSet(cutSet);
                }
            }
            ResultLbl.Content = cutGroup.Print();
        }

        private void Button_Click_2(object sender, RoutedEventArgs e)
        {
            cuts.Clear();
            CutLbl.Content = "";
            ResultLbl.Content = "";
        }
    }

    class CutSet
{
    public List<int> items;
    public int Quantity { get; set; }

    public CutSet()
    {
        items = new();
        Quantity = 1;
    }

    public void AddItem(int i)
    {
        items.Add(i);
    }

    public int GetSumCut()
    {
        return (items.Sum() + items.Count * 5);
    }

    public override int GetHashCode()
    {
        var result = 7;
        result *= items.Count;
        result *= GetSumCut() + 2;
        foreach (int i in items)
        {
            result += i * i;
        }
        return result;
    }

    public override bool Equals(object obj)
    {
        if (obj == null || GetType() != obj.GetType())
        {
            return false;
        }

        CutSet other = (CutSet)obj;
        return this.items.SequenceEqual(other.items);
    }
}

class CutGroup
{
    public List<CutSet> cutSets;

    public CutGroup()
    {
        cutSets = new();
    }

    public void AddSet(CutSet i)
    {
        cutSets.Add(i);
    }

    public string Print()
    {
        int baseQuantity = 0;
        string lbl = "";
        foreach (CutSet cutSet in cutSets)
        {
            baseQuantity += cutSet.Quantity;
            lbl += cutSet.Quantity + " x [";
            lbl += string.Join(", ", cutSet.items);
            lbl += "]";
            lbl += "\n";
            lbl += "\n";
        }
        lbl += "Total bars: " + baseQuantity;
        lbl += "\n";
        return lbl;
    }
}
}

Scroll to Top