Example #1
0
        private bool BerechnenMittelbehaelterNoetig(List <TDreieck> _Dreiecke)
        {
            double          B1Winkel = 0.0, B2Winkel = 0.0;
            List <TDreieck> DreieckeWinkeltest = _Dreiecke.ToList();

            while (DreieckeWinkeltest.Count > 0)
            {
                TDreieck D = DreieckeWinkeltest[DreieckeWinkeltest.Count - 1];

                if (B1Winkel < 180.0)
                {
                    B1Winkel += D.WA;

                    if (B1Winkel < 180.0)
                    {
                        DreieckeWinkeltest.RemoveAt(DreieckeWinkeltest.Count - 1);
                    }
                }
                else if (B2Winkel < 180.0)
                {
                    B2Winkel += D.WA;

                    if (B2Winkel < 180.0)
                    {
                        DreieckeWinkeltest.RemoveAt(DreieckeWinkeltest.Count - 1);
                    }
                }
                else
                {
                    return(true);
                }
            }

            return(false);
        }
Example #2
0
        public void DreieckHinzufügen(TDreieck D)
        {
            if (BehaelterTyp == TBehaelterTyp.Mittelbehaelter)
            {
                DreieckHinzufügenMittelbehaelter(D);
                return;
            }

            D.Verschieben(TempPos - new Point(D.A.X, D.A.Y));
            Dreiecke.Add(D);
        }
Example #3
0
        public void DreieckHinzufügenMittelbehaelter(TDreieck D)
        {
            D.Verschieben(TempPos - new Point(D.A.X, D.A.Y));

            if (AnordnungsFlag)
            {
                Dreiecke.Insert(0, D);
            }
            else
            {
                Dreiecke.Add(D);
            }

            AnordnungsFlag = !AnordnungsFlag;
        }
Example #4
0
        // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++pai+

        private void DateiEinlesen(string Datei)
        {
            string[] Zeilen            = Datei.Split('\n');
            string[] StartpunktStrings = Zeilen[Zeilen.Length - 1].Split(' ');

            int DreieckAnzahl;

            TDreieck[] _Dreiecke;

            try
            {
                DreieckAnzahl = int.Parse(Zeilen[0]);
                _Dreiecke     = new TDreieck[DreieckAnzahl];

                for (int I = 0; I < DreieckAnzahl; I++)
                {
                    string[] HindernisString = Zeilen[I + 1].Split(' ');
                    int      PunktAnzahl     = int.Parse(HindernisString[0]);
                    Point[]  Punkte          = new Point[PunktAnzahl];

                    for (int J = 0; J < PunktAnzahl; J++)
                    {
                        double X = double.Parse(HindernisString[J * 2 + 1]);
                        double Y = double.Parse(HindernisString[J * 2 + 2]);

                        Punkte[J] = new Point(X, Y);
                    }

                    if (Punkte.Length > 3)
                    {
                        throw new Exception("Mehr Punkte als erwartet!");
                    }

                    _Dreiecke[I] = new TDreieck(Punkte[0], Punkte[1], Punkte[2]);
                }
            }
            catch (Exception Ex)
            {
                MessageBox.Show("Die Datei konnte nicht korrekt eingelesen werden!" + Environment.NewLine + Ex.Message);
                return;
            }

            Dreiecke = _Dreiecke.ToArray();

            MenuItemSaveAs.IsEnabled = true;
            Berechnen();
        }
