WICHTIG: Der Betrieb von goMatlab.de wird privat finanziert fortgesetzt. - Mehr Infos...

Mein MATLAB Forum - goMatlab.de

Mein MATLAB Forum

 
Gast > Registrieren       Autologin?   

Partner:




Forum
      Option
[Erweitert]
  • Diese Seite per Mail weiterempfehlen
     


Gehe zu:  
Neues Thema eröffnen Neue Antwort erstellen

Vektor randomisieren ohne Zahlenwiederholung

 

verzweifelter Gast

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 12.05.2014, 10:40     Titel: Vektor randomisieren ohne Zahlenwiederholung
  Antworten mit Zitat      
Hallo,
ich programmiere derzeit ein Experiment für meine Masterarbeit.

Ich möchte dabei u.a. eine Sequenz erstellen, mit der ich die Position eines Items bestimme. Ich brauche dafür einen Vektor mit insgesamt 528 Stellen (Anzahl der Trials). Es gibt 16 mögliche Positionen. Jede Position soll gleich häufig vorkommen (also insgesamt jede 33 mal).
Die Schwierigkeit besteht für mich darin, dass eine Position nicht unmittelbar 2 mal hintereinander auftauchen soll.

Wenn ich mein Problem als Analogie ausdrücken müsste, hätte ich also 16 Urnen mit jeweils 33 Kugeln darin. Ich möchte aus allen Urnen zufällig so lange ziehen bis alle Urnen leer sind, nur nicht zwei mal hintereinander aus derselben.

Ich stöße hier leider an meine Grenzen. Ich hoffe, dass jemand eine Idee hat um mein Problem zu lösen.

Vielen Dank!


selber verzweifelter Gast

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 12.05.2014, 11:07     Titel: Lösung
  Antworten mit Zitat      
Hallo, ich konnte mein Problem grad selbst lösen.
Beim Herumstöbern bin ich auf den Befehl reshape gestoßen und dann kam eins zum anderen. Ich will nur kurz meine Lösung präsentieren:

Code:
a(1,:) = randperm(16);
m = [];

while 1
    for i = 1:32
        a(1+i,:) = randperm(16);
        if a(1+i,1) == a(i,16)
            m(i)= 0;
        else
            m(i)= 1;
        end
    end
    if min(m)>0
        break
    end
end
   
a_t = a';
zeile11 = reshape(a_t,1,[]);
 
Nras
Forum-Meister

Forum-Meister


Beiträge: 608
Anmeldedatum: 21.02.12
Wohnort: ---
Version: 7.12.0.635 (R2011a)
     Beitrag Verfasst am: 12.05.2014, 11:21     Titel:
  Antworten mit Zitat      
Hallo,

deine eigene Lösung erfüllt leider nicht deine Anforderungen. Das sind nicht wirklich Zufallspositionen, da da in 16er-Blöcken immer alle Positionen 1-16 angenommen werden. Das heißt beispielsweise, dass ich Position 16 schon exakt weiß, wenn ich die ersten 15 Positionen ausgesucht habe. Sowas wie 1,2,1,2,1,2,3,1,4,5,3,2,6,2,1 kann bei dir nicht vorkommen...
Eine richtig gute Lösung weiß ich auch nicht, ich habe mich aber von deinem Urnenmodell inspirieren lassen, das sollte funktionieren, ist aber sicher nicht die schnellste/eleganteste Lösung:

Code:
% Die Urnen
Urns = cell(1, 16);
for u = 1:16
    Urns{u} = ones(1, 33)*u;
end

pos = NaN(1, 528);
u = randsample(1:16,1,true,cellfun(@length, Urns));
pos(1) = u;
Urns{u} = Urns{u}(1:end-1);
for t = 2:528
    valid_draw = false;
    while ~valid_draw
        weights = cellfun(@length, Urns);
        % kann vermutlich auch mal nicht terminieren, wenn am Ende nur noch
        % eine einzige Urne Kugeln hat.
        if sum(weights~=0) == 1 % nur noch eine Urne hat Kugeln
            if t<528    % nur beim letzten Durchgang erlaubt
                error('kann nicht mehr terminieren')
            end
        end
       
        % zufaellig Urne waehlen
        u = randsample(1:16, 1, true, weights);
        if pos(t-1) ~= u
            pos(t) = u;
            Urns{u} = Urns{u}(1:end-1);
            valid_draw = true;
        end
    end
