Autor Beitrag
IsabelleZimmermann
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 54



BeitragVerfasst: Di 06.08.19 20:38 
Hallo zusammen,

lange Zeit bin ich gut zurecht gekommen.
Aber jetzt hänge ich an einem Problem und komme nicht weiter.

In einer Klasse speichere ich Variablen in eine ArrayList vom Typ int.
Datentyp int deshalb weil bei der nachfolgenden Verschnittoptimierung(Restverwertung mit möglichst wenig Abfallstücken) mit den Werten gerechnet wird. Diese habe ich hinbekommen, darf sie aber nicht veröffentlichen.

Mein Problem ist nun, dass ich noch keinen Algorithmus gefunden habe, der (unendlich) viele Datensätze nach der Fertigungsbreite sortiert(Index2 des Datensatzes) und die zugehörigen 7 anderen Elemente des jeweiligen Datensatzes mitnimmt.

Ich habe bereits die OrderbyDescending-Funktion ausprobiert, einen selbst geschriebenen Algorithmus der immerhin 10 Datensätze richtig sortiert, habe die Compare-Methode der IComparer-Schnittstelle überschrieben und jetzt habe ich es mit der Kombination aus einer "eigenen" Compare-Methode probiert und dem Sortieren.

Das Ergebnis ist nun, dass das 2. Element (Fertigungbreite) in den Datensätzen nicht mehr auftaucht und nur noch ab dem 3. Datensatz, aber dann unsortiert. Ich habe mich noch nicht lange genug mit dieser Lösungsvariante beschäftigt um den Fehler zu finden.

Der Quellcode hierzu:
ausblenden volle Höhe C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
public int Compare(int kleiner, int groesser)
{
        int retvalue = 0;

        // größeren Wert zurück geben
        if (kleiner < groesser)
            retvalue = groesser;

        if (kleiner > groesser)
            retvalue = kleiner;

        if (kleiner == groesser)
            retvalue = groesser;

        return retvalue;
}

public void DataSortBarcodeTest(System.Collections.ArrayList alistx)
{
        int max0, max1,max3,max4, max5, max6, max7, max0minus, max1minus, max3minus, max4minus, max5minus,    max6minus, max7minus;
        max0minus = 0;
        max1minus = 1;
        max3minus = 3;
        max4minus = 4;
        max5minus = 5;
        max6minus = 6;
        max7minus = 7;
        for (int i = 1;i<listBarcodes.ToString().Count()/8;i++)
        {
            max0 = 0 + (i - 1) * 8;
            max1 = 1 + (i - 1) * 8;
            max3 = 3 + (i - 1) * 8;
            max4 = 4 + (i - 1) * 8;
            max5 = 5 + (i - 1) * 8;
            max6 = 6 + (i - 1) * 8;
            max7 = 7 + (i - 1) * 8;
            int max = 2 + (i-1) * 8;
            
            int min = 2;
            

            if (max >= 10)
            {
                min = 2 + (i - 2) * 8;
                max0minus = 0 + (i - 2) * 8;
                max1minus = 1 + (i - 2) * 8;
                max3minus = 3 + (i - 2) * 8;
                max4minus = 4 + (i - 2) * 8;
                max5minus = 5 + (i - 2) * 8;
                max6minus = 6 + (i - 1) * 8;
                max7minus = 7 + (i - 1) * 8;
            }

            //alistx.Sort();// 
            //alistx.Reverse();
            
            int x = Compare(Convert.ToInt32(alistx[min]), Convert.ToInt32(alistx[max]));
            if(x == Convert.ToInt32(alistx[max]))
            {
                
                
                int tmp = Convert.ToInt32(alistx[min]);
                alistx[min] = x;
                alistx[max] = tmp;

                // Modellnummer
                tmp = Convert.ToInt32(alistx[max0minus]);
                alistx[min] = alistx[max0];
                alistx[max] = tmp;
                // Farbe
                tmp = Convert.ToInt32(alistx[max1minus]);
                alistx[min] = alistx[max1];
                alistx[max] = tmp;
                // Wert Index4
                tmp = Convert.ToInt32(alistx[max3minus]);
                alistx[min] = alistx[max3];
                alistx[max] = tmp;
                // Wert Index 5
                tmp = Convert.ToInt32(alistx[max4minus]);
                alistx[min] = alistx[max4];
                alistx[max] = tmp;
                // Auftragsnummer
                tmp = Convert.ToInt32(alistx[max5minus]);
                alistx[min] = alistx[max5];
                alistx[max] = tmp;
                // Position
                tmp = Convert.ToInt32(alistx[max6minus]);
                alistx[min] = alistx[max6];
                alistx[max] = tmp;
                // Stückzahl
                tmp = Convert.ToInt32(alistx[max7minus]);
                alistx[min] = alistx[max7];
                alistx[max] = tmp;
            }
           
        }
        foreach (var xxxx in alistx)
                MessageBox.Show(xxxx.ToString());
    }


Kann mir bitte jemand weiterhelfen?

Ich weiß, dass die Namensgebung nicht ganz sinnvoll ist. Diese werde ich noch anpassen, wenn ich eine Lösung zu dem Problem habe.

Wenn ich es nicht hin bekomme bis nächste Woche(spätestens 15.08.) wird die Maschine ohne mein Programm ausgeliefert. 1 Tag brauche ich ja noch zum Testen der Übertragung der Daten zur Steuerung der Maschine.

Viele Grüße,
Isabelle

Moderiert von user profile iconChristian S.: C#-Tags hinzugefügt
Moderiert von user profile iconTh69: (Weitere) C#-Tags hinzugefügt
Moderiert von user profile iconChristian S.: Topic aus WinForms verschoben am Di 06.08.2019 um 21:38
Christian S.
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 20451
Erhaltene Danke: 2264