Example #5
0
        // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

        private void Berechnen()
        {
            // Alle Dreiecke in Liste zuordnen & Behaelterliste erstellen
            List <TDreieck>   DreieckeUnzugeteilt = Dreiecke.ToList();
            List <TBehaelter> _Behaelter          = new List <TBehaelter>();

            // Dreiecke nach KLEINSTER Kante ordnen | Worst Case: O(N)=N² Operation
            DreieckeUnzugeteilt = OrdneNachKleinsterStrecke(DreieckeUnzugeteilt);

            // Gesamtwinkel bestimmen
            double GesamtWinkel = 0.0;

            foreach (TDreieck D in DreieckeUnzugeteilt)
            {
                GesamtWinkel += D.WA;
            }

            // Handeln nach Gesamtwinkel
            if (GesamtWinkel < 180.0)
            {
                // 1 Behaelter ausreichend
                TBehaelter B = new TBehaelter();
                B.BehaelterTyp = TBehaelter.TBehaelterTyp.Startbehaelter;

                _Behaelter.Add(B);

                while (DreieckeUnzugeteilt.Count > 0)
                {
                    TDreieck D = DreieckeUnzugeteilt[DreieckeUnzugeteilt.Count - 1];
                    _Behaelter[0].DreieckHinzufügen(D);
                    DreieckeUnzugeteilt.RemoveAt(DreieckeUnzugeteilt.Count - 1);
                }
            }
            else
            {
                // 2 oder mehr Behaelter notwendig?
                if (BerechnenMittelbehaelterNoetig(Dreiecke.ToList()))
                {
                    // Start-, Mittel- und Endbehälter
                    TBehaelter BStart = new TBehaelter();
                    TBehaelter BEnde  = new TBehaelter();
                    BStart.BehaelterTyp = TBehaelter.TBehaelterTyp.Startbehaelter;
                    BEnde.BehaelterTyp  = TBehaelter.TBehaelterTyp.Endbehaelter;

                    _Behaelter.Add(BStart);
                    _Behaelter.Add(BEnde);

                    // Mittelbehälterzahl (ungefähr - im worst case sind es mehr)
                    int BehaelterZahlMindestens       = (int)Math.Ceiling(GesamtWinkel / 180.0);
                    int MittelbehaelterZahlMindestens = BehaelterZahlMindestens - 2;

                    if (MittelbehaelterZahlMindestens > 0)
                    {
                        for (int I = 0; I < MittelbehaelterZahlMindestens; I++)
                        {
                            TBehaelter BMittel = new TBehaelter();
                            BMittel.BehaelterTyp = TBehaelter.TBehaelterTyp.Mittelbehaelter;

                            _Behaelter.Insert(1, BMittel);
                        }
                    }

                    // Abwechselnd Start- und Endbehälter auf 90° auffüllen (Dreiecke mit größter Strecke zuerst)
                    bool   InStartcontainer = true;
                    double WinkelStart      = 0.0;
                    double WinkelEnd        = 0.0;
                    while ((WinkelStart < 90.0) && (WinkelEnd < 90.0) && DreieckeUnzugeteilt.Count > 0)
                    {
                        TDreieck D = DreieckeUnzugeteilt[DreieckeUnzugeteilt.Count - 1];

                        if (InStartcontainer)
                        {
                            WinkelStart += D.WA;

                            if (WinkelStart > 90.0)
                            {
                                continue;
                            }

                            BStart.DreieckHinzufügen(D);
                        }
                        else
                        {
                            WinkelEnd += D.WA;

                            if (WinkelEnd > 90.0)
                            {
                                continue;
                            }

                            BEnde.DreieckHinzufügen(D);
                        }

                        DreieckeUnzugeteilt.RemoveAt(DreieckeUnzugeteilt.Count - 1);

                        // Flag umkehren
                        InStartcontainer = !InStartcontainer;
                    }

                    // Temporären Winkel setzen
                    foreach (TBehaelter B in _Behaelter)
                    {
                        B.TempWinkel = 0.0;
                    }

                    // Start- und Endbehälter sind bereits teilweise gefüllt
                    BStart.TempWinkel = BStart.GefuellterWinkel();
                    BEnde.TempWinkel  = BEnde.GefuellterWinkel();

                    // Restliche Dreiecke auch unter Mittelbehältern zuteilen
                    int Index       = 0;
                    int Fehlzaehler = 0;
                    while (DreieckeUnzugeteilt.Count > 0)
                    {
                        TBehaelter B = _Behaelter[Index];
                        TDreieck   D = DreieckeUnzugeteilt[DreieckeUnzugeteilt.Count - 1];

                        // Dreieck hinzufügen wenn noch Platz ist
                        B.TempWinkel += D.WA;

                        if (B.TempWinkel < 180.0)
                        {
                            // Dreieck hinzufügen
                            B.DreieckHinzufügen(D);

                            DreieckeUnzugeteilt.RemoveAt(DreieckeUnzugeteilt.Count - 1);

                            Fehlzaehler = 0;
                        }
                        else
                        {
                            Fehlzaehler++;
                        }

                        // Falls die Behälter nicht ausreichen wird ein neuer hinzugefügt
                        if (Fehlzaehler >= _Behaelter.Count)
                        {
                            TBehaelter BNeu = new TBehaelter();
                            BNeu.BehaelterTyp = TBehaelter.TBehaelterTyp.Mittelbehaelter;
                            BNeu.TempWinkel   = 0;

                            _Behaelter.Insert(1, BNeu);
                        }

                        // Nächste Iteration
                        Index++;
                        if (Index >= _Behaelter.Count)
                        {
                            Index = 0;
                        }
                    }
                }
                else
                {
                    // Start- und Endbehälter
                    TBehaelter BStart = new TBehaelter();
                    TBehaelter BEnde  = new TBehaelter();
                    BStart.BehaelterTyp = TBehaelter.TBehaelterTyp.Startbehaelter;
                    BEnde.BehaelterTyp  = TBehaelter.TBehaelterTyp.Endbehaelter;

                    _Behaelter.Add(BStart);
                    _Behaelter.Add(BEnde);

                    // Abwechselnd Dreiecke zu Start- und Endbehälter hinzufügen (Dreiecke mit größter Strecke zuerst)
                    bool InStartcontainer = true;
                    while (DreieckeUnzugeteilt.Count > 0)
                    {
                        TDreieck D = DreieckeUnzugeteilt[DreieckeUnzugeteilt.Count - 1];

                        if (InStartcontainer)
                        {
                            BStart.DreieckHinzufügen(D);
                        }
                        else
                        {
                            BEnde.DreieckHinzufügen(D);
                        }

                        DreieckeUnzugeteilt.RemoveAt(DreieckeUnzugeteilt.Count - 1);

                        // Flag umkehren
                        InStartcontainer = !InStartcontainer;
                    }
                }
            }

            // Dreiecke in allen Behältern korrekt orientieren
            foreach (TBehaelter B in _Behaelter)
            {
                B.DreieckeAnordnen();
            }

            TBehaelter[] BesteAnordnung;
            double       BesteStrecke;

            if (_Behaelter.Count > 3) // Ab 3 sind Permuatation möglich (2 Behälter werden abgezogen)
            {
                // Permuatationen ohne Start- und Endbehälter
                List <TBehaelter> PermuatationsBehaelter = new List <TBehaelter>(_Behaelter);
                PermuatationsBehaelter.RemoveAt(0);
                PermuatationsBehaelter.RemoveAt(PermuatationsBehaelter.Count - 1);

                // Alle möglichen Kombinationen bestimmen
                var PermutationenRoh = BehaelterPermutationen(PermuatationsBehaelter, PermuatationsBehaelter.Count).ToArray();

                List <TBehaelter[]> Permutationen = new List <TBehaelter[]>();

                double[] Ergebnisse = new double[PermutationenRoh.Length];
                for (int I = 0; I < PermutationenRoh.Length; I++)
                {
                    List <TBehaelter> PermutationenUnvollstaendig = PermutationenRoh[I].ToList();
                    PermutationenUnvollstaendig.Insert(0, _Behaelter[0]);
                    PermutationenUnvollstaendig.Add(_Behaelter[_Behaelter.Count - 1]);

                    TBehaelter[] PermutationenVollstaendig = PermutationenUnvollstaendig.ToArray();

                    Permutationen.Add(PermutationenVollstaendig);

                    TBerechnung Berechnung = new TBerechnung(PermutationenVollstaendig);
                    Ergebnisse[I] = Berechnung.Berechnen();
                }

                int BestePermuatationIndex = -1;
                for (int I = 0; I < Ergebnisse.Length; I++)
                {
                    if (BestePermuatationIndex == -1 || Ergebnisse[I] < Ergebnisse[BestePermuatationIndex])
                    {
                        BestePermuatationIndex = I;
                    }
                }

                // Beste Permutation anzeigen
                TBehaelter[] BestePermutation = Permutationen[BestePermuatationIndex].ToArray();
                BestePermutation[0].Verschieben(new Vector(-(BestePermutation[0].TempPos.X - 200), 0));

                TBerechnung BerechnungBeste = new TBerechnung(BestePermutation);
                BerechnungBeste.Berechnen();

                BesteAnordnung = BestePermutation;
                BesteStrecke   = Ergebnisse[BestePermuatationIndex];
            }
            else
            {
                TBerechnung Berechnung = new TBerechnung(_Behaelter.ToArray());
                BesteStrecke   = Berechnung.Berechnen();
                BesteAnordnung = _Behaelter.ToArray();
            }

            // Ausgabe
            StatusBarItemInfo.Content = "Distanz: " + (int)Math.Round(BesteStrecke) + "m";

            // Behälter setzen & Zeichnen
            Behaelter = _Behaelter;
            Zeichne();
        }