Verfasst am: 26.10.2012, 21:23
Titel: Verknüpfen von Spalten einer Matrix
Hallo,
bin ein Matlab-Laie und mit dieser Aufgabe ziemlich überfordert:
Erstellt werden soll eine Matrix mit 2 Spalten und 1440 Zeilen. In der ersten Spalte sollen jeweils 720 Nullen und Einsen stehen, die geshuffelt werden. Soweit bin ich schon, das klappt.
Das Problem: Die Inhalte der zweiten Spalte sind von der ersten abhängig. Die zweite Spalte soll mit den Zahlen 1, 2, 3 und 4 aufgefüllt werden. Der Wert der ersten Zeile ist dabei relativ egal. Für die weiteren Zeilen soll gelten: wenn in der ersten Spalte eine 0 steht, soll in der zweiten Spalte die Zahl von Zeile n-1 wiederholt werden. Wenn in der ersten Spalte eine 1 steht, darf in der zweiten Spalte nicht die Zahl aus Zeile n-1 stehen. Stattdessen soll eine der drei anderen Zahlen drankommen, wobei die drei verbleibenden Zahlen zumindest eine etwa ähnliche Wahrscheinlichkeit haben sollten, gewählt zu werden. Insgesamt sollen alle Zahlen von 1 bis 4 gleich häufig vorkommen.
kannst du dir zumindest mal deinen Zufallsvektor zwischen 1 und 4 erstellten. Über die find() Funktion kannst du die Indizes herausfinden wo 0 und 1 in deiner ersten Spalte stehen. Danach musst du dann nur noch deine Bedingungen setzen.
Ich weiß zwar nicht, was du mit ähnlicher Wahrscheinlichkeit meinst, aber vllt. könnte man für das Problem randi nehmen.
Viele Grüße
Christof
Jule
Gast
Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
Verfasst am: 27.10.2012, 11:14
Titel:
Hallo Christof,
erstmal vielen Dank für deine Antwort. Mit gleicher Wahrscheinlichkeit meine ich, dass z.B. nach jeder 2 in der zweiten Spalte die Zahlen 1, 3 und 4 über alle 1440 Zeilen hinweg etwa gleich häufig drankommen sollten, wenn in der ersten Spalte eine 1 steht.
Mein Problem ist, dass ich nicht weiß, wie ich die zweite Spalte gemäß der Vorgaben ordnen soll. Eine randomisierte Spalte bekomme ich hin, dsa Problem ist das Erstellen der Bedingungen. Ich weiß beispielsweise nicht, wie ich in der Matrix auf die Zeile n-1 verweisen kann, um die Bedingung daran zu knüpfen. Zweites Problem: ich weiß nicht, wie ich es hinbekomme, dass alle Zahlen gleich häufig drankommen. Hatte mir überlegt drei weitere Matrizen mit je einer Spalte zu generieren, in denen jeweils drei der Zahlen vorkommen und dann über so etwas wie Ziehen ohne Zurücklegen bei einer 1 in der ersten Spalte aus der passenden Matrix ein Element zu wählen und einzufügen. Habe nur keine Ahnung, wie ich das machen kann.
Das was du wünschst ist so wie ich es sehe eine Verschärfung des Rucksackproblem, wobei eine exakte Lösung und zusätzliche Randbedinnungen gegeben sind.
Theoretisch sind daher maximal 3^1439 Lösungsschritte notwendig, du darfst dich also nicht beschweren wenn Matlab lange läuft Ich hab nen klassischen Try&Error Ansatz verwendet.
Ich schätze, dass du bis zu 2h warten musst, hab es nur für kleinere Größen ausprobiert.
Hier die Lösung:
Code:
function m=f001b(lines)
scol=[1,2,3,4];
ifmod(lines,size(scol,2))~=0 error('invalid input');
end
k=round(lines/length(scol));
m=zeros(lines,2);
m(:,1)=randi([0,1],[lines,1]);
m(1,1)=1;%in der ersten Zeile muss immer gezogen werden
zeilen_mit_eins=find(m==1);
%Anstelle von Zeilen wird mit Blöcken gearbeitet, wobei jeder Block mit
%einer "1er Zeile" Beginnt.
blocksize=[zeilen_mit_eins(2:end);size(m,1)+1]-zeilen_mit_eins(1:end);
blocknum=size(blocksize,1);
solution=zeros(blocknum,1);
guess=zeros(blocknum,1);
allowed_guess=zeros(blocknum,3);
line=1;
%3rd guess failed, undo;
guess(line)=0;
solution(line)=0;
allowed_guess(line,:)=[0,0,0];
line=line-1;
else if(allowed_guess(line,1)==0)
%noch keine Abfolge zum Raten gesetzt
ifline==1
allowed=scol(randperm(4));
allowed=allowed(1:3);%avoid special case in first line;
else
allowed=setdiff(scol,solution(line-1));
allowed=allowed(randperm(3));
end
allowed_guess(line,:)=allowed; %erlaubte werte;
end
guess(line)=guess(line)+1;
solution(line)=allowed_guess(line,guess(line)); %setze probehalber eine der erlaubten Lösunmgen
valid_sol=true;
for idx=scol
valid_sol=valid_sol&&sum(blocksize(solution==idx))<=k;
end if valid_sol
line=line+1;
end end end
m(zeilen_mit_eins,2)=solution;
%Bis hier wurden nur die "Entscheidungszeilen" berücksichtigt, also die mit
%einer 1 in der ersten Spalte
for idx=2:lines if m(idx,2)==0
m(idx,2)=m(idx-1,2);
end end end
Verfasst am: 28.10.2012, 18:45
Titel: Re: Verknüpfen von Spalten einer Matrix
Hallo Jule,
Ich komme mit der Aufgabenstellung immer noch nicht zurecht. Ausdrücke wie "relativ egal" und "zumindest eine etwa ähnliche Wahrscheinlichkeit" machen eine Lösung eigentlich unmöglich.
Zudem ist meiner Ansicht nach nicht garantiert dass es eine Lösung gibt. Falls zufällig die erste Spalte mit 770 Nullen beginnt, wird sich keine gewünschte Matrix finden lassen, oder?
Zudem schließen sich die Forderungen, dass bei einer 1 in der ersten Spalte die drei verbleibenden Ziffern in der zweiten Spalte mit ähnlicher Wahrscheinlichkeit gezogen werden, und die Forderung, dass in der zweiten Spalte alle 4 Möglichkeiten exakt gleich häufig vorkommen sollen, gegenseitig aus.
Da die Aufgabenstellung also vage ist, um nicht zu sagen Wischi-Waschi, würde ich sie mit einer angemessenen Brutalität lösen:
Code:
Spalte1 = [ones(770, 1), zeros(770, 1)];
Spalte1 = Spalte1(randperm(length(Spalte1));
proceed = true;
counter = 0;
while proceed
counter = counter + 1;
disp(counter);
Spalte2 = repmat((1:4)', 360, 1);
Spalte2 = Spalte2(randperm(Spalte2));
for k = 2:1440
Teste die Bedingung gegen Spalte2(k-1) und Spalte1(k)
bei Erfolg:
proceed = false;
end end end
Das Implementieren der Bedingungs-Tests überlasse ich Dir.
Wenn das eine Hausaufgabe ist, lasse Dich nicht beeindrucken, auch nicht wenn Dein Lehrer die Lösung für hirnrissig hält. Du wirst sicherlich auch mal sinnvollere Aufgaben gestellt bekommen.
Gruß, Jan
Jule
Gast
Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
Verfasst am: 29.10.2012, 11:18
Titel:
Hallo dmjr und Jan,
vielen Dank für eure Antworten, ich werde beide Optionen ausprobieren . Es handelt sich bei der Aufgabe um ein mit Matlab zu programmierendes psychologisches Experiment, in dem Probanden vier Aufgaben randomisiert ausführen müssen, wobei die Wahrscheinlichkeit eines Aufgabenwechsels 50% betragen soll und alle Aufgaben gleich häufig drankommen müssen. Dass es unter Umständen keine Lösung geben kann hab ich auch schon befürchtet.
Bei meiner Lösung dürfte es gerade gegen im letzten Viertel der Liste eine nicht unerhebliche Autokorrelation geben. Da kann es einfach vorkommen, dass das "Kontingent" für ein oder zwei Zahlen schon aufgebraucht ist und diese dann gar nicht mehr vorkommt.
Das wäre ein Vorteil von dem Ansatz von Jan, allerdings bin ich mir da gerade nicht sicher ob der Algorithmus in annehmbarer Zeit terminiert
Das wäre ein Vorteil von dem Ansatz von Jan, allerdings bin ich mir da gerade nicht sicher ob der Algorithmus in annehmbarer Zeit terminiert ;)
Ja, das ist ein typischer Effekt dieser "Gunshot"-Programmiertechnik. Mit einem "geeigneten" Seed für den RNG findet es die Lösung in der ersten Iteration, ansonsten artet es in wildes Herumballern aus :-)
Ein Genetischer Algorithmus wäre hier effizienter: es werden dann in der nächtsen Iteration mit einer gewissen Wahrscheinlichkeit korrekte Zeilen beibehalten. Ähnlich ist der "Bomben-Wurf-Algorithmus": Erstelle einen zufälligen Start-Vektor, variere ein paar Zeilen so, dass sie das Kriterium erfüllen (durch vertauschen der Werte, das ist einfach, wenn es nur 4 Zeilen betrifft), und dann verwürfele alle Zeilen zufällig (der Bombenwurf), die nicht das Kriterium erfüllen.
Gruß, Jan
Einstellungen und Berechtigungen
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
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.