Win 10
C# (VS 2019)
BeitragVerfasst: Di 06.08.19 21:37 
Also, bevor man sich hier daran versucht, in einer Liste Blöcke zu sortieren, eine Frage vorweg: Wie aufwendig wäre es, die Datenstruktur dahingehend zu ändern, dass die Elemente der Liste Instanzen einer Klasse wie
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
public class Item {
  public int ModellNummer {get; set;}
  public int Farbe {get; set;}
  public int Fertigungsbreite {get; set; }
  public int Index4 {get; set; } // besserer Name?
  public int Index5 {get; set; } // besserer Name?
  public int Auftragsnummer {get; set; }
  public int Position {get; set;}
  public int Stueckzahl {get; set;}
}

sind? Die Art, wie Du die Daten im Moment verwaltest, ist in meinen Augen überhaupt nicht sinnvoll und erschwert nicht nur das Sortieren, sondern ist auch extrem fehleranfällig.

Eine Arbeiten mit obiger Struktur sähe dann so aus:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
// am Anfang der Datei:
using System.Linq;


// und dann im Quelltext
var myList = new List<Item>(); // bitte keine ArrayList verwenden!

myList.Add(new Item() { ModellNummer = 42, Farbe = 3, Fertigungsbreite = 12/*, ... */ });
/* ... weitere hinzufügen ... */

var sortedList = myList.OrderBy(i => i.Fertigungsbreite).ToList();

_________________
Zwei Worte werden Dir im Leben viele Türen öffnen - "ziehen" und "drücken".
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4764
Erhaltene Danke: 1052

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Di 06.08.19 21:40 
Statt der (untypisierten - noch aus .NET 1.x stammenden) ArrayList solltest du besser eine List<> benutzen (dann benötigst du auch die Convert-Methoden nicht mehr).

Auch ist deine Compare-Methode (sowie auch deren Verwendung) eigenartig (bzw. sogar falsch).

Und verstehe ich es richtig, daß du in der Liste Blöcke von Daten hast, welche du umsortieren möchtest?
Warum erzeugst du dir dann nicht eine passende Klasse für einen Block und packst diese dann in eine Liste? So kannst du dann die gesamte Liste bequem (mit den Standardmethoden) umsortieren, ohne komische Indexoperationen von Hand zu programmieren:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
class Block
{
  public int ModellNummer { get; set; }
  public int Farbe { get; set; }
  // ...
}

List<Block> alistx;


Edit: also so, wie Christian auch zeitgleich geschrieben hat ;-)
IsabelleZimmermann Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 54



BeitragVerfasst: Mi 07.08.19 08:42 
Danke für die Hinweise.
Ich weiß aber nicht ob ich es so einfach umsetzten kann, weil es einen Ablauf gibt wie die Elemente in die Liste gelangen.

Ich werde aber jetzt die richtige Liste verwenden, nicht mehr die ArrayList.
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4764
Erhaltene Danke: 1052

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Mi 07.08.19 10:02 
Selbst wenn du initial die List<int> benutzt, so kannst du doch dann diese in die List<Block> umkopieren, dann sortieren und anschließend evtl. wieder zurückkopieren.
IsabelleZimmermann Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 54



BeitragVerfasst: Mi 07.08.19 10:20 
user profile iconTh69 hat folgendes geschrieben Zum zitierten Posting springen:
Selbst wenn du initial die List<int> benutzt, so kannst du doch dann diese in die List<Block> umkopieren, dann sortieren und anschließend evtl. wieder zurückkopieren.


Ja, das stimmt.
Vom Prinzip her ist es so, dass ich ein Formular Form6 habe mit statischen Variablen Farbe, usw.
Diese speichere ich dann in einem anderen Formular in die Liste, da die Daten in einem Fenster angezeigt werden.

Jetzt weiß ich nicht genau mit welcher Klasse ich die Liste initialisieren soll.
Mein Aufruf für die Sortierung ist jetzt folgender:
ausblenden C#-Quelltext
1:
var sortedList = myList.OrderByDescending(form5 => Form5.listBarcodesInt[max]).ToList();					

Aber dieser funktioniert noch nicht richtig, da die gewünschte Variable(Fertigungsbreite) nicht umsortiert wird.
Wenn ich zum Beispiel 2 Datensätze mit 1200 und 1300 eingebe, erscheint im ersten Datensatz immer noch die 1200 und erst im nächsten 1300 anstatt umgekehrt.

Es kann sein, dass die Variable "form5" die richtigen Werte enthält, aber ich weiß nicht wie ich diese aufrufen kann.
Mein Aufruf ist wahrscheinlich noch falsch...

Moderiert von user profile iconTh69: C#-Tags hinzugefügt
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4764
Erhaltene Danke: 1052

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Mi 07.08.19 10:44 
Von welchem Typ ist denn myList? Hast du den Code von Christian jetzt übernommen?

Und dein Lambda-Ausdruck paßt aber überhaupt nicht! Verstehst du den überhaupt?

Und um meine obige Aussage zu präzisieren:
Schreibe dir zwei Methoden
ausblenden C#-Quelltext
1:
List<Block> ConvertTo(List<int> list) // bzw. List<Item> (oder wie auch immer die Klasse bei dir dann heißt)					
sowie
ausblenden C#-Quelltext
1:
List<int> ConvertTo(List<Block> list)					


PS: Und "... Formular Form6 habe mit statischen Variablen Farbe, usw." hört sich auch nach einem Design-Fehler an.


Zuletzt bearbeitet von Th69 am Mi 07.08.19 13:05, insgesamt 1-mal bearbeitet
IsabelleZimmermann Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 54



BeitragVerfasst: Mi 07.08.19 11:57 
Ok, danke.