end


Viele Grüße,
Nras

Edit:
Das oben passt eigentlich auch nicht, da du die Urnen ja nicht gewichtet nach dem Anzahl ihrer Kugeln, die sie noch beinhalten, ziehen willst. Andernfalls (also mit randi() statt randperm()) wird es aber sogar sehr oft nicht terminieren... Da muss ein anderer Weg her.

Zuletzt bearbeitet von Nras am 12.05.2014, 11:30, insgesamt einmal bearbeitet
Private Nachricht senden Benutzer-Profile anzeigen
 
selber verzweifelter Gast

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 12.05.2014, 11:30     Titel:
  Antworten mit Zitat      
Argh, du hast da vollkommen recht! Das habe ich übersehen. Es ist immer gut, wenn einen jemand darauf aufmerksam macht bevor es zu spät ist. Danke!

Ich werde deine Version mal testen. Vielen Dank dafür.
 
Nras
Forum-Meister

Forum-Meister


Beiträge: 608
Anmeldedatum: 21.02.12
Wohnort: ---
Version: 7.12.0.635 (R2011a)
     Beitrag Verfasst am: 12.05.2014, 11:49     Titel:
  Antworten mit Zitat      
Würde es so machen:
Code:
N = 100;    % paar Testläufe
nachbarn_ungleich = NaN(1,N);
jede_pos_33_mal = NaN(1,N);
for n = 1:N
    pos = repmat(1:16,1,33);    % alle zu verteilenden positionen
    pos = pos(randperm(528));   % startversuch
    condition = any(diff(pos)==0);   % das muss erfüllt sein

    while condition == false
        % indizes der positionen, die neu gezogen werden sollen
        old_idx = find(diff(pos)==0);

        % mit new_idx soll getauscht werden
        new_idx = randperm(528);
        new_idx = new_idx(1:length(old_idx));
       
        % tauschen
        temp_old = pos(old_idx);
        pos(old_idx) = pos(idx_new);
        pos(new_idx) = temp_old;

        % pruefen, ob bedingung nun erfuellt ist
        condition = any(diff(pos)==0);
    end
    nachbarn_ungleich(n) = any(diff(pos)==0);   % keine nebeneinander
    jede_pos_33_mal(n) = all(histc(pos,unique(pos)) == ones(1, 16)*33);
end
disp(sum(nachbarn_ungleich)/N*100)
disp(sum(jede_pos_33_mal)/N*100)

Die äußere For-Schleife war nur testweise, um sicher zu gehen, dass kein Unsinn passiert.

Viele Grüße,
Nras
Private Nachricht senden Benutzer-Profile anzeigen
 
Neues Thema eröffnen Neue Antwort erstellen



Einstellungen und Berechtigungen
Beiträge der letzten Zeit anzeigen:

Du kannst Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum antworten.
Du kannst deine Beiträge in diesem Forum nicht bearbeiten.
Du kannst deine Beiträge in diesem Forum nicht löschen.
Du kannst an Umfragen in diesem Forum nicht mitmachen.
Du kannst Dateien in diesem Forum posten
Du kannst Dateien in diesem Forum herunterladen
.





 Impressum  | Nutzungsbedingungen  | Datenschutz | FAQ | goMatlab RSS Button RSS

Hosted by:


Copyright © 2007 - 2025 goMatlab.de | Dies ist keine offizielle Website der Firma The Mathworks

MATLAB, Simulink, Stateflow, Handle Graphics, Real-Time Workshop, SimBiology, SimHydraulics, SimEvents, and xPC TargetBox are registered trademarks and The MathWorks, the L-shaped membrane logo, and Embedded MATLAB are trademarks of The MathWorks, Inc.