Optymizacja zlozonego loop'a.

0

Panowie, kodze sobie ostatnio po godzinach w Javie, pewien projekt i w jednej z metod urodzil mi sie zapierajacy dech w piersiacrh koszmarek. W php biorac pod uwage mozliwosc dynamicznego deklarowania zmiennych, zrobienie w kodzie ponizej nie stanowiloby problemu, no ale to Java.

Jakies sugestie jak mozna by to "spakowac" tak zeby az tak nie "walilo po oczach"?

    public void run()
    {
        this.settingsDataStorage.setSprocess("train");

        initStaticLoopers();

        List<List<Integer>> alIterations = settingsDataStorage.getAlOptimizationIterations();

        this.networkResultsCollector.init();

        int s00number = alIterations.get(0).size();
        for (int s00 = 0; s00 < s00number; s00++) {
            int i00 = 0; int i00number = alIterations.get(0).get(s00);
            while(alLoopers.get(0).setSettings(0, s00, i00, i00number) < i00number){

                i00++;

                initDynamicLoopers();

                alIterations = settingsDataStorage.getAlOptimizationIterations();

                int s01number = alIterations.get(1).size();
                for (int s01 = 0; s01 < s01number; s01++) {
                    int i01 = 0; int i01number = alIterations.get(1).get(s01);
                    while(alLoopers.get(1).setSettings(1, s01, i01, i01number) < i01number){

                        i01++;

                        int s02number = alIterations.get(2).size();
                        for (int s02 = 0; s02 < s02number; s02++) {
                            int i02 = 0; int i02number = alIterations.get(2).get(s02);
                            while(alLoopers.get(2).setSettings(2, s02, i02, i02number) < i02number){

                                i02++;

                                int s03number = alIterations.get(3).size();
                                for (int s03 = 0; s03 < s03number; s03++) {
                                    int i03 = 0; int i03number = alIterations.get(3).get(s03);
                                    while(alLoopers.get(3).setSettings(3, s03, i03, i03number) < i03number){

                                        i03++;

                                        this.networkDataStorage.initResultsCollections();

                                        int s04number = alIterations.get(4).size();
                                        for (int s04 = 0; s04 < s04number; s04++) {
                                            int i04 = 0; int i04number = alIterations.get(4).get(s04);
                                            while(alLoopers.get(4).setSettings(4, s04, i04, i04number) < i04number){

                                                i04++;

                                                int s05number = alIterations.get(5).size();
                                                for (int s05 = 0; s05 < s05number; s05++) {
                                                    int i05 = 0; int i05number = alIterations.get(5).get(s05);
                                                    while(alLoopers.get(5).setSettings(5, s05, i05, i05number) < i05number){

                                                        i05++;

                                                        int s06number = alIterations.get(6).size();
                                                        for (int s06 = 0; s06 < s06number; s06++) {
                                                            int i06 = 0; int i06number = alIterations.get(6).get(s06);
                                                            while(alLoopers.get(6).setSettings(6, s06, i06, i06number) < i06number){

                                                                i06++;

                                                                int s07number = alIterations.get(7).size();
                                                                for (int s07 = 0; s07 < s07number; s07++) {
                                                                    int i07 = 0; int i07number = alIterations.get(7).get(s07);
                                                                    while(alLoopers.get(7).setSettings(7, s07, i07, i07number) < i07number){

                                                                        i07++;

                                                                        int s08number = alIterations.get(8).size();
                                                                        for (int s08 = 0; s08 < s08number; s08++) {
                                                                            int i08 = 0; int i08number = alIterations.get(8).get(s08);
                                                                            while(alLoopers.get(8).setSettings(8, s08, i08, i08number) < i08number){

                                                                                i08++;

                                                                                int s09number = alIterations.get(9).size();
                                                                                for (int s09 = 0; s09 < s09number; s09++) {
                                                                                    int i09 = 0; int i09number = alIterations.get(9).get(s09);
                                                                                    while(alLoopers.get(9).setSettings(9, s09, i09, i09number) < i09number){

                                                                                        i09++;

                                                                                        int s10number = alIterations.get(10).size();
                                                                                        for (int s10 = 0; s10 < s10number; s10++) {
                                                                                            int i10 = 0; int i10number = alIterations.get(10).get(s10);
                                                                                            while(alLoopers.get(10).setSettings(10, s10, i10, i10number) < i10number){

                                                                                                i10++;

                                                                                                int s11number = alIterations.get(11).size();
                                                                                                for (int s11 = 0; s11 < s11number; s11++) {
                                                                                                    int i11 = 0; int i11number = alIterations.get(11).get(s11);
                                                                                                    while(alLoopers.get(11).setSettings(11, s11, i11, i11number) < i11number){

                                                                                                        i11++;

                                                                                                        int s12number = alIterations.get(12).size();
                                                                                                        for (int s12 = 0; s12 < s12number; s12++) {
                                                                                                            int i12 = 0; int i12number = alIterations.get(12).get(s12);
                                                                                                            while(alLoopers.get(12).setSettings(12, s12, i12, i12number) < i12number){

                                                                                                                i12++;

                                                                                                                trainNetwork(i12);
                                                                                                            }
                                                                                                        }
                                                                                                    }
                                                                                                }
                                                                                            }
                                                                                        }
                                                                                    }
                                                                                }
                                                                            }
                                                                        }
                                                                    }
                                                                }
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }

                                        networkResultsCollector.writeResultsToFile();
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }

        networkResultsCollector.writeResultsCompactedToFile();
    }
1

Zapodałeś mocny trójkąt forów :)

6

Tu problemem nie jest Java, tylko brak umiejętności programowania. W php wyglądałoby równie tragicznie i nie dałoby się tego tknąć. Nikt nie będzie za Ciebie tego refaktorowal, tym bardziej, że brak totalnych podstaw, np. nazwy zmiennych.

Przeczytaj Clean Code, to będzie dla Ciebie boost w karierze.

1

Arrow anti-pattern

A poza tym to np. zamiast pisac List<List<Integer>> mozesz jak czlowiek napisac var allIterations =.

2

jak mozna by to "spakowac"

Ciężko powiedzieć bo kod jest zupełnie nieczytelny i nie wiadomo co chciałeś tam osiągnąć i co to w ogóle robi. Jakieś zmienne s01, s02, i01, i02 WTF? Na szybko patrząc to można by te wszystkie copy-paste zwinąć w jedną funkcje rekurencyjną chociażby, ale jestem pewien że da się nawet prościej bo te alIterations.get(10).size() sugerują ze zamiast copypaste można by tam mieć zwykłą pętle...
Ale niestety zeby to poprawić to trzeba najpierw jasno opisać co ten kod miał za zadanie robić.

2

Orzesz w morde. Ma chłop rozmach :D

0

OK, ja się na Javie nie znam, ale jak już przedmówcy zauważyli, kluczową kwestią jest, żebyś podał, co ten kod ma robić. Opisz np. w punktach. Zawrzyj wszystkie szczegóły – zarówno, co robi cała funkcja, jak i co robią poszczególne pętle, fragmenty itd.

6

W zasadzie sprawa jest prosta.
Funkcja przyjmuje nic, zwraca void. Czyli nie robi nic.
Upraszczamy do takiej postaci:

public void run() {
}

I gotowe.

Bardziej doświadczeni programiści java, wiedzą jednak, że pewnie chodziło o coś w tym stylu:

public void run() {
    throw new NullPointerException("I tak by się to tak skończyło, nie ma się co męczyć");
}
1

Nie umiem odszyfrować, co ten for w forze w forze w ... w forze przedstawia, za co odpowiadają poszczególne poziomy zagnieżdżenia (01 i tym podobne też nic nie mówią) ani ogólnie co to ma robić. Nie mam również pojęcia, co ma do tego dynamiczne typowanie / "dynamiczna deklaracja zmiennych" :(

Jeśli bardzo chcesz zamaskować fakt, że masz milion poziomów zagnieżdżenia i dodatkowo da się jakoś logicznie uzasadnić, że poziom zagnieżdżenia N różni się czymś (poza zmienną, po której iterujesz) od poziomu N-1, na pewno możesz pochować poziomy zagnieżdżenia po pomocniczych metodach... Ale w ten sposób radzisz sobie z trupem wylatującym z szafy przez poćwiartowanie go i poupychanie w szufladach.

A tak poza tym, chyba dążysz do porządnego refaktoringu, a nie optymalizacji :)

A jeśli dobrze mi się zdaje, co widzę, jest spora szansa że te pętle są zagnieżdżone zupełnie bez sensu. Masz 12 elementów czegoś, więc potrzebujesz 12 poziomów zagnieżdżenia - co, gdyby było ich 100? Co, gdyby każdy iterowany zbiór / tablica / kolekcja ze 100 miały tylko po 2 elementy? miałbyś 2^100 iteracji, czyli z grubsza 1 000 000 000 000 000 000 000 000 000 000, a w praktyce jeszcze trochę więcej. Nie jesteś w stanie przepisać tego kodu tak, by miał 1 - no góra 2 pętle zamiast N=12 wymiarów?

1

Opowiedz co to robi.

0

@Shalom:
W skrocie jest to "silnik" dla sieci neuronowej. Normalnie wszystkie parametry sieci podajesz statycznie i odpalasz algorytm i czekasz na wynik. Natomiast w przypadku tego kodu, zarowno architektura sieci, jak i wszystkie niezbedne parametry, lacznie z formatowaniem danych, zakresami danych itp itd do obrobki moga byc przygotowywane dynamicznie. Zatem masz tzw looper'y, ktorych kolejnosc ustawiane w settingu ktore przygotowuja (dynamicznie lub statycznie w zaleznosci od looper'a) konkretne wartosc ustawien tzn, zakresu danych, elementow architektury sieci itp itd, po to by w "oku cyklonu" tego koszmarka odpalic siec metoda:

trainNetwork(i12);

Aplikacja jest konsolowa wiec run niekoniecznie musi mi cokolwiek zwracac, poza tym wyniki zapisywane sa do pliku, a biezacy status wyswietla w konsoli. To tak z grubsza, jesli caly czas zbyt pobieznie to chetnie dopowiem.

0
spartan24 napisał(a):

@Shalom:

W skrocie jest to "silnik" dla sieci neuronowej. Normalnie wszystkie parametry sieci podajesz statycznie i odpalasz algorytm i czekasz na wynik. Natomiast w przypadku tego kodu, zarowno architektura sieci, jak i wszystkie niezbedne parametry, lacznie z formatowaniem danych, zakresami danych itp itd do obrobki moga byc przygotowywane dynamicznie. Zatem masz tzw looper'y, ktorych kolejnosc ustawiane w settingu ktore przygotowuja (dynamicznie lub statycznie w zaleznosci od looper'a) konkretne wartosc ustawien tzn, zakresu danych, elementow architektury sieci itp itd, po to by w "oku cyklonu" tego koszmarka odpalic siec metoda:

ale po co to ma 12 poziomów zagnieżdżenia pętli? Jakie znowu loopery? o.O Po czym tak naprawdę iterujesz, co zawierają te poszczególne cośtam(0), cośtam(1)?

Masz sobie sieć neuronową. Sieć ma warstwy, neurony, połączenia między neuronami. Dostaje dane na wejściu, przetwarza je i wypluwa coś na wyjściu.

Parametry (wagi połączeń) jesteś w stanie przedstawić jako macierze połączeń między poszczególnymi warstwami. Czyli masz tyle tych macierzy, ile warstw (nie licząc wejściowej). Czyli masz kilka, może kilkanaście macierzy reprezentujących stan / konfigurację jednej sieci neuronowej.

Teraz jeszcze potrzebujesz zbiór danych, który podzielisz na zbiory uczące, sprawdzające czy jak tam je zwał (zapomniało mi się).

Gdzie tu potrzebujesz aż 12 poziomów zagnieżdżenia?

1

Ok ok czyli robisz kupę nieczytelnego kodu żeby na koniec zawołać trainNetwork(i12); które absolutnie nic nie mówi i pracuje na jakichś globalach? To jest na poważnie? Niestety ale mój werdykt jest taki ze nie da się tego poprawić tylko trzeba go zaorać do gołej ziemi i przepisać od nowa. Tym razem z głową i bez globali. Ad uczelnia sieci o dowolnej strukturze i parametrach to https://github.com/Pharisaeus/Neural nie jest to może kanon piękna, pisane 100 lat temu na studiach, ale myśle że nadal jest wielokrotnie bardziej czytelne i train network wygląda tak: https://github.com/Pharisaeus/Neural/blob/master/NeuralNetwork/pl/edu/agh/neural/learning/backpropagation/BackpropagationLearning.py#L13 ;]

0

@Shalom: Nie na globalach. To jest jedynie jedna z metod pewnej klasy. W moim pytaniu istota nie jest architektura calej aplikacji ale sposob poradzenia sobie z tak zagniezdzonymi loop'ami w specyfice jezyka jakim jest Java.

Jeszcze raz. Mamy szereg czynnikow ktore maja wplyw na dzialanie sieci: ilosc wartsw, ilosc inputow, ilosc outpuow, rodzaje funkcji aktywacji, sposob inicjacji wag, zakresy danych pobierane do treningu, werifykacji i testu. Kazdy z tych elementow normalnie podawany jest statycznie, tzn np ilosc warstw 3, ilosc inputow 5, ilosc output'ow 1 itp itd.
Podawania tych wszystkich wartosc recznie i odpalanie sieci, ponowne podawanie i odpalanie jest delikatnie mowiac malo efektywne.
Mozna zajac sie tym dynamicznie tzn np w przypadku architektury sieci ustawic kolejne zmiany architektury zaczynajac od 3 potem 4,5,6 konczac np 10 warstwach. Generowaniem tych konkretnych wartosci zamuja sie looper'y, zatem przykladowo ilosc warstw moze rosnac np liniowo, lub byc modyfikowana biorac pod uwage aktualny wynik nauczania. Tak ja wspominalem wczesniej zbierane jest to wszystko do kupy i odpalane w oku cyklonu.

0

W moim pytaniu istota nie jest architektura calej aplikacji ale sposob poradzenia sobie z tak zagniezdzonymi loop'ami w specyfice jezyka jakim jest Java

Ale ze co ma do tego Java?

Jesli uwazasz, ze w PHP nie trzeba deklarowac zmiennych to sprobuj sobie uzyc niezadeklarowanej zmiennej :)

0

@spartan24: Dzięki za ten opis, który już zamieściłeś. Jednak ponawiam swoją sugestię: opisz ze szczegółami, co robią poszczególne pętle i inne fragmenty kodu, które można wyodrębnić logicznie. Np. w punktach. Punktów może być dowolna ilość o dowolnym poziomie zagnieżdżenia. Chodzi mi o to, żeby reprezentacja algorytmu reprezentowanego przez tę funkcję była inna niż kod w Javie. (Nie znam się na sieciach neuronowych, więc przepraszam, jeśli ta sugestia nie jest trafna).

1
spartan24 napisał(a):

@Shalom: Nie na globalach. To jest jedynie jedna z metod pewnej klasy. W moim pytaniu istota nie jest architektura calej aplikacji ale sposob poradzenia sobie z tak zagniezdzonymi loop'ami w specyfice jezyka jakim jest Java.

Jeszcze raz. Mamy szereg czynnikow ktore maja wplyw na dzialanie sieci: ilosc wartsw, ilosc inputow, ilosc outpuow, rodzaje funkcji aktywacji, sposob inicjacji wag, zakresy danych pobierane do treningu, werifykacji i testu. Kazdy z tych elementow normalnie podawany jest statycznie, tzn np ilosc warstw 3, ilosc inputow 5, ilosc output'ow 1 itp itd.
Podawania tych wszystkich wartosc recznie i odpalanie sieci, ponowne podawanie i odpalanie jest delikatnie mowiac malo efektywne.

Ok, zdajesz sobie sprawę że nawet wyuczenie sieci dla jednego zestawu tych parametrów może chwilę zająć? Co dopiero gdy spróbujesz przebić się przez wszystkie kombinacje np.

  • 4 różne liczby warstw sieci
  • 3 różne liczby neuronów w każdej z podwarstw (tylko tu możesz mieć 3^N możliwości!)
  • najlepiej to jeszcze K różnych algorytmów uczenia sieci
  • 5 różnych funkcji aktywacji

Chyba nie muszę wymieniać dalej? ;)

Mozna zajac sie tym dynamicznie tzn np w przypadku architektury sieci ustawic kolejne zmiany architektury zaczynajac od 3 potem 4,5,6 konczac np 10 warstwach. Generowaniem tych konkretnych wartosci zamuja sie looper'y, zatem przykladowo ilosc warstw moze rosnac np liniowo, lub byc modyfikowana biorac pod uwage aktualny wynik nauczania. Tak ja wspominalem wczesniej zbierane jest to wszystko do kupy i odpalane w oku cyklonu.

czyli te Twoje loopery to te kosmiczne 12 pętli w pętlach w pętlach? To nie zadziała.

to ze w php zrobienie czegos takiego to raptem 2 petle, zagniezdzone jedna w drugiej, a w Javie nie mam pojecia jak to zrobic, dlatego pytam.

Dalej nie wiemy co tak naprawdę chcesz zrobić. Dla mnie terminologia loopery i oko cyklonu to jakieś dziwne wymysły, które nic mi nie mówią - nigdy nie spotkałem się z podobną terminologią, może poza filmami katastroficznymi pokroju Sharknado.

Jak dla mnie to możesz chcieć sprawdzić te N^12 kombinacji jakichś ustawień, a możesz siłować się z iterowaniem po entry-secie mapy, której używałeś w PHP i nazwałeś to dynamicznym deklarowaniem zmiennych, a w Javie nie znalazłeś odpowiednika. A może chodzi o coś innego. Nie wiem, bo używasz niezrozumiałego słownictwa, którego najprawdopodobniej nikt poza Tobą nie używa.

@Shalom: jest jakas szansa, ze w koncu ktos zacznie mowic na temat?

Wyobraź sobie, że przyszedłem do Ciebie, bo mam problem z upieczeniem tortu. Zamiast mówić o świeczkach, mówię o płonących pochodniach albo źródełkach światła, jak pytasz dlaczego chcę kupić 5 piekarników to tłumaczę, że tort z cukierni miał 4 warstwy przełożone kremem, ale jak ktoś chciał to mógł mieć 5 albo 3. A potem zaczynam się wpieniać, że mówisz nie na temat :)

0

@superdurszlak: wszystko smiga bez zarzutu, oczywiscie ograniczenia wynikaja z mozliwosci sprzetu i zakresu zarowno podawanych danych jak i generowanych kombinacji ustawien.
Zatem nie mam problemu z dzialaniem kodu, a jedynie koszmarnymi loop'ami.
Poza tym po kiego te wszystkie wycieczki do PHP, tu jest mowa o Javie i o mozliwosci optymizacji tego kodu. Reasumujac nie masz pojecia jak sobie z tym poradzic i na tym poprzestanmy. Jesli sprawia ci przyjemnosc podnoszenie mi cisnienia jestem na kilku watkach na flame'ie tam sie mozemy rozmowic, tutaj nawet nie bede reagowal bo nie po to tu jestem.

0

@everybody: nie odpowiadam na suche teksty.
Poczekam jeszcze na @Shalom'a jesli nie da rady nic zrobic, temat beda uwazal za zamkniety.

0

Poza tym po kiego te wszystkie wycieczki do PHP, tu jest mowa o Javie i o mozliwosci optymizacji tego kodu. Reasumujac nie masz pojecia jak sobie z tym poradzic i na tym poprzestanmy. Jesli sprawia ci przyjemnosc podnoszenie mi cisnienia jestem na kilku watkach na flame'ie tam sie mozemy rozmowic, tutaj nawet nie bede reagowal bo nie po to tu jestem.

Uwazasz ze problem jest w Javie. Zatem staramy sie wspolnie go znalezc. Poki co to nie powiedziales jeszcze ZADNYCH konkretow. Tylko jakies ogolniki pokroju w specyfice jezyka jakim jest Java.

Zauwaz ze jesli zidentyfikujemy Twoj problem to byc moze sie okaze Ty po prostu czegos nie rozumiesz i wyjasnienie Ci tego bedzie rozwiazaniem problemu.

Zatem jak bys to zrobil w PHP i dlaczego tak nie mozesz w Javie?

Bo roznica pokroju $i = 5 vs int i = 5 to nie jest powod do robienia 300 petli.

0

W moim pytaniu istota nie jest architektura calej aplikacji ale sposob poradzenia sobie z tak zagniezdzonymi loop'ami w specyfice jezyka jakim jest Java.

Ja bym zaczął od jakiegoś takiego cudaka:

import java.util.Collections;
import java.util.List;
import java.util.function.BiFunction;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

// bloatware, to można chwilowo zignorować

class NetworkConfiguration {
    private final int inputs;
    private final int outputs;
    private final int layers;
    private final String label;

    NetworkConfiguration(int inputs, int outputs, int layers, String label) {
        this.inputs = inputs;
        this.outputs = outputs;
        this.layers = layers;
        this.label = label;
    }

    @Override
    public String toString() {
        return "NetworkConfiguration{" +
                "inputs=" + inputs +
                ", outputs=" + outputs +
                ", layers=" + layers +
                ", label='" + label + '\'' +
                '}';
    }

    public static Builder builder() {
        return new Builder();
    }

    static class Builder {
        private int inputs;
        private int outputs;
        private int layers;
        private String label;

        public Builder withInputs(Integer inputs) {
            this.inputs = inputs;
            return this;
        }

        public Builder withOutputs(Integer outputs) {
            this.outputs = outputs;
            return this;
        }

        public Builder withLayers(Integer layers) {
            this.layers = layers;
            return this;
        }

        public Builder withLabel(String label) {
            this.label = label;
            return this;
        }

        public Builder copy() {
            return builder()
                    .withInputs(inputs)
                    .withOutputs(outputs)
                    .withLayers(layers)
                    .withLabel(label);
        }

        public NetworkConfiguration build() {
            return new NetworkConfiguration(inputs, outputs, layers, label);
        }
    }
}

public class Looper {

// to jest ważne!
    public <T> List<NetworkConfiguration.Builder> generate(List<NetworkConfiguration.Builder> templates,
                                                           List<T> values,
                                                           BiFunction<NetworkConfiguration.Builder, T, NetworkConfiguration.Builder> setter) {
        return templates
                .stream()
                .flatMap(template -> values
                        .stream()
                        .map(value -> setter.apply(template.copy(), value))
                )
                .collect(Collectors.toList());
    }

    public static void main(String[] args) {
// tak można tego używać
        Looper looper = new Looper();
        NetworkConfiguration.Builder starter = NetworkConfiguration.builder();
        List<Integer> inputs = IntStream.range(0, 10).boxed().collect(Collectors.toList());
        List<NetworkConfiguration.Builder> withInputs= looper.generate(Collections.singletonList(starter), inputs, NetworkConfiguration.Builder::withInputs);
        List<Integer> outputs = IntStream.range(10, 20).boxed().collect(Collectors.toList());
        List<NetworkConfiguration.Builder> withOutputsAndInputs = looper.generate(withInputs, outputs, NetworkConfiguration.Builder::withOutputs);

        withOutputsAndInputs.forEach(x -> System.out.println(x.build()));
    }
}

Masz jedną magiczną funkcje która generuje konfiguracje sieci na podstawie listy konfiguracji wypełniając jeden z podanych parametrów wartościami.
Można by tam pewnie xakep-style wywalic te collecty i lecieć wszystko gołymi streamami ale nie chce mi się teraz mysleć.

I teraz te twoje 70 zagnieżdżonych pętli załatwia takie:

List<Integer> outputs = IntStream.range(10, 20).boxed().collect(Collectors.toList());
looper.generate(withInputs, outputs, NetworkConfiguration.Builder::withOutputs)

edit: mały fix

    public <T> Stream<NetworkConfiguration.Builder> generate(Stream<NetworkConfiguration.Builder> templates,
                                                             List<T> values,
                                                             BiFunction<NetworkConfiguration.Builder, T, NetworkConfiguration.Builder> setter) {
        return templates
                .flatMap(template -> values
                        .stream()
                        .map(value -> setter.apply(template.copy(), value))
                );
    }

    public static void main(String[] args) {
        Looper looper = new Looper();
        NetworkConfiguration.Builder starter = NetworkConfiguration.builder();
        List<Integer> inputs = IntStream.range(0, 10).boxed().collect(Collectors.toList());
        Stream<NetworkConfiguration.Builder> withInputs = looper.generate(Stream.of(starter), inputs, NetworkConfiguration.Builder::withInputs);
        List<Integer> outputs = IntStream.range(10, 20).boxed().collect(Collectors.toList());
        Stream<NetworkConfiguration.Builder> withOutputsAndInputs = looper.generate(withInputs, outputs, NetworkConfiguration.Builder::withOutputs);
        List<String> labels = Arrays.asList("ala", "ma", "kota");
        Stream<NetworkConfiguration.Builder> withOutputsAndInputsAndLabels = looper.generate(withOutputsAndInputs, labels, NetworkConfiguration.Builder::withLabel);

        withOutputsAndInputsAndLabels.forEach(x -> System.out.println(x.build()));
    }

Teraz już na streamach bez zbędnych collectów. I w wersji na hackera:

        Looper looper = new Looper();
        List<Integer> inputs = IntStream.range(0, 10).boxed().collect(Collectors.toList());
        List<Integer> outputs = IntStream.range(10, 20).boxed().collect(Collectors.toList());
        List<String> labels = Arrays.asList("ala", "ma", "kota");

        Stream<NetworkConfiguration> configurations = looper.generate(
                looper.generate(
                        looper.generate(
                                Stream.of(NetworkConfiguration.builder()), inputs, NetworkConfiguration.Builder::withInputs
                        ),
                        outputs, NetworkConfiguration.Builder::withOutputs
                ),
                labels, NetworkConfiguration.Builder::withLabel
        ).map(NetworkConfiguration.Builder::build);
1

Reasumujac nie masz pojecia jak sobie z tym poradzic

Owszem, przez analogię do przykładu z tortem - nadal nie wiem po co potrzebujesz aż pięciu piekarników, by upiec swój tort przekładany kremem. Nadal nie wyjaśniłeś, po co potrzebujesz aż 5 piekarników i nadal pieklisz się, że głąby z 4programmers nie rozumieją i nie chcą pomóc.

Jak chcesz to tak zostawić, spoko - pisz sobie choćby i 200 zagnieżdżonych pętli, na zdrowie. Tylko nie miej pretensji, że nikt nie chce Ci pomóc, skoro nie chcesz przedstawić problemu w zrozumiały sposób.

I nie, loopery, oka cyklonu i zmienne zmienna1, zmienna2, zmienna3 nie objaśniają problemu.

0

@Shalom: bardzo Ci dziekuje, przeanalizuje sobie kod, ktory zapodales.
Ile sie nalezy? Daj jakies namiary na paypala to Ci chociaz na dobre piwo przesle :D.
Mowie powaznie.

0

Panowie, kodze sobie ostatnio po godzinach w Javie, pewien projekt i w jednej z metod urodzil mi sie zapierajacy dech w piersiacrh koszmarek.

Ten kod wygląda, jakbyś tak naprawdę chciał napisać rekurencję, ale jakbyś się bał tego zrobić.

0
spartan24 napisał(a):

Panowie, kodze sobie ostatnio po godzinach w Javie, pewien projekt i w jednej z metod urodzil mi sie zapierajacy dech w piersiacrh koszmarek. W php biorac pod uwage mozliwosc dynamicznego deklarowania zmiennych, zrobienie w kodzie ponizej nie stanowiloby problemu, no ale to Java.

Jakies sugestie jak mozna by to "spakowac" tak zeby az tak nie "walilo po oczach"?

    public void run()

            PYRAMID OF DOOM

    }

OMG co to jest? Wygląda jak Final Boss Of Refactoring.

A tak na poważnie - masz tam sagment kodu powtarzający się na kolejnych zagnieżdżeniach - jeśli jest jakiś pattern wg którego zmieniają się parametry, to może zrób z tego f-cje rekurencyjną z odpowiednimi warunkami jej kontynuacji / stopu / ew. jej uruchamianej wersji?

P.S.
Ten potwór zepsuł nawet forum, jak kliknąłem wstecz w przegladarce to mi się jakiś megajson wyświetlił :D
screenshot-20210308232011.png

3

Po pierwsze gratuluję OP wkręcenia @Shalom'a.

Po drugie, jeśli chodziło o test które fragmenty będą najbardziej wk...ce dla przyszłych inżynierów wsparcia, to ja głosuję na:

  • kreatywne literówki ("getAlOptimizationIteration", "alIterations", "setSprocess")
  • set z get ("setSettings")
  • stosowanie anonimowych zmiennych ("s07number")

Sugerowałbym zmianę nazwy metody "trainNetwork" bo jest trochę zbyt oczywista.

0

Nigdy nie wypowiadałem się w Javie ( Nie kodze, bo nie umiem i nie lubię :( ), ale ta ilość zagnieżdżeń mnie mocno zaintrygowała - Nigdy takowej nie widziałem. Mimo wszystko to szacunek dla autora, że miał cierpliwość w "rysowaniu" takiego trójkąta :D

1 użytkowników online, w tym zalogowanych: 0, gości: 1