Hallo!
Gegeben sind die ganzzahlige Zeit „t“ und das Array „data“.
Anzahl der Einträge im Array: n = data.length
Ich brauche einen Algorithmus, der zu jeder Zeit einen Wert x zwischen 1 und n liefert, damit ein Eintrag data[ x-1 ] ausgegeben werden kann.
Bei aufeinanderfolgenden t soll x nicht gleich sein, also: x(t) != x(t+1)
Außerdem sollen die Ausgaben bunt gemischt werden, so dass jedes x ungefähr gleich oft vorkommt und Abfolgen sich selten wiederholen.
Es darf keine weitere Datenquelle wie ein Zufallsgenerator genutzt werden.
Der Sinn ist, Fotos auf mehreren Bildschirmen laufen zu lassen. Ich habe zueinander passende Bilder in data[] zusammengestellt, die synchron angezeigt werden sollen. Es gibt keine Zentrale, daher muss jeder Raspberry Pi aus dem Algorithmus und der Zeit wissen, welche Aufnahme gerade dran ist.
Meine Idee ist, mit „t modulo n“ Gruppen zu bilden, in denen jedes x genau einmal vorkommt. Die Reihenfolge innerhalb der Gruppe wird dann mit einem Chaos-Generator ausgewürfelt, der mit t initialisiert wird. Ich könnte mir vorstellen, dass es eine viel elegantere Lösung gibt.
Viele Grüße Thomas
Aktueller Stand, der schon ganz OK funktioniert:
function pseudorandom(t, n) { // return a pseudo random number between 0 and n var x = 0; t = t * 347263074; // Add noise t = t.toString(); if (t == 0) return x;
for (var i = 0; i < t.length; i++) { x = ((x << 5) - x) + t.charCodeAt(i); x |= 0; // Convert to 32bit integer } x = Math.abs(x); x = x % (n+1); return x; };
Hi,
On Thu, November 3, 2016 12:30, Thomas Schmidt wrote:
Ich brauche einen Algorithmus, der zu jeder Zeit einen Wert x zwischen 1 und n liefert, damit ein Eintrag data[ x-1 ] ausgegeben werden kann.
Der Sinn ist, Fotos auf mehreren Bildschirmen laufen zu lassen. Ich habe zueinander passende Bilder in data[] zusammengestellt, die synchron angezeigt werden sollen. Es gibt keine Zentrale, daher muss jeder Raspberry Pi aus dem Algorithmus und der Zeit wissen, welche Aufnahme gerade dran ist.
Meine Idee ist, mit ât modulo nâ Gruppen zu bilden, in denen jedes x genau einmal vorkommt. Die Reihenfolge innerhalb der Gruppe wird dann mit einem Chaos-Generator ausgewürfelt, der mit t initialisiert wird. Ich könnte mir vorstellen, dass es eine viel elegantere Lösung gibt.
Du suchst keinen Zufallsgenerator, sondern einen Hash über die Zeit.
1) lass Dir die aktuelle Zeit geben (kompletter String mit Datum, damit es sich nicht wiederholt) 2) lege MD5 drueber (oder MD4, SHA ist hier nur CPU-Verschwendung) 3) nimm die letzten (oder ersten, egal) 32 bit 4) modulo n
Die wichtigere Frage ist: wie willst Du die Uhren der RPi's synchron halten wenn es keine Verbindung gibt?
Konrad
On Thu, 3 Nov 2016 13:05:21 +0100 "Konrad Rosenbaum" konrad@silmor.de wrote:
Die wichtigere Frage ist: wie willst Du die Uhren der RPi's synchron halten wenn es keine Verbindung gibt?
NTP? Wenngleich das auf einem Raspi trotzdem ganz schön driftet, aber da gibts Chips zum nachstecken für ganz kleines Geld.
Interessant wäre, ob die PIs in physikalischer Nähe sind und nur keine Netzwerkverbindung haben (dann könnte man mit $Funk irgend einen Sync nachbauen) oder ob sie weiter voneinander entfernt sind und der Sync nicht ganz so wichtig ist (dann kann man die Zeit weniger granular betrachten, sondern bspw. auf 15 Sekunden gerundet, dann können die auch bisschen driften).
Carsten
Vielen Dank Konrad für die Idee, einfach einen fertigen Hash-Algorithmus als Chaosgenerator zu nehmen. Genau das habe ich ja schon getan, mein Algorithmus entspricht Javas String.hashCode().
http://werxltd.com/wp/2010/05/13/javascript-implementation-of-javas-string-h...
Es ist noch nicht sichergestellt, dass nicht zweimal hintereinander genau das gleiche Bild kommt.
Die Synchronisation der Bildschirme ist überhaupt kein Problem. Raspbian macht out of the box ntp. Das Bild wechselt auf allen Bildschirmen alle 30 Sekunden. Die Genauigkeit ist um Größenordnungen ausreichend. Als t-Parameter nehme ich dementsprechend floor(Unixtime/30s).
Viele Grüße Thomas
lug-dd@mailman.schlittermann.de