Vad kallas det när man programmerar ett "träd"?

Permalänk

Vad kallas det när man programmerar ett "träd"?

Jag vet inte exakt vad detta kallas. Men jag har en känning om att jag har behov utav ett sådant "träd".

Här är ett exempel från Deeplearning4J i Java

MultiLayerConfiguration conf = new NeuralNetConfiguration.Builder() .weightInit(WeightInit.XAVIER) .activation(Activation.RELU) .optimizationAlgo(OptimizationAlgorithm.STOCHASTIC_GRADIENT_DESCENT) .updater(new Sgd(0.05)) // ... other hyperparameters .list() .backprop(true) .build();

Ni ser att det blir typ som ett "träd" beroende på vilken funktion man anropar.

Då är mina frågor:

1. Vad kallas detta?
2. Hur gör man detta i C++ på det enklaste sättet?

Självklart vet jag hur man gör, men det jag efterfrågar är om erfarenhet.
Min teori är att jag har en stor klass, i klassen så finns det privata fält som också har olika klasser. Den stora klassen har vissa funktioner som jag kan komma åt dessa olika klasser som finns i fälten.

Är detta korrekt? Eller har jag glömt något?

Permalänk
Medlem

Träd skulle jag själv inte kalla det, snarare en kedja.

1. Fluent API kallas det i C#, Fluent Interface i Java, efter hur Martin Fowler och Eric Evans benämnde mönstret 2005 ( https://martinfowler.com/bliki/FluentInterface.html ). Även "Builder pattern" används.

2. https://en.wikipedia.org/wiki/Fluent_interface#C++ ger ett exempel. Annars kan du ju bara titta på iostream...

En enkel implementation är ju att du har en klass, vars metoder du vill kedja returnerar objektet i sig med gjorda ändringar, varpå du ju kan fortsätta med anrop av nästa metod, osv, och sen avslutar med att t.ex. bygga ett Configurationobjekt eller en List från en LINQ-query.

Visa signatur

The power of GNU compiles you!
"Often statistics are used as a drunken man uses lampposts -- for support rather than illumination."

Permalänk
Skrivet av kode:

Träd skulle jag själv inte kalla det, snarare en kedja.

1. Fluent API kallas det i C#, Fluent Interface i Java, efter hur Martin Fowler och Eric Evans benämnde mönstret 2005 ( https://martinfowler.com/bliki/FluentInterface.html ). Även "Builder pattern" används.

2. https://en.wikipedia.org/wiki/Fluent_interface#C++ ger ett exempel. Annars kan du ju bara titta på iostream...

En enkel implementation är ju att du har en klass, vars metoder du vill kedja returnerar objektet i sig med gjorda ändringar, varpå du ju kan fortsätta med anrop av nästa metod, osv, och sen avslutar med att t.ex. bygga ett Configurationobjekt eller en List från en LINQ-query.

Exakt! Det var detta som jag menade.
Så om man får be om lite råd från mer erfarna i C++. Jag har inte programmerat så mycket i C++, mest bara C. Men nu kommer OOP till nytta.

Jag har denna klass

class ADL400 { private: float voltA; float voltB; float voltC; float currentA; float currentB; float currentC; float frequency; float voltAB; float voltBC; float voltAC; float value; ADL400(const char port[]); public: void setFunction(ADL400_FUNCTION_NAME functionName); void execute(); void getValue(); };

Mitt mål är att jag ska kunna anropa ungefär så här

BigClass bigClass = BigClass().Units(UNIT_NAME unitName).ADL400(const char port[]).setFunction(ADL400_FUNCTION_NAME functionName);

Sedan när jag har skapat min stora klass. Då ska jag kunna anropa

bigClass.execute(); float value = bigClass.getValue();

Nu är funktionen execute() på fel ställe dock. Den ska bara i BigClass(). Lika väl som funktionen getValue() Men jag hoppas att du förstår.

Frågan är hur du skulle ha gjort när det kommer till Enums för att t.ex. göra ett val på en viss klass som man vill "gå vidare" till.
Är Enums bra, eller finns det bättre sätt?

Något som jag ej gillar med Enums är att det går inte konvertera om dessa till text då Enums är bara heltal.

Permalänk
Medlem
Skrivet av heretic16:

Exakt! Det var detta som jag menade.
Så om man får be om lite råd från mer erfarna i C++. Jag har inte programmerat så mycket i C++, mest bara C. Men nu kommer OOP till nytta.

Jag har denna klass

class ADL400 { private: float voltA; float voltB; float voltC; float currentA; float currentB; float currentC; float frequency; float voltAB; float voltBC; float voltAC; float value; ADL400(const char port[]); public: void setFunction(ADL400_FUNCTION_NAME functionName); void execute(); void getValue(); };

Mitt mål är att jag ska kunna anropa ungefär så här

BigClass bigClass = BigClass().Units(UNIT_NAME unitName).ADL400(const char port[]).setFunction(ADL400_FUNCTION_NAME functionName);

Sedan när jag har skapat min stora klass. Då ska jag kunna anropa

bigClass.execute(); float value = bigClass.getValue();

Nu är funktionen execute() på fel ställe dock. Den ska bara i BigClass(). Lika väl som funktionen getValue() Men jag hoppas att du förstår.

Frågan är hur du skulle ha gjort när det kommer till Enums för att t.ex. göra ett val på en viss klass som man vill "gå vidare" till.
Är Enums bra, eller finns det bättre sätt?

Något som jag ej gillar med Enums är att det går inte konvertera om dessa till text då Enums är bara heltal.

Det som ger möjligheten att kedja vidare så som du skriver är just att alla funktioner i kedjan måste returnera ett objekt, punkten är till för att nå vad som nu finns inuti det objektet. Du kan alltså inte ha en void funktion och försöka bygga vidare på den.

Om vi tar ditt exempel:

BigClass bigClass = BigClass().Units(UNIT_NAME unitName).ADL400(const char port[]).setFunction(ADL400_FUNCTION_NAME functionName);

Så det första "BigClass()" är en constructor så punkten efter funkar eftersom den returnerar det instansierade BigClass objektet, och om "Units(UNIT_NAME unitName)" finns i det instansierade objektet så är det också korrekt. Däremot kan du nu inte kalla på en ny klass mitt i så "ADL400(const char port[])" är inte korrekt.
Men om Units() skulle returnera ett ADL400 objekt så skulle du kunna fortsätta med "setFunction(ADL400_FUNCTION_NAME functionName)".
Men efter allt det kommer du inte få ut något BigClass objekt så "BigClass bigClass =" är inte korrekt.

Ett korrekt sätt(förutsatt att "Units(UNIT_NAME unitName)" returnerar ett ADL400 objekt) skulle vara:

BigClass someBetterName= BigClass(); someBetterName.Units(UNIT_NAME unitName).setFunction(ADL400_FUNCTION_NAME functionName);

Permalänk

Något som jag är behov utav är att beroende på vilka argument jag stoppar in så kan jag anropa andra funktioner. Men i C++ går inte detta. Jag måste hitta på något helt annat.

Tanken är att jag ska ha en ComboBox. När jag väljer ett element i denna, så dyker det upp en ny ComboBox med andra element inkluderad. Beroende på vilket element jag väljer så får följande ComboBox andra element.

Jag skulle behöva något sådant. Det kanske finns ett alternativt sätt att göra?

Permalänk
Hedersmedlem
Skrivet av heretic16:

Tanken är att jag ska ha en ComboBox. När jag väljer ett element i denna, så dyker det upp en ny ComboBox med andra element inkluderad. Beroende på vilket element jag väljer så får följande ComboBox andra element.

Jag skulle behöva något sådant. Det kanske finns ett alternativt sätt att göra?

Hör detta ihop med trädet, eller är det ett nytt problem?

Permalänk
Skrivet av Elgot:

Hör detta ihop med trädet, eller är det ett nytt problem?

Det är samma problem.
Men jag tror att det är möjligt att göra sådan kod, men att underhålla koden, kommer nog bli svårt. Målet är att jag skall ändra koden igenom att lägga till mer funktionaliteter. Så jag måste hitta ett annat sätt att organisera mina ComboBoxes.

Jag har ett alternativ. Jag postar bild senare. Sedan får ni kommentera om det är en bra lösning eller inte.

Permalänk
Medlem
Skrivet av heretic16:

Något som jag är behov utav är att beroende på vilka argument jag stoppar in så kan jag anropa andra funktioner. Men i C++ går inte detta. Jag måste hitta på något helt annat.

Tanken är att jag ska ha en ComboBox. När jag väljer ett element i denna, så dyker det upp en ny ComboBox med andra element inkluderad. Beroende på vilket element jag väljer så får följande ComboBox andra element.

Jag skulle behöva något sådant. Det kanske finns ett alternativt sätt att göra?

Om jag förstår dig rätt med din comboBox så är nog det du letar efter abstract class/interface.

Det låter dig skapa en mall som sedan olika ärvande klasser måste implementera.

Det skiljer sig ganska mycket ifrån hur man får en method chain som var det du beskrev innan. Och jag förstår nu vad du menar med att du vill ha ett träd, något i stil med:

Exempel

// the abstract class class ComboBoxItem{ // some pure virtual functions public: virtual void onSelect() = 0; virtual void onUnselect() = 0; } // the class inhereting the abstract class class ComboBoxBranchCreator: public ComboBoxItem{ public: // implementing the pure virtual function void onSelect(){ // create and draw new combo box } void onUnselect(){ // remove drawn combo box } } // another class inhereting the abstract class class ComboBoxOption: public ComboBoxItem{ public: // implementing the pure virtual function void onSelect(){ // do work or nothing } void onUnselect(){ // Undo work } } class ComboBox{ private: ComboBoxItem[] myItems; public: ComboBox(ComboBoxItem[] items); void onItemSelect(ComboBoxItem selectedItem, ComboBoxItem previousItem){ previousItem.onUnselect(); selectedItem.onSelect(); } }

Du kan då skapa en ComboBox med en mix av "ComboBoxBranchCreator" och "ComboBoxOption", och då göra olika saker beroende på vad det är för objekt som väljs.

Permalänk
Skrivet av swesen:

Om jag förstår dig rätt med din comboBox så är nog det du letar efter abstract class/interface.

Det låter dig skapa en mall som sedan olika ärvande klasser måste implementera.

Det skiljer sig ganska mycket ifrån hur man får en method chain som var det du beskrev innan. Och jag förstår nu vad du menar med att du vill ha ett träd, något i stil med:

Exempel

// the abstract class class ComboBoxItem{ // some pure virtual functions public: virtual void onSelect() = 0; virtual void onUnselect() = 0; } // the class inhereting the abstract class class ComboBoxBranchCreator: public ComboBoxItem{ public: // implementing the pure virtual function void onSelect(){ // create and draw new combo box } void onUnselect(){ // remove drawn combo box } } // another class inhereting the abstract class class ComboBoxOption: public ComboBoxItem{ public: // implementing the pure virtual function void onSelect(){ // do work or nothing } void onUnselect(){ // Undo work } } class ComboBox{ private: ComboBoxItem[] myItems; public: ComboBox(ComboBoxItem[] items); void onItemSelect(ComboBoxItem selectedItem, ComboBoxItem previousItem){ previousItem.onUnselect(); selectedItem.onSelect(); } }

Du kan då skapa en ComboBox med en mix av "ComboBoxBranchCreator" och "ComboBoxOption", och då göra olika saker beroende på vad det är för objekt som väljs.

Nja. Jag tror det är lite mer komplicerat än så.
Det jag har gjort för att läsa problemet är att använda mig av GUI och strukturera upp så att ett visst område har speciella ComboBoxar som bara tjänar ett visst syfte. Beroende på vad jag väljer, så finns det bara en grupp ComboBoxar som som kan bara göra vissa saker eller hålla i vissa objekt.

Om du undrar vad detta är så är det ImGui. Det är i C++. Det Finns CImGui också för C. Men det är bara en "wrapper" för C++ så man kan använda ImGui funktioner i C.

Jag gillar verkligen ImGui. Jag har aldrig haft en bra tid att skapa GUI applikationer i C++. Men ImGui ändrade allt på detta.

Permalänk
Medlem
Skrivet av heretic16:

Nja. Jag tror det är lite mer komplicerat än så.
Det jag har gjort för att läsa problemet är att använda mig av GUI och strukturera upp så att ett visst område har speciella ComboBoxar som bara tjänar ett visst syfte. Beroende på vad jag väljer, så finns det bara en grupp ComboBoxar som som kan bara göra vissa saker eller hålla i vissa objekt.

https://i.ibb.co/m95s2mf/Sk-rmbild-2023-06-21-231443.png

Om du undrar vad detta är så är det ImGui. Det är i C++. Det Finns CImGui också för C. Men det är bara en "wrapper" för C++ så man kan använda ImGui funktioner i C.

Jag gillar verkligen ImGui. Jag har aldrig haft en bra tid att skapa GUI applikationer i C++. Men ImGui ändrade allt på detta.

Jag skulle nog lösa det som jag skrev ovan med interfaces.