Zuviel Werbung? - > Hier kostenlos beim SPS-Forum registrieren

Seite 1 von 5 123 ... LetzteLetzte
Ergebnis 1 bis 10 von 46

Thema: Probleme mit Zykluszeit

  1. #1
    Registriert seit
    30.06.2007
    Ort
    In der Pfalz
    Beiträge
    503
    Danke
    72
    Erhielt 77 Danke für 65 Beiträge

    Standard


    Zuviel Werbung?
    -> Hier kostenlos registrieren
    Hallo,

    habe folgende Aufgabe zu lösen:

    Ich hab 20 Einzelwerte (REAL) und einen Sollwert (REAL).
    Der Sollwert ergibt sich im Normalfall aus einer beliebigen kombination mehrerer Einzelwerte.
    Ich soll immer nach der Kombination suchen, die am nähsten über dem Sollwert liegt oder genau den Sollwert ergibt.
    Aus wieviel Einzelwerten sich dann der Ermittelte ideale Wert zusammensetzt ist egal.

    Einen Baustein der mir das macht habe ich bereits mit SCL geschrieben (allerdings mit nur 10 Einzelwerten) und er funktioniert auch einwandfrei.

    Mein eigentliches Problem:

    Bei 20 Einzelwerten habe ich 2^20 - 1 Kombinationsmöglichkeiten.
    Das ergibt doch sehr wahrscheinlich eine extrem hohe Zykluszeit.

    Was für eine CPU eingesetzt werden soll weiß ich noch nicht (aber irgendeine von Siemens oder evtl. VIPA). Ihr könnt mir ja mal was empfehlen.

    Wie seht ihr das Problem mit der Zykluszeit?
    Zitieren Zitieren Probleme mit Zykluszeit  

  2. #2
    Registriert seit
    06.10.2003
    Beiträge
    3.409
    Danke
    449
    Erhielt 504 Danke für 407 Beiträge

    Standard

    Hallo Steve,

    http://sps-forum.de/showthread.php?t=14230

    Teil 2?


    Gruß, Onkel
    Es gibt viel mehr Leute, die freiwillig aufgeben, als solche, die echt scheitern.
    Henry Ford

  3. #3
    Registriert seit
    07.03.2004
    Beiträge
    4.369
    Danke
    946
    Erhielt 1.158 Danke für 831 Beiträge

    Standard

    Bei solchen Aufgaben ist doch die Frage ob man das Ergebnis in dem gleichen Zyklus benötigt in dem man den Algorithmus gestartet hat.

    Ich kenne ja Deinen Code nicht. Aber ich gehe mal davon aus das Du es in einer Art schleife ohne Backtracking (Rekursion) gelöst hast. Eine Schleife kann man ja recht leicht so umbauen das sie statt einen eigenen Sprung zu veranstalten einfach den Zyklischen Ablauf der SPS nutzt. Wichtig hier bei ist natürlich das alle Lokal verwendeten Variablen auch statisch deklariert sind.

    Man kann dann ein Busy-Flag an den Prozess geben und wenn eine Abbruchbedingung im Algorithmus eintritt Busy-Flag wegnehmen und Ergebnis präsentieren.
    If you open your Mind too much, your Brain will fall out.

  4. #4
    Avatar von Steve81
    Steve81 ist offline Erfahrener Benutzer
    Themenstarter
    Registriert seit
    30.06.2007
    Ort
    In der Pfalz
    Beiträge
    503
    Danke
    72
    Erhielt 77 Danke für 65 Beiträge

    Standard

    Zitat Zitat von Onkel Dagobert Beitrag anzeigen
    Hallo Steve,

    http://sps-forum.de/showthread.php?t=14230

    Teil 2?


    Gruß, Onkel
    Stimmt!

    und hier mal der Code:

    Code:
    //---------------------------------------Bausteinbezeichnung-------------------------------------------------------------
    FUNCTION_BLOCK FB11
    TITLE = 'Gewichtberechnung'
    VERSION : '2.0'
    AUTHOR : 'C&S'
    //---------------------------------------Variablendeklaration------------------------------------------------------------
    VAR_INPUT
        Anzahl_p_P_min, Anzahl_p_P_max : INT ;
        Sollgewicht, Max_Diff_max_min, min_Gewicht_p_St, max_Gewicht_p_St, max_Plus_Abw_Soll, G1, G2, G3, G4, G5, G6, G7, G8, G9, G10 : REAL ;
    END_VAR
    VAR_OUTPUT
         SPEICHER  :INT:=0;  
         BITSUMOUT : INT:=0;
         ISTIDEAL  : REAL:=0.0;
    END_VAR    
    VAR_IN_OUT
            ENABLE : BOOL ;
    END_VAR
    VAR    
        X, I, J, S, T, U, ADR, HBits : INT ;
        IST, MAXIMUM, MINIMUM, SUMME : REAL ;
        HO : DWORD ;
        GEWICHTE : ARRAY [1..10] OF REAL ;
        Gewichtesort : ARRAY [1..10] OF REAL ;
        wordi : WORD ;
        wordj : WORD ;
        wordk : WORD ;
        DBNRW : WORD ;
        IasDINT : DINT ;
    END_VAR
    //---------------------------------------Anweisungsteil------------------------------------------------------------------
    BEGIN
    IF ENABLE THEN
            GEWICHTE[1] := G1 ;
            GEWICHTE[2] := G2 ;
            GEWICHTE[3] := G3 ;
            GEWICHTE[4] := G4 ;
            GEWICHTE[5] := G5 ;
            GEWICHTE[6] := G6 ;
            GEWICHTE[7] := G7 ;
            GEWICHTE[8] := G8 ;
            GEWICHTE[9] := G9 ;
            GEWICHTE[10] := G10 ;
            DBNRW := INT_TO_WORD(3) ;
            ISTIDEAL := 0 ;             
     
            FOR I := 1 TO 1023 DO        
     
            HBits := BITSUM (IN :=  DINT_TO_DWORD(INT_TO_DINT(I)));               
     
     
     
            IF (HBits >= Anzahl_p_P_min) AND (HBits <= Anzahl_p_P_max) THEN
     
            IST := 0;
            J := 1;
            S := 1;
            T := 10;    
                FOR X := 1 TO 10 DO                
                    wordi := INT_TO_WORD(I);
                    wordj := INT_TO_WORD(J);
                    wordk := wordi AND wordj;                                                                                      
                    IF wordk<>0 THEN                    
                        //IST := IST + GEWICHTE [X] ;
                        Gewichtesort [S] := GEWICHTE [X] ;
                        S := S + 1 ;
                    ELSE
                        Gewichtesort [T] := 0 ;
                        T := T - 1 ;                
                    END_IF ;                            
                    J := J * 2 ;
                END_FOR ;
     
                ADR := 0 ;
                FOR U := 1 TO 10 DO                                
                    WORD_TO_BLOCK_DB(DBNRW) .DD[ADR] := REAL_TO_DWORD(Gewichtesort[u]) ;
                    ADR := ADR + 4;
                END_FOR ;
     
            FC63 (DBNR:=3, MNR:=0, ANZ:=HBits, MAXIMUM:=MAXIMUM, MINIMUM:=MINIMUM, SUMME:=IST);
     
                IF (MAXIMUM <= max_Gewicht_p_St) AND (MINIMUM >= min_Gewicht_p_St) AND ((MAXIMUM - MINIMUM) <= Max_Diff_max_min) AND (IST <= (Sollgewicht + max_Plus_Abw_Soll)) AND (IST >= Sollgewicht) THEN
     
                    IF IST = Sollgewicht THEN
                        ISTIDEAL := IST ;
                        SPEICHER := I ;
                        BITSUMOUT := HBits ;            
                        I := 1024 ;
     
                    ELSIF (IST > ISTIDEAL) AND (Sollgewicht > ISTIDEAL) THEN
                        ISTIDEAL := IST ;
                        SPEICHER := I ;
                        BITSUMOUT := HBits ;
     
                    ELSIF (Sollgewicht < ISTIDEAL) AND (IST < ISTIDEAL) AND (Sollgewicht < IST) THEN
                        ISTIDEAL := IST ;
                        SPEICHER := I ;
                        BITSUMOUT := HBits ;
     
                    END_IF ;
                END_IF ;
            END_IF ;
        END_FOR ;
    ENABLE := 0 ;
    END_IF;
    //--------------------------------------Bausteinende---------------------------------------------------------------------
    END_FUNCTION_BLOCK
    Also dass ich dich richtig verstehe Zotos, ich sollte die Schleife also pro Zyklus ein paar mal durchlaufen lassen z.B. 100 mal, und dann beim nächsten dort weitermachen wo ich aufgehört habe!

    Der Prozess ließe das in einem gewissen Ausmaß zu, allerdings brauch ich ca. alle Sekunde ein Ergebnis. Ich vermute sogar das wird knapp bei 20 Einzelwerten. Oder irre ich mich da?

  5. #5
    Registriert seit
    01.10.2007
    Ort
    Waiblingen
    Beiträge
    3.317
    Danke
    767
    Erhielt 536 Danke für 419 Beiträge

    Standard

    Zitat Zitat von Steve81 Beitrag anzeigen
    ...
    und hier mal der Code:
    ...
    allerdings brauch ich ca. alle Sekunde ein Ergebnis.
    ...
    Guten Morgen,

    das riecht mir danach, dass da ein anderer Algorithmus her muss. Da ich meine Videos regelmäßig passend auf Video-CD zurechtschnippel, schildere ich mal kurz, wie ich das mach:

    alle Portionen nach Größe sortieren - bei zwanzig Werten ist das mit Bubblesort noch bequem machbar.
    Dann die zwei größten Portionen miteinander addieren und wenn nicht gut passend, weil deutlich zu viel, größte und zweitgrößte Portion miteinander addieren ... usw. Wenn die zwei Größten Portionen zu wenig, dann noch die dritte Portion hinzunehmen. Das löst aber noch nicht vollständig, da dann zunehmend immer mehr kleine Portionen liegen bleiben.
    Also abwechselnd dazu immer die kleinsten Portionen miteinander kombinieren und dann entsprechend von dort aus gehend dreier und vierer-Kobinationen probieren.
    Heuristische Abkürzung: was nicht zur Lösung beiträgt sind wahrscheinlich fünfer-sechser bis eben zwanziger-Kombinationen, die also nur Rechenlast darstellen und daher vom Algorithmus ausgeblendet werden müssen. So kenne ich das jedenfalls aus meiner Praxis, wenn es darum geht, Sechserpacks mit Äpfeln zu einem Kilo zu kombinieren. Hier steht die Anzahl der zu kombinierenden Portionen bereits von vorneherein fest.

    Vermutlich spreche ich da schon das bereits angesprochene Rucksackproblem an - hab mir nicht die Mühe gemacht, das in Wiki nachzulesen ...

  6. #6
    Registriert seit
    07.03.2004
    Beiträge
    4.369
    Danke
    946
    Erhielt 1.158 Danke für 831 Beiträge

    Standard

    Zitat Zitat von Steve81 Beitrag anzeigen
    Also dass ich dich richtig verstehe Zotos, ich sollte die Schleife also pro Zyklus ein paar mal durchlaufen lassen z.B. 100 mal, und dann beim nächsten dort weitermachen wo ich aufgehört habe!
    Genau das meinte ich.

    Hier mal einfach in den Code rein geschrieben und nichts getestet da kann es sehr gut sein das beim Übergang +/- eins zum Schleifenzähler muss.

    Aber ich traue Dir zu, dass Du das selbst testen und verbessern kannst.

    Code:
     //---------------------------------------Bausteinbezeichnung-------------------------------------------------------------
    FUNCTION_BLOCK FB11
    TITLE = 'Gewichtberechnung'
    VERSION : '2.0'
    AUTHOR : 'C&S'
    //---------------------------------------Variablendeklaration------------------------------------------------------------
    VAR_INPUT
        Anzahl_p_P_min, Anzahl_p_P_max : INT ;
        Sollgewicht, Max_Diff_max_min, min_Gewicht_p_St, max_Gewicht_p_St, max_Plus_Abw_Soll, G1, G2, G3, G4, G5, G6, G7, G8, G9, G10 : REAL ;
    END_VAR
    VAR_OUTPUT
         SPEICHER  :INT:=0;  
         BITSUMOUT : INT:=0;
         ISTIDEAL  : REAL:=0.0;
         BUSY      : BOOL; (* ZoToS: der Algorithmus läuft *)
    END_VAR    
    VAR_IN_OUT
            ENABLE : BOOL ;
    END_VAR
    VAR    
        X, I, J, S, T, U, ADR, HBits : INT ;
        IST, MAXIMUM, MINIMUM, SUMME : REAL ;
        HO : DWORD ;
        GEWICHTE : ARRAY [1..10] OF REAL ;
        Gewichtesort : ARRAY [1..10] OF REAL ;
        wordi : WORD ;
        wordj : WORD ;
        wordk : WORD ;
        DBNRW : WORD ;
        IasDINT : DINT ;
        forCount :INT; (* ZoToS: zum splitten der Forschleife *)
    END_VAR
    //---------------------------------------Anweisungsteil------------------------------------------------------------------
    BEGIN
    IF ENABLE AND NOT BUSY THEN  (* ZoToS: ENABLE ohne BUSY -> Initialisierung *)
            GEWICHTE[1] := G1 ;
            GEWICHTE[2] := G2 ;
            GEWICHTE[3] := G3 ;
            GEWICHTE[4] := G4 ;
            GEWICHTE[5] := G5 ;
            GEWICHTE[6] := G6 ;
            GEWICHTE[7] := G7 ;
            GEWICHTE[8] := G8 ;
            GEWICHTE[9] := G9 ;
            GEWICHTE[10] := G10 ;
            DBNRW := INT_TO_WORD(3) ;
            ISTIDEAL := 0 ;
            BUSY := TRUE;  (* ZoToS: Jezt läuft der Algorithmus *)
            forCount := 1; (* ZoToS: die schleife soll von vorne Beginnen *)
    ELSE (* ZoToS *)
      IF ENABLE AND BUSY AND I < 1023 THEN  (* ZoToS: Also es läuft und ist noch unter den 1023 Elementen *)
        
        forCount := I; (* ZoToS: forCount festlegen  *)
        
        FOR I := forCount TO forCount + 127 DO (* ZoToS *)
            HBits := BITSUM (IN :=  DINT_TO_DWORD(INT_TO_DINT(I)));               
     
            IF (HBits >= Anzahl_p_P_min) AND (HBits <= Anzahl_p_P_max) THEN
     
            IST := 0;
            J := 1;
            S := 1;
            T := 10;    
                FOR X := 1 TO 10 DO                
                    wordi := INT_TO_WORD(I);
                    wordj := INT_TO_WORD(J);
                    wordk := wordi AND wordj;                                                                                      
                    IF wordk<>0 THEN                    
                        //IST := IST + GEWICHTE [X] ;
                        Gewichtesort [S] := GEWICHTE [X] ;
                        S := S + 1 ;
                    ELSE
                        Gewichtesort [T] := 0 ;
                        T := T - 1 ;                
                    END_IF ;                            
                    J := J * 2 ;
                END_FOR ;
     
                ADR := 0 ;
                FOR U := 1 TO 10 DO                                
                    WORD_TO_BLOCK_DB(DBNRW) .DD[ADR] := REAL_TO_DWORD(Gewichtesort[u]) ;
                    ADR := ADR + 4;
                END_FOR ;
     
            FC63 (DBNR:=3, MNR:=0, ANZ:=HBits, MAXIMUM:=MAXIMUM, MINIMUM:=MINIMUM, SUMME:=IST);
     
                IF (MAXIMUM <= max_Gewicht_p_St) AND (MINIMUM >= min_Gewicht_p_St) AND ((MAXIMUM - MINIMUM) <= Max_Diff_max_min) AND (IST <= (Sollgewicht + max_Plus_Abw_Soll)) AND (IST >= Sollgewicht) THEN
     
                    IF IST = Sollgewicht THEN
                        ISTIDEAL := IST ;
                        SPEICHER := I ;
                        BITSUMOUT := HBits ;            
                        I := 1024 ;
     
                    ELSIF (IST > ISTIDEAL) AND (Sollgewicht > ISTIDEAL) THEN
                        ISTIDEAL := IST ;
                        SPEICHER := I ;
                        BITSUMOUT := HBits ;
     
                    ELSIF (Sollgewicht < ISTIDEAL) AND (IST < ISTIDEAL) AND (Sollgewicht < IST) THEN
                        ISTIDEAL := IST ;
                        SPEICHER := I ;
                        BITSUMOUT := HBits ;
     
                    END_IF ;
                END_IF ;
            END_IF ;
        END_FOR ;
      ELSE 
        BUSY := FALSE; (* ZoToS *)  
      END_IF; (* ZoToS *)     
    ENABLE := 0 ;
    END_IF;
    //--------------------------------------Bausteinende---------------------------------------------------------------------
    END_FUNCTION_BLOCK
    Zitat Zitat von Steve81 Beitrag anzeigen
    Der Prozess ließe das in einem gewissen Ausmaß zu, allerdings brauch ich ca. alle Sekunde ein Ergebnis. Ich vermute sogar das wird knapp bei 20 Einzelwerten. Oder irre ich mich da?
    Ich denke mit einem Aufteilen des Algorithmus und einer schnellen CPU sollte das zu machen sein. Wenn nicht greif eben zu einem schnellen System (z.B. CoDeSys/Beckhoff).
    Geändert von zotos (08.12.2007 um 16:06 Uhr) Grund: die Forschleife Überarbeitet
    If you open your Mind too much, your Brain will fall out.

  7. Folgender Benutzer sagt Danke zu zotos für den nützlichen Beitrag:

    Steve81 (08.12.2007)

  8. #7
    Avatar von Steve81
    Steve81 ist offline Erfahrener Benutzer
    Themenstarter
    Registriert seit
    30.06.2007
    Ort
    In der Pfalz
    Beiträge
    503
    Danke
    72
    Erhielt 77 Danke für 65 Beiträge

    Standard

    Hallo zotos,

    danke für die schnelle Hilfe, habs zwar noch nicht ausprobiert, sieht aber ziemlich vielversprechend aus.
    Melde mich dann wieder wenn ich ein Ergebnis hab.

  9. #8
    Registriert seit
    07.03.2004
    Beiträge
    4.369
    Danke
    946
    Erhielt 1.158 Danke für 831 Beiträge

    Standard

    Ich habe mal einfach eine FOR-Schleife die von 0..1023 läuft auf 8 SPS Zyklen verteilt.

    Code:
    VAR
        myArray   :ARRAY[0..1023] OF INT;
        forIndex  :INT;
        forTarget :INT;
        Busy      :BOOL;
    END_VAR
    
    IF NOT BUSY THEN
        (* Initialisierung *)
        forIndex := 0;
        forTarget :=0;
        Busy := TRUE;
    ELSE
        IF BUSY AND forIndex <1023 THEN (* Die Schleife Läuft *)
            forTarget := forIndex + 127; (* hier bestimmt man indirekt die Anzahl der SPS-Zyklen *)
            FOR forIndex:=forIndex TO forTarget DO (* for Index wurde im Init gesetzt danach wird er Statisch gehalten *)
                (* Inhalt der eigentlichen Forschleife *)
                myArray[forIndex] := forIndex * 2; (* Nur zum Testen *)
            END_FOR;
        ELSE
            (* Ende der gesamten Schleife *)
            BUSY := FALSE;
        END_IF;
    END_IF;
    If you open your Mind too much, your Brain will fall out.

  10. #9
    Registriert seit
    01.10.2007
    Ort
    Waiblingen
    Beiträge
    3.317
    Danke
    767
    Erhielt 536 Danke für 419 Beiträge

    Standard

    Zitat Zitat von Steve81 Beitrag anzeigen
    ...
    Mein eigentliches Problem:
    Bei 20 Einzelwerten habe ich 2^20 - 1 Kombinationsmöglichkeiten.
    ...
    genau DA sehe ich Dein Problem - reden wir nun von 1023 Schleifendurchläufen oder von 1048575?

  11. Folgender Benutzer sagt Danke zu Perfektionist für den nützlichen Beitrag:

    zotos (08.12.2007)

  12. #10
    Registriert seit
    07.03.2004
    Beiträge
    4.369
    Danke
    946
    Erhielt 1.158 Danke für 831 Beiträge

    Standard


    Zuviel Werbung?
    -> Hier kostenlos registrieren
    Zitat Zitat von Perfektionist Beitrag anzeigen
    genau DA sehe ich Dein Problem - reden wir nun von 1023 Schleifendurchläufen oder von 1048575?
    Ja bei 1048575 wird es so nicht gehen. Das habe ich überlesen ;o(
    If you open your Mind too much, your Brain will fall out.

Ähnliche Themen

  1. Zykluszeit
    Von Maurice im Forum CODESYS und IEC61131
    Antworten: 3
    Letzter Beitrag: 17.09.2011, 15:19
  2. Zykluszeit S7-200
    Von pinolino im Forum Simatic
    Antworten: 8
    Letzter Beitrag: 14.01.2009, 07:27
  3. Zusammenhang Zykluszeit Profibus Zykluszeit SPS
    Von Peltzerserbe im Forum Feldbusse
    Antworten: 1
    Letzter Beitrag: 28.04.2008, 22:09
  4. S7-317 2-DP Zykluszeit
    Von gustave im Forum Simatic
    Antworten: 6
    Letzter Beitrag: 23.06.2007, 10:19
  5. Zykluszeit bei OB`s
    Von slaesh im Forum Simatic
    Antworten: 3
    Letzter Beitrag: 25.10.2005, 18:00

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •