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

Programmieren in Bäumen: cellfun

 

Wimme
Forum-Anfänger

Forum-Anfänger


Beiträge: 28
Anmeldedatum: 15.09.11
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 20.09.2012, 09:36     Titel: Programmieren in Bäumen: cellfun
  Antworten mit Zitat      
Hallo!

Ich habe eine Struktur "tree" angelegt, die Bäume repräsentieren kann:

tree.content: z.B. 2
tree.kids: ein cell array von weiteren 'trees'

Jetzt möchte ich eine Funktion schreiben, die mir eine Liste von allen Knoten gibt, die mehr als einen Nachfolger im Baum haben.
Z.B. würde [2 4 6] bedeuten, dass die Knoten mit dem jeweiligen Content 2, 4 und 6 mehr als einen Nachfolger haben.

Ich habe folgendes versucht:
Code:
% identifes nodes which have more than one successor
function splits = findSplitsInTree(tree)
if isempty(tree.kids)
    splits = [];
else if length(tree.kids)== 1
        splits = findSplitsInTree(tree.kids{1});
    else
        splits = [tree.content cellfun(@findSplitsInTree,tree.kids)];
    end
end


Was aber leider nicht funktioniert, und ich verstehe nicht warum. Hat jemand eine Idee?

edit:
Gut wäre es eigentlich auch, wenn die Rückgabe nicht ein Array der Form [2 3 4] wäre, sondern ein cell-array mit den entsprechenden Teilbäumen. Also anstatt [2 3 4] ein cell array mit drei Elementen, wobei z.B. das erste Element der Teilbaum mit dem Content 2 ist.

Danke,
Wimme
Private Nachricht senden Benutzer-Profile anzeigen


denny
Supporter

Supporter



Beiträge: 3.853
Anmeldedatum: 14.02.08
Wohnort: Ulm
Version: R2012b
     Beitrag Verfasst am: 20.09.2012, 11:01     Titel:
  Antworten mit Zitat      
Hallo

bitte dazu mehr Info, speziell was nicht funktioniert kommt eine Fehlermeldung?

Du rufst die Funktion ja rekursiv, was sind deine Abbruchkriterien?

Warum unterscheidet sich der Aufruf
zw. length(tree.kind)==1 und length(tree.kind)>1?
Private Nachricht senden Benutzer-Profile anzeigen
 
Wimme
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 28
Anmeldedatum: 15.09.11
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 20.09.2012, 11:10     Titel:
  Antworten mit Zitat      
Hallo denny,

danke für deine Antwort.

Zitat:
bitte dazu mehr Info, speziell was nicht funktioniert kommt eine Fehlermeldung?


Ja, sorry. Die Fehlermeldung ist:
Code:
Error using cellfun
Non-scalar in Uniform output, at index 1, output 1.
Set 'UniformOutput' to false.

Error in kram>findSplitsInTree (line 146)
        splits = [tree.content cellfun(@findSplitsInTree,tree.kids)];

Error in kram>findSplitsInTree (line 144)
        splits = findSplitsInTree(tree.kids{1});

Error in kram (line 6)
 leaves = findSplitsInTree(tree);


Wenn ich uniformOutput auf "false" setze, bekomme ich ein Ergebnis, das in meinem Beispiel wie folgt aussieht: [2] [] [] {1x6 cell} [] []

Was ja irgendwie keinen Sinn macht.


Zitat:
Du rufst die Funktion ja rekursiv, was sind deine Abbruchkriterien?

Nunja, der erste Fall, bei dem der aufgerufene subtree keine Kinder mehr hat ist ein Abbruch. Hier wird als Ergebnis einfach nur [] zurück gegeben.

Zitat:
Warum unterscheidet sich der Aufruf
zw. length(tree.kind)==1 und length(tree.kind)>1?

Ich möchte nur Knoten finden, die mehrere Nachfolger haben. Beim Fall length(tree.kind)==1 möchte ich mir also nicht den tree.content merken, beim Fall > 1 jedoch schon.


________


Wie in meinem Edit angemerkt, würde ich aber gerne inzwischen nicht mehr eine Liste der Form [1 2 3] haben, sondern ein cell array von subtrees.


Helfen dir die Bermerkungen weiter?
Private Nachricht senden Benutzer-Profile anzeigen
 
denny
Supporter

Supporter



Beiträge: 3.853
Anmeldedatum: 14.02.08
Wohnort: Ulm
Version: R2012b
     Beitrag Verfasst am: 20.09.2012, 14:21     Titel:
  Antworten mit Zitat      
Hallo
Danke, bin aber noch nicht sicher ob ich dir folgen kann.

Zitat:
Wenn ich uniformOutput auf "false" setze, bekomme ich ein Ergebnis, das in meinem Beispiel wie folgt aussieht: [2] [] [] {1x6 cell} [] []

Was ja irgendwie keinen Sinn macht.

CELLFUN UniformOutput mach hier schon Sinn, da Rückgabeparameter Listen mit unterschiedlicher Anzahl Elementen sind.
Code:

splits = findSplitsInTree(tree)
splits = [splits{:}]
 


Zuletzt bearbeitet von denny am 20.09.2012, 17:13, insgesamt einmal bearbeitet
Private Nachricht senden Benutzer-Profile anzeigen
 
Wimme
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 28
Anmeldedatum: 15.09.11
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 20.09.2012, 15:50     Titel:
  Antworten mit Zitat      
ich verstehe deinen Beitrag leider nicht recht.

Ich habe das ganze jetzt doch nochmal anders aufgezogen, ohne das schöne cellfun zu verwenden. Nach einigem Hin und Her klappt es jetzt auch:
Code:
function splits = findSplitsInTree(tree)

splits = [];
if length(tree.kids)== 1
    splits = findSplitsInTree(tree.kids{1});
else if length(tree.kids)> 1
        for i = 1:length(tree.kids)
            temp = findSplitsInTree(tree.kids{i});
            if ~isempty(temp)
                for j = 1:length(temp)
                    splits{length(splits)+1} = temp{j};
                end
            end
        end
        splits{length(splits)+1} = tree;
    end
end

 
Private Nachricht senden Benutzer-Profile anzeigen
 
Jan S
Moderator

Moderator


Beiträge: 11.057
Anmeldedatum: 08.07.10
Wohnort: Heidelberg
Version: 2009a, 2016b
     Beitrag Verfasst am: 20.09.2012, 17:52     Titel:
  Antworten mit Zitat      
Hallo Wimme,

Du wolltest Cells als Output.
Code:
function splits = findSplitsInTree(tree)
splits = {};
if length(tree.kids) == 1
    splits = findSplitsInTree(tree.kids{1});
elseif length(tree.kids)> 1
    for i = 1:length(tree.kids)
        splits = cat(2, splits, findSplitsInTree(tree.kids{i}));
    end
    splits{length(splits)+1} = tree;  %
end

Gruß, Jan
Private Nachricht senden Benutzer-Profile anzeigen
 
Sirius3
Forum-Guru

Forum-Guru


Beiträge: 441
Anmeldedatum: 12.11.11
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 21.09.2012, 17:38     Titel:
  Antworten mit Zitat      
Hallo Wimme,

falls Du doch einen Vektor willst:
Code:
function splits = findSplitsInTree(tree)
splits = [tree.content(length(tree.kids) > 1) cell2mat(cellfun(@findSplitsInTree,tree.kids,'UniformOutput',false))];
end


Grüße
Sirius
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.