kontrolliertes "randommäßiges" Sortieren einer Lis

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Chill-man
User
Beiträge: 24
Registriert: Dienstag 8. Januar 2008, 10:46

Hallo erstmal, ;)

der Titel hört sich ja recht komisch an, allerdings ist mir nichts besseres eingefallen.

ich suche nach einer einfachen möglichkeit eine definierte Liste (bestehend aus 0-19) kontrolliert zu mischen, sodass man die verteilung sofort wiederherstellen könnte.

In Pascal würde das ungefair so aussehen:

Code: Alles auswählen


for i=0 to 19 do
begin
zz=random(19)
buffer = A[i]
A[i] = A[zz]
A[zz] = buffer
end

Code: Alles auswählen

import random
l = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
zz = random.randint(0,19)
print zz
buffer = l[i]
l[i] = l[zz]
l[zz] = buffer
print l

wie baue ich da eine for loop drum oder irgend eine andere loop?
Zuletzt geändert von Chill-man am Dienstag 8. Januar 2008, 14:29, insgesamt 1-mal geändert.
BlackJack

Habe ich etwas übersehen, oder suchst Du einfach nur `random.shuffle()`!?
Chill-man
User
Beiträge: 24
Registriert: Dienstag 8. Januar 2008, 10:46

schon ok hab selbst nen bissl rumprobiert

Code: Alles auswählen


import random

liste = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]
r = []

i = 0
while i < 20:
    zz = random.randint(0,19)
    buffer = liste[i]
    liste[i] = liste[zz]
    liste[zz] = buffer
    r.append(zz+1)
    i = i+1

i = 0
while i < 20:
    if liste[i] == 1 or liste[i] == 5 or liste[i] == 9 or liste[i] == 13 or liste[i] == 17:
        print "Bed_1"
    if liste[i] == 2 or liste[i] == 6 or liste[i] == 10 or liste[i] == 14 or liste[i] == 18:
        print "Bed_2"
    if liste[i] == 3 or liste[i] == 7 or liste[i] == 11 or liste[i] == 15 or liste[i] == 19:
        print "Bed_3"
    if liste[i] == 4 or liste[i] == 8 or liste[i] == 12 or liste[i] == 16 or liste[i] == 20:
        print "Bed_4"
    if i == 19:
        randomnumbers = r
        final = liste
        print liste
    #ganz am Schluss
    i = i+1

CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

Was Du genau willst habe ich immer noch nicht kapiert. Und auch nicht, was die zweite Schleife bezweckt, aber den ersten Teil kannst Du abkürzen, wie von BlackJack angeregt:

Code: Alles auswählen

liste = range(1,21)
random.shuffle(liste)
Gruß,
Christian
Chill-man
User
Beiträge: 24
Registriert: Dienstag 8. Januar 2008, 10:46

hallo,

aber wenn ich das mit dem random.shuffle(liste) Befehl mache, dann kann ich das an einem späteren Zeitpunkt nicht mehr genau so generieren, oder gibts dafür auch einen shuffle code oder ka was?
Benutzeravatar
nkoehring
User
Beiträge: 543
Registriert: Mittwoch 7. Februar 2007, 17:37
Wohnort: naehe Halle/Saale
Kontaktdaten:

Hi Chill-man,

was meinst du mit "genau so generieren"? Du generierst doch eh mit Zufallswerten. Wo ist der unterschied, ob eine fertige Liste nun geshufflet (also durcheinandergewuerfelt) wird oder eben auf deine Art zufaellig erzeugt wird?

