Files |  Tutorials |  Articles |  Links |  Home |  Team |  Forum |  Wiki |  Impressum

Aktuelle Zeit: Fr Jul 04, 2025 04:07

Foren-Übersicht » Programmierung » Allgemein
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 5 Beiträge ] 
Autor Nachricht
 Betreff des Beitrags: Zeitliche Sortierung - Intervalle
BeitragVerfasst: Mi Mär 16, 2011 18:55 
Offline
DGL Member
Benutzeravatar

Registriert: So Jan 07, 2007 21:26
Beiträge: 130
Wohnort: mal hier mal da mal irgendwo
Hi Leute,
ja ich weiß das Thema klingt komisch aber mir is keine bessere kurze Umschreibung eingefallen :?
Also es gehts um Folgendes, ich habe Ereignisse die in bestimmten Intervallen ausgeführt werden sollen.
Kurzes Beispiel: Alle 2 Sekunden Textausgabe "Hallo" und alle 10 Sekunden "Test" ausgeben.
Nun will ich daraus eine Liste machen die diese "Aufgaben" beinhaltet.
Das Ergebnis zum Beispiel wäre: (2sec|"hallo",2sec|"hallo",2sec|"hallo",2sec|"hallo",2sec|"hallo",0sec|"test")
Nun ist es aber so das ich nicht nur 2 Ereignisse hab sondern unterschiedlich viele und diese in einem Array habe. Nun fehlt mir komplett der Ansatz um das Umzusetzen.
Quasi möchte ich einen Periodischen Intervall ermitteln.
Ich hoffe ihr könnt mir weiter helfen, ich hocke schon seit 2 Wochen an diesem Problem :(

MfG
bubble

_________________
Wenn Worte nichts als Worte sind,
dann müssen's Steine sein!
Solange - bis sie pleite sind - schmeißt Fensterscheiben ein!

- Fidl Kunterbunt -


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Mi Mär 16, 2011 19:21 
Offline
DGL Member
Benutzeravatar

Registriert: Di Sep 06, 2005 18:34
Beiträge: 362
Wohnort: Hamburg
Hi,

also mir fällt da ein Algorithmus ein, in dem du die Aufgaben nach Intervall sortierst, dann immer den kürzesten in die Liste schreibts, das entsprechende Intervall von allen anderen abziehst und ihn dann wieder einsortierst.

Also angenommen, die Aufgaben liegen unsortiert in Liste A und du willst eine Liste B wie oben beschrieben erstellen ginge das etwa so:
Code:
sort(A) // nach intervall sortieren
Auftrag tmp = A[0];
delete(A, tmp);
add(B, tmp) // den Auftrag mit kleinstem Intervall an B anfügen
forall(Auftrag auf in A)
    auf.intervall -= tmp.intervall;
add(A, tmp)


Dabei muss darauf geachtet werden, am Ende immer den Auftrag mit seinem ursprüünglichen Intervall einzufügen (was ich hier weggelassen hab).

Das wird dann wiederholt, bis die gewünschte Länge bzw. eine bestimmte Abbruchbedingung erreicht ist.

Nur ein schneller Einfall, keine Ahnung ob das wirklich so richtig ist.

Gruß
Shai

_________________
Der Mensch hat neben dem Trieb der Fortpflanzung und dem zu essen und zu trinken zwei Leidenschaften: Krach zu machen und nicht zuzuhören. (Kurt Tucholsky)
Schwabbeldiwapp, hier kommt die Grütze. (Der Quästor)


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Mi Mär 16, 2011 23:07 
Offline
DGL Member
Benutzeravatar

Registriert: Sa Aug 18, 2007 18:47
Beiträge: 694
Wohnort: Köln
Programmiersprache: Java
Ich hoffe ich habs überhaupt richtig verstanden...
Du hast Aufgaben, die in regelmäßigen Abständen wiederholt werden sollen?

Bischen Pseudocode:
Code:
class Aufgabe {
  float interval;
  float delta;
 
  function update(float vergangeneZeit) {
    delta += vergangeneZeit;
    if (delta >= interval) {
      AufgabeAusführen();
      delta -= interval;
    }
  } 
}

_________________
Es werde Licht.
glEnable(GL_LIGHTING);
Und es ward Licht.


Zitat aus einem Java Buch: "C makes it easy to shoot yourself in the foot; C++ makes it harder, but when you do it blows your whole leg off"

on error goto next


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Mi Mär 16, 2011 23:08 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Also ich bin mir nicht sicher ob ich das hier richtig verstehe. Geht es dir darum diese Liste zu generieren oder wirklich die Aufgaben zum richtigen Zeitpunkt auszuführen? Ich nehme mal das letztere an, da das wahrscheinlicher ist. Falls du das erstere willst kannst du aber trotzdem weiter lesen. Ganz am Ende gehe ich nochmal darauf ein.


Was du brauchst ist z.B. ein Heap. Findet sich üblicherweise in der Standardbibliothek, brauchst du also wahrscheinlich nicht selbst implementieren. Ich kenne Delphi so gut wie nicht, also keine Ahnung wie das da heißt, aber in C++ wäre es z.B. ein std::priority_queue.

Ein Heap (zu deutsch: "Haufen") hat im wesentlichen nur drei Operationen:
push : fügt ein neues Objekt in den Heap ein
top : gibt das kleinste Element zurück
pop : entfernt das kleinste Element aus dem Heap.

Wie der Heap letztlich intern funktioniert ist unwichtig. Es sei aber soviel gesagt das es sich letztlich um eine Art dynamisches Array handelt bei dem die Elemente auf eine spezielle weise sortiert gehalten werden. Durch geschicktes tauschen von Elementen wird vermieden ständig das gesamte Array neu zu sortieren. Bei Wikipedia findet sich dazu sicher was, falls Interesse besteht.

Für jeden Auftrag berechnest du einen Zeitstempel für den ersten Ausführungstermin des Intervalls. Da deine Intervalle recht kurz sind ist eine Millisekunden-Auflösung ratsam. Für Zeitstempel benutze ich hier einfach Zeit in Millisekunden seit einem bestimmten Datum. Welches Datum du nimmst ist Wurst. Um UNIX-konform zu sein könnte man etwa den 1. Januar 1970 00:00 Uhr UTC benutzen. In Windows ist da aber schwer dran zu kommen, zumindest wenn man Millisekunden-Auflösung möchte. Der Zeitpunkt des Programmstarts tut hier aber genauso gut.

Da ich wie gesagt kein Delphi kann, hier eine C++-Implementierung:
Code:
class Auftrag {
public:
   // Konstruktor
   Auftrag(uint64_t interval, std::string text) {
      m_interval = interval;
      m_text = text;
      reset();
   }   

   // Auftrag ausführen
   void execute() {
      std::cout << m_text; // Text ausgeben
   }

   // Neue Ausführungszeit berechnen
   void reset() {
      m_nextExecutionTime = timestamp() + m_interval;
   }

   // Operator damit der Heap den Zeitstempel zweier Aufträge vergleichen kann
    bool operator<(const Auftrag& other) const {
      return m_nextExecutionTime < other.m_nextExecutionTime;
   }

    uint64_t m_nextExecutionTime; // nächster Ausführungszeitpunkt in Millisekunden
   uint64_t m_interval;          // Intervall-Dauer in Millisekunden

   std::string m_text;
};



// Heap erzeugen, Aufträge definieren
std::priority_queue<Auftrag*> heap;
heap.push(new Auftrag(2000, "Hallo"));
heap.push(new Auftrag(10000, "Test"));

// Aufträge ausführen bis in alle Ewigkeit
while (!heap.empty()) {
   uint64_t now = timestamp();
   Auftrag* auftrag = heap.top(); // Erstes Element auf dem Heap
   if (now < auftrag->m_nextExecutionTime) {
      msleep(auftrag->m_nextExecutionTime - now); // Millisekunden sleep
   }
   heap.pop(); // Erstes Element löschen

   auftrag->execute();
   auftrag->reset();
   heap.push(auftrag);
}



So, wie versprochen...falls du doch das erstere willst, also nur die Liste generieren....dann geht das mit der gleichen Methode. Natürlich würdest du auf das sleep verzichten. Statt die tatsächliche Zeit zu benutzen verwendest du eine Variable. Wenn immer du einen Auftrag vom Heap nimmst addierst du seine Interval-zeit auf diese Variable...so als wäre diese Zeit vergangen. Die Abbruch-Bedingung würdest du in die reset-Methode einbauen, diese könnte etwa false zurückgeben wenn der Auftrag nicht erneuert werden soll.


In einer größeren Implementierung würde man natürlich die execute- und reset-Methoden virtuell machen damit Unterklassen diese überschreiben können.


P.S. Das war jetzt wahrscheinlich Overkill...aber damit kannst du problemlos 1000sende Aufträge gleichzeitig verarbeiten.

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Fr Mär 18, 2011 06:37 
Offline
DGL Member
Benutzeravatar

Registriert: So Jan 07, 2007 21:26
Beiträge: 130
Wohnort: mal hier mal da mal irgendwo
Hi,
danke für die viele Hilfe. Coolcat, du hast recht, für das was ich jetzt damit vor hab ist deine Variante overkill. Aber für späteres auf jedenfall Interessant. :)
Ich hab mir vorgestern schon mal Shaijans Beitrag durchlesen können, nur halt noch nicht zurückschreiben können :S
Am besten gefällt mir die Variante von damadmax :] Simpel und leicht zu implementieren ^^

Leider bin ich aber auch erst wieder in ca. 2 Wochen zu hause um daran wirklich weiter arbeiten zu können. Bisher muss ich mich noch mit Block und Kuli zufrieden geben :S

MfG
bubble

_________________
Wenn Worte nichts als Worte sind,
dann müssen's Steine sein!
Solange - bis sie pleite sind - schmeißt Fensterscheiben ein!

- Fidl Kunterbunt -


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 5 Beiträge ] 
Foren-Übersicht » Programmierung » Allgemein


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 7 Gäste


Du darfst keine neuen Themen in diesem Forum erstellen.
Du darfst keine Antworten zu Themen in diesem Forum erstellen.
Du darfst deine Beiträge in diesem Forum nicht ändern.
Du darfst deine Beiträge in diesem Forum nicht löschen.
Du darfst keine Dateianhänge in diesem Forum erstellen.

Suche nach:
Gehe zu:  
cron
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.008s | 14 Queries | GZIP : On ]