Oder ist es dir wichtig, dass auch doppelte Eintraege moeglich sind? Denn das passiert bei deiner Variante immermal... bei der anderen nicht!
[url=http://www.python-forum.de/post-86552.html]~ Wahnsinn ist auch nur eine andere Form der Intelligenz ~[/url]
hackerkey://v4sw6CYUShw5pr7Uck3ma3/4u7LNw2/3TXGm5l6+GSOarch/i2e6+t2b9GOen7g5RAPa2XsMr2
BlackJack

`randomnumbers`, `r`, und `final` werden gar nicht benutzt.

Und da Du Pascal erwähntest weiss ich nicht ob die Zuweisungen an `randomnumbers` und `final` das machen was Du erwartest. In Pascal würden dabei Daten kopiert, in Python einfach nur die beiden Namen zusätzlich an die Objekte gebunden.

Bei Schleifen bei denen man weiss wie oft sie durchlaufen werden nimmt man keine ``while``-Schleife sondern eine ``for``-Schleife. Wenn man diese komischen letzten ``if``-Abfrage nach ``i == 19`` weg lässt und die Liste einfach nach der Schleife ausgibt, dann braucht man auch keinen Index `i` sondern kann direkt über die Zahlen iterieren. Dann werden die ``if``-Abfragen auch kürzer weil man nicht ständig ``liste`` schreiben muss. Das lässt sich noch etwas weiter kürzen wenn man nicht mit Vergleichen und ``or`` arbeitet, sondern mit ``in``::

Code: Alles auswählen

        if i in (1, 5, 9, 13, 17):
            print "Bed_1"
Letztlich braucht man die ganzen ``if``\s aber nicht, weil sich die 'Bed_'-Nummer einfach berechnen lässt. Damit schrumpft der Quelltext auf folgendes::

Code: Alles auswählen

import random

def main():
    liste = range(1, 21)
    random.shuffle(liste)
    
    for i in liste:
        print 'Bed_%d' % ((i - 1) % 4 + 1)
    print liste

if __name__ == '__main__':
    main()

PS: Was meinst Du mit "an einem späteren Zeitpunkt nicht mehr genau so generieren!?
schlangenbeschwörer
User
Beiträge: 419
Registriert: Sonntag 3. September 2006, 15:11
Wohnort: in den weiten von NRW
Kontaktdaten:

Noch ein Versuch :D
Chill-man hat geschrieben:sodass man die verteilung sofort wiederherstellen könnte.
Meinst du innerhalb der Laufzeit oder soll die Zufallsliste bei jedem Programmstart gleich sein?
Dazu könntest du entweder den gleichen Initialisierungswert verwenden, oder einen zufälligen, den du jedoch zur Laufzeit speicherst, oder du schreibst die Indices vom Anfang mit in deine Datenstruktur. Letzteres sähe dann in etwa so aus:
[(wert, zufallsindex), (wert, zufallsindex), ...]
Du musst einen Code dann anpassen und kannst die Liste sehr einfach in den Anfangszustand zurücksetzen.
(Du könntest natürlich auch einfach eine Kopie speichern.)

Nochwas zu deinem 2. Quelltext. Verstehen tue ich ihn auch net, aber

Code: Alles auswählen

if liste[i] == 1 or liste[i] == 5 or liste[i] == 9 or liste[i] == 13 or liste[i] == 17:
kannst du einfacher schreiben:

Code: Alles auswählen

if liste[i]  in (1, 5, 9, 13, 17):
Chill-man
User
Beiträge: 24
Registriert: Dienstag 8. Januar 2008, 10:46

Ui, das geht ja richtig flott hier ;)

also das mit dem zusammenfassen ist ja klasse (ich glaube man merkt, dass ich noch nicht so geübt in python bin), vielen Dank dafür schonmal.

Also mit dem genau so generieren meine ich, dass die die geshuffelte zahlenreihenfolge genau so nocheinmal erstellen möchte, ohne dass ich eine millionen mal rumprobieren möchte, damit genau die Zahlenfolge wieder kommt.

Achja ich hätte da noch eine Frage: kann man diese Liste irgendwie ausserhalb des scripts speichern um dann bei einem Neustart des scripts drauf zugreifen zu können?

Wofür brauche ich das ganze? ;)
Ich möchte einen Versuch mit Blender erstellen, bei dem 4 Objekte angezeigt werden, welche per Zufall ausgewählt werden sollen und verschoben werden sollen. Insgesamt soll dies 20 mal geschehen.
Das projekt ist soweit fertig, bis auf das mit dem random auswählen halt.

Danke schonmal Tillmann
Zuletzt geändert von Chill-man am Dienstag 8. Januar 2008, 15:52, insgesamt 1-mal geändert.
Zap
User
Beiträge: 533
Registriert: Freitag 13. Oktober 2006, 10:56

Wenn du gerne bestimmte Konstelationen prüfen möchtest dann kannst du sie ja entweder als Parameter an dein Skript übergeben oder wie du schon überlegt hast aus einer Datei auslesen.
Was das Speichern angeht hat der Gerold mal eine nette Sammlung geschrieben:
http://www.python-forum.de/topic-6157.h ... +schreiben
Zuletzt geändert von Zap am Dienstag 8. Januar 2008, 15:51, insgesamt 1-mal geändert.
schlangenbeschwörer
User
Beiträge: 419
Registriert: Sonntag 3. September 2006, 15:11
Wohnort: in den weiten von NRW
Kontaktdaten:

Wann willst du sie nochmal so erstellen? Beim nächsten Programmstart? Willst du sie dazu speichern?
Du kannst natürlich eine Liste speichern, da gibts etliche Möglichkeiten: txt, ini, pickle, ..., db. Wenn du aber nur eine Liste speichern willst, die du nur ausliest und nicht änderst, kannst du sie doch in deinen Quelltext schreiben, oder?
Chill-man
User
Beiträge: 24
Registriert: Dienstag 8. Januar 2008, 10:46

Danke Zap und schlangenbeschwörer.
Also die Liste möchte ich beim nächsten programmstart nochmal laden können, da mein script des öfteren neu geladen wird, allerdings der Versuch dann noch nicht fertig ist.

Zu dem generieren nochmal, der Versuch soll etliche Personen umfassen und da ich die Versuchspersonen einfach vor den Rechner setzten will und nicht die Konstellation vor jeder neuen Versuchsperson per Hand ändern möchte, soll sie random sein. Die Daten werden während des Versuchs in einer Datei abgespeichert da soll dann auch drin stehn wie diese gemischte Liste erzeugt wurde, sprich nicht einfach nur die endgültige Liste (die speicher ich sowieso ab).

Ich denke mal ich versuchs mit der pickle Methode.
Benutzeravatar
nkoehring
User
Beiträge: 543
Registriert: Mittwoch 7. Februar 2007, 17:37
Wohnort: naehe Halle/Saale
Kontaktdaten:

Du willst speichern wie die Liste erzeugt wurde??? Wie meinst du das denn nun wieder?
[url=http://www.python-forum.de/post-86552.html]~ Wahnsinn ist auch nur eine andere Form der Intelligenz ~[/url]
hackerkey://v4sw6CYUShw5pr7Uck3ma3/4u7LNw2/3TXGm5l6+GSOarch/i2e6+t2b9GOen7g5RAPa2XsMr2
Chill-man
User
Beiträge: 24
Registriert: Dienstag 8. Januar 2008, 10:46

also ich will jede zahl die durch random.randint(0,19) erzeugt wurde mit dem dazugehörigen i (i=Trialnumber) speichern.
Es sei denn, es gibt bei dem random.shuffle befehl auch eine möglichkeit einfach nur zum beispiel

random.shuffle()#da sollte jetzt irgendwie ne id hinzukommen
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

Ich könnte ja noch verstehen, wenn Du noch die ursprüngliche Liste zu irgendeinem Zweck in der Hinterhand behalten möchtest, aber ansonsten .... genauso ratlos wie nkoehring.

Wenn Du auch den Eindruck hast, wir reden hier aneinander vorbei, so versuche doch mal in einfachen Worten das Problem zu beschreiben, das Du lösen willst - ohne Rücksicht auf programmiertechnische Details.

Gruß,
Christian
rayo
User
Beiträge: 773
Registriert: Mittwoch 5. November 2003, 18:06
Wohnort: Schweiz
Kontaktdaten:

Hi

Ich glaube mal du willst einfach die gleiche Zufallsreihenfolge.

Das geht mit

Code: Alles auswählen

random.seed(x)
Gruss
Chill-man
User
Beiträge: 24
Registriert: Dienstag 8. Januar 2008, 10:46

also besser ausgedrückt (so hoffe ich)

ich möchte mischen und wenn ich 2 wochen danach an den rechne rgehe möchte ich exakt die gleich mischen wie sie zuvor gemischt wurde, allerdings will ich während dieser 2 wochen die liste anders gemischt haben.

2 wochen ist jetzt nur ein beispiel.
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

Langsam glaube ich zu verstehen: Möchtest Du vielleicht Permutationen einer Liste (alle oder einen Teil davon) zufällig auswählen und dann zyklisch wiederkehrend abarbeiten?
Chill-man
User
Beiträge: 24
Registriert: Dienstag 8. Januar 2008, 10:46

Also, vielen Dank für eure Hilfe ;-)

So wie ich mir das vorgestellt habe, brauche ich es doch nicht, es wird ausreichen die shuffle funktion zu nehmen. Falls es euch interessiert wofür ich das ganze brauche, hier ein kleiner Eindruck:

http://home.arcor.de/tillmannschatz/Ble ... rsuch2.rar

falls ihr blender habt, dann könnt ihr auch die blendfile öffnen, falls nicht liegt die exe datei im Unterordner Game.
Dies ist nur eine kleine Testversion.
Falls ihr verbesserungsvorschläge am code habt immer raus damit.

Cheers Tillmann
Benutzeravatar
nkoehring
User
Beiträge: 543
Registriert: Mittwoch 7. Februar 2007, 17:37
Wohnort: naehe Halle/Saale
Kontaktdaten:

Hallo Chill-man,

ich habe mir das Programm jetzt nicht angeschaut. Vielleicht komm ich ja nachher mal dazu. Aber falls du dochmal irgendwie sowas in der Richtung machen moechtes, dann ist Rayo's Tipp genau der richtige:

Gibst du jedem User ihre eigene ID und verwendest diese als Seed, bekommt jeder User die gleiche Liste generiert.

Oder nimmst du den Wochentag als Seed, bekommst du jeden Montag die gleiche Liste, Dienstags, Mittwochs, usw aber eine jeweils andere.

Code: Alles auswählen

import random

user_id = input("User ID? ")
liste = range(20)
random.seed(user_id**3) # damit der seed n bissl groesser ist
random.shuffle(liste)
print liste
[url=http://www.python-forum.de/post-86552.html]~ Wahnsinn ist auch nur eine andere Form der Intelligenz ~[/url]
hackerkey://v4sw6CYUShw5pr7Uck3ma3/4u7LNw2/3TXGm5l6+GSOarch/i2e6+t2b9GOen7g5RAPa2XsMr2
Antworten