Maksymalne wykorzystanie możliwości komputera do obliczeń

0

Mam 7 lub 8 parametrów, których wartość musi się mieścić w zakresie <1; 200>. Wszystkie są użyte w jednym równaniu. Chciałbym policzył dla jakich wartości tych parametrów działanie będzie miało największy wynik. W tym celu zrobiłem 7 pętli for parametr_n := 1 to 200 do. Każda kolejna jest wpisana w poprzednią, a w ostatniej jest działanie. O ile sam program działa dobrze, bo sprawdziłem to na mniejszym zakresie to po prostu strasznie wolno to oblicza. Zresztą na mniejszym zakresie trwało to ponad pół godziny, W końcu jest to bardzo dużo obliczeń. Chciałbym zapytać czy można w jakiś sposób to przyśpieszyć? Program po uruchomieniu zużywa ok 12-15% procesora i 2 MB pamięci. Co ważne, ten program jest tylko pomocniczy dla mnie i nie ma być uruchamiany na innym komputerze. Więc chciałbym wykorzystać możliwości mojego w jak największym stopniu.

0

Wielowątkowość albo OpenCL

0

Najlepiej jakbyś pokazał szczegóły problemu. Jak wyglądają te równania, jaką wartość masz maksymalizować itp.
Po tym się okaże jak najlepiej do tego podejść: siłowo (OpenCL) czy może miękko (algorytm genetyczny), a może jakaś inna prosta metoda optymalizacji (np Newtona).

2

Szybkie wyliczenie dla 7 parametrów, 2007 = 12800000000000000 = 12 800 000 miliardów
Gdyby więc twoje równanie dało się policzyć w ciągu 1 taktu procesora a twój procesor miał 5GHz to zajęłoby to 2560000 sekund czyli 30 dni.
Gdyby parametrów było 8 to zajęłoby to oczywiście 200 razy dłużej. Powodzenia.

Miej na uwadze że twój procesor zapewne ma ~3GHz a wyliczenie równania zajmuje przynajmniej kilkadziesiąt taktów, a może i kilkaset, zależnie od poziomu skomplikowania. Więc realnie czas obliczeń będzie przynajmniej o rząd/dwa rzędy wielkości większy...

0

Jakiś algorytm genetyczny powinien dać dobrą heurezę.

1

Pytanie czy funkcja, która jest wyliczana może zostać przetransformowana zgodnie z zasadą:

F(a_{1}, ... , a_{n}) = \sum\limits_{i=1}^n G_{i}(a_{i})

inaczej mówiąc czy można ją pociąć na sumę funkcji o mniejszej ilości parametrów.

0
MarekR22 napisał(a):

Najlepiej jakbyś pokazał szczegóły problemu. Jak wyglądają te równania, jaką wartość masz maksymalizować itp.
Po tym się okaże jak najlepiej do tego podejść: siłowo (OpenCL) czy może miękko (algorytm genetyczny), a może jakaś inna prosta metoda optymalizacji (np Newtona).

Wartosc := ((A / 100) * (SumaD - SumaM)) + ((B / 100) / CiagD * CiagM) + ((C / 100) * SumaM) + ((D / 100) * SumaD) + ((E / 100) / Maks * CiagM) + ((F / 100) * (0.25 - SumaM));

To jest działanie. Zmienne A-F to parametry które muszę obliczyć, tak aby Wartosc była największa. Na razie jest to 6 parametrów. To jest minimalna ilość, aby mogło zadziałać. Ale optymalnie by było dołożyć jeszcze 1 może dwa.

Tak, wiem, że jest to bardzo dużo obliczeń i zdaje sobie sprawę z tego, że może to długo potrwać. Nie liczę na wynik w ciągu kilku sekund. Ale też czekanie kilkudziesięciu dni wydaje mi się przesadą. Jedyne co mogę zmienić to jeszcze zakres dla każdego parametru z 200 do 150. Mimo wszystko jeśli się okaże, że nie będzie możliwe policzenie tego w szybszym tempie to będę musiał znaleźć inny sposób.

0

@dani17 moje obliczenia były dla bardzo optymistycznego przypadku, realnie spodziewałbym się że potrwa to przynajmniej z rok ;)

Prosty przykład: jeśli twoje obliczenia dla 6 parametrów wykonywałyby się w ciągu 1 sekundy to obliczenia dla 7 parametrów w 3,5 minuty a dla 8 prawie 12 godzin. Oczywiście nie ma takiej możliwości bo żeby obliczenia dla 6 parametrów trwały 1 sekundę potrzebowałbyś procesora z zegarem 64 000 GHz liczącego całe to wyrażenie w 1 takcie ;)

A czym są te wartości SumaD, SumaM, CiagD itd. One są zależne od parametrów jak rozumiem?

0

To są zmienne, obliczone z innej części na podstawie danych wprowadzonych przeze mnie.

W momencie uruchomienia funkcji która próbuje napisać one są już stałe i się nie zmieniają. Zmieniać maja się tylko parametry A-F, no i oczywiście Wartosc.

1

Żartujesz sobie? Bo ja tu w takim razie widzę wyrażenie:
wynik = f(A) + g(B) + h(C) + ...
Którego maksimum zawsze będzie sumą maksimów poszczególnych funkcji. Chyba że ja czegoś nie widzę... Co więcej tak na oko to każda z tych funkcji jest silnie monotoniczna i ma tylko dwa ekstrema -> dla mininalnej i dla maksymalnej wartości parametru. Jeśli ta druga część którą sobie wyliczasz wcześniej jest dodatnia do maksiumum występuje dla największej wartości parametru a jeśli ujemna to maksimum uzyskasz dla mininalnej wartości parametru.

No bo przecież jak znajdziesz maksimum f(A) = ((A / 100) * (SumaD - SumaM)) to masymalna suma Wartosc ZAWSZE będzie zawierać maksimum tej funkcji. A f(A) ma przecież postać: A*stała/100 czyli de facto A/stała więc siłą rzeczy ma wartość maksymalną dla dużego A o ile stała jest dodatnia, lub dla małego A jeśli stała jest ujemna.

0

Okej, może trochę za bardzo chciałem to uprościć.
Mam nadzieję, że teraz wyjaśnię prawidłowo. Jednak obawiam się, że wyjdzie na to, że tego liczenia będzie jeszcze więcej. Zarówno Wartosc i jak i zmienne wyliczone w innej funkcji mają być tablicami 4-elementowymi. Co więcej takich tablic jest n. n zależy od wcześniejszych danych. Dodatkowo mam tablicę Wyniki. Jest ona n-elementowa, typu Integer. Tam znajdują się dane z pliku. Tak na prawdę parametry A-F muszą być policzone dla jak największej zmiennej Suma. Suma jest zwiększana jeżeli Wynik[n] jest... ciężko to jakoś rozsądnie wyjaśnić :/ Spróbuję przedstawić to lepiej w kodzie

Suma := 0; 
for M := 1 to IloscWynikow do
  begin
    NajwiekszaWartosc := 0;
    for N := 1 to 4 do
      TabliceWartosci[M].Wartosc[N] := ((A / 100) * (TabliceZmiennych[M].SumaD[N] - TabliceZmiennych[M].SumaM[N])) + ((B / 100) / TabliceZmiennych[M].CiagD[N] * TabliceZmiennych[M].CiagM[N]) + ((C / 100) * TabliceZmiennych[M].SumaM[N]) + ((D / 100) * TabliceZmiennych[M].SumaD[N]) + ((E / 100) / TabliceZmiennych[M].Max[N] * TabliceZmiennych[M].CiagM[N]) + ((F / 100) * (0.25 - TabliceZmiennych[M].SumaM[N]));
    for N := 1 to 4 do
      if TabliceWartosci[M].Wartosc[N] > NajwiekszaWartosc then
        NajwiekszaWartosc := TabliceWartosci[M].Wartosc[N];
    for N := 1 to 4 do
      if TabliceWartosci[M].Wartosc[N] = NajwiekszaWartosc then
        if N = Wyniki[M] then
          Inc(Suma);
  end;
if Suma > SumaMax then
  begin
    SumaMax := Suma;
    ZapiszParametry;
  end;

Tak wygląda kod. jest on wpisany w pętle for F := 1 to 200 do...

4

No dobra, ale to zupełnie nie zmienia tego co napisałem powyżej. Nie ma sensu robić tu żadnych chorych pętli z testowaniem wszystkich możliwości, bo całe to twoje wyrażenie jest sumą wartości NIEZALEŻNYCH funkcji. Więc wystarczy dla każdej z nich z osobna znaleźć maksimum i tyle. Może wyjaśnie ci na przykladzie:
Mamy funkcję która ma 3 parametry: f(x,y,z) = x+y+z. Parametry mogą przyjmować wartości od 0 do 1000. A ty teraz próbujesz puścić 3 zagnieżdżone pętle żeby znaleźć maksimum tej funkcji.
Pierwsza obserwacja jest taka że twoja funkcja jest sumą elementów zależnych tylko od jednego parametru, tzn f(x,y,z) = g(x) + h(y) + k(z). To znaczy że nie potrzeba żadnych zagnieżdżonych pętli bo maksimum funkcji f to będzie zawsze suma maksimów funkcji g, h i k.
Dzieje sie tak dlatego, że im większe liczby dodajesz tym większą sumę otrzymasz...
Druga obserwacja jest taka że każda z tych funkcji jest monotoniczna (w całym zadanym przedziale albo zawsze rośnie albo zawsze maleje) więc przyjmuje wartości skrajne na końcach przedziału w którym liczysz. Ekstrema mogą więc być tylko dla wartości 0 lub 1000. I zgadza sie to z rzeczywistością, każda z tych funkcji ma maksimum dla argumentu równego 1000 a minimum dla argumentu równego 0.

Wniosek? funkcja f ma maksimum dla x=1000, y=1000, z=1000. I żadne dziwne pętle ani lata obliczeń nie są do tego potrzebne. Wystarczy elementarna wiedza z zakresu analizy matematycznej.

1
public class MaxOfF {

	public static void main(String[] args) {

		double sumaD = 10;
		double sumaM = 11;
		double maxA = IntStream.rangeClosed(1, 20000)
				.mapToDouble((A) -> ((A / 100.) * (sumaD - sumaM)))
				.max().getAsDouble();
		double CiagD = 10;
		double CiagM = 11;
		double maxb = IntStream.rangeClosed(1, 20000)
				.mapToDouble((B) -> ((B / 100) / CiagD * CiagM))
				.max().getAsDouble();
		
		// i talej dla c, d, e, i f
		System.out.println(maxA + maxb);
	}

}

dla dwóch parametrów w za to w zakresie do 20k. Czas wykonania poniżej sekundy. Można to napisać naprawdę generycznie tak by szukało maksimów dla funkcji jednoargumentowej, ale to było by już robienie gotowca.

0

No, ale tak na prawdę zupełnie coś innego ja chce osiągnąć. Chodzi o to, że te zmienne wyliczone wcześniej znajdują się w tablicy czteroelentowej. A z kolei takich tablic jest n. SumaD[1] < > SumaD[2] < > SumaD[3] < > SumaD[4], chociaż tak na prawdę one wszystkie mogą się równać. Ale załóżmy, że n = 20. To SumaD będzie można powiedzieć tablica dwuwymiarową [20x4].

Główny problemem jest taki, że nie chce policzyć maksymalnej wartości, a maksymalna zgodność z tablicą Wyniki. Na prawdę cieżko jest mi to wytłumaczyć, dlatego spróbuje to jakby na przykładzie przedstawić.

M = 1
Wyniki[M] := 3
TablicaWartosci[M].Wartosc[1] := 10
TablicaWartosci[M].Wartosc[2] := 30
TablicaWartosci[M].Wartosc[3] := 20
TablicaWartosci[M].Wartosc[4] := 40

Największa wartość jest dla Wartosc[4]. A tablica Wyniki[M] wskazywała 3. W tej sytuacji zgodność jest 0. Jednak jeżeli będzie to się prezentowało tak:

TablicaWartosci[M].Wartosc[1] := 10
TablicaWartosci[M].Wartosc[2] := 20
TablicaWartosci[M].Wartosc[3] := 40
TablicaWartosci[M].Wartosc[4] := 30

To zgodność jest 1.
W tej drugiej sytuacji wynikiem maja być parametry A-F, które doprowadziły do policzenia tych wartości.

Oczywiście M w moim programie nie jest 1, tylko w chwili obecnej 67. Jednak jest to pewnego rodzaju baza, którą ciągle rozbudowuje.

dodanie znaczników <code class="delphi"> - @furious programming

0

Ustalmy fakty:

  • chcesz policzyc sobie największą wartość tego swojego wyrażenia dla parametrów A-F w zakresie 1-200, tak?
  • chcesz potem porównać policzoną wartość z jakąś zapisaną wartością?
  • chcesz zapamiętać parametry dla których te dwie wartości były zgodne?

To ja nadal nie rozumiem zupełnie twojego problemu. Ja ci od razu mogę powiedzieć że twoje wyrażenie ma ekstrema tylko dla skrajnych wartości A-F, tzn albo dla 1 albo dla 200. Więc nie ma sensu liczyć w pętlach żadnych. Nie ma mozliwości żebyś uzyskał wartość maksymalną wyrażenia z innymi wartościami parametrów.

0

Przede wszystkim, niepotrzebnie chciałem to uprościć.
Jesteś już trochę bliżej tego o co mi chodzi, ale chyba nadal to nie to. Tak na prawdę, ten kod, który przedstawiłem powie najwięcej. Słowami nie potrafię tego wyjaśnić niestety. Powiem, że sam w Excelu dopasowywałem te współczynniki w taki sposób, że ta zgodność o której pisałem wynosiła 60%. Jednak, żebym mógł użyć tego w programie musi wynosić powyżej 80%. Po pierwsze nie mam pewności że da się to w ogóle osiągnąć tym wzorem. Być może będę musiał go poprawić. Ale wydaje mi się, że po odpowiednim dopasowaniu tych współczynników będzie można to wyliczyć.

0
Shalom napisał(a):

Ustalmy fakty:

  • chcesz policzyc sobie największą wartość tego swojego wyrażenia dla parametrów A-F w zakresie 1-200, tak?
  • chcesz potem porównać policzoną wartość z jakąś zapisaną wartością?
  • chcesz zapamiętać parametry dla których te dwie wartości były zgodne?

To ja nadal nie rozumiem zupełnie twojego problemu. Ja ci od razu mogę powiedzieć że twoje wyrażenie ma ekstrema tylko dla skrajnych wartości A-F, tzn albo dla 1 albo dla 200. Więc nie ma sensu liczyć w pętlach żadnych. Nie ma mozliwości żebyś uzyskał wartość maksymalną wyrażenia z innymi wartościami parametrów.

Zaczynam z parametrami A-F równymi 1. Robię 67 pętli. Tyle ile mam "rekordów" w bazie.
Każda z 67 pętli ma wyliczyć Wartosci[1..4]. Jeżeli największa wartość ma taki indeks jak ten wskazany w tablicy Wyniki to Inc(Zgodnosc). Załóżmy, że przy tych parametrach udało się to 10 razy.

Teraz zwiększam ostatni parametr i znowu to samo. Zwiększam po kolei każdy kolejny do 200. Załóżmy, że każdy paramtre ma teraz różną wartość z zakresu <1; 200>. Ponownie robię 67 pętli. Tym razem indeks największej wartości jest zgodny z tym wskazanym przez tablice Wyniki 62 razy. A więc zapisuje parametry jako wynik.

Następnie dalej zwiększam parametry aż do momentu w którym wszystkie osiągną wartość 200. I za każdym razem robię 67 pętli. Jednak zgodność już ani razu nie jest na poziomie 62, przez co ostatecznym wynikiem jest ten z poprzedniego akapitu.

Na prawdę cieżko jest to wyjaśnić. Kod mówi najwięcej. I działa on prawidłowo. Tyle, że na liczbach w zakresie <1; 4>

Chce policzyć 4 wartości zapisane do tablicy. Następnie porównać indeks największej wartości z tym wskazanym przez tablice Wyniki. W tablicy Wyniki znajdują się tylko wartości od 1 do 4. Parametry chce zapisać jeśli ta zgodność będzie jak największa.
Mam wrażenie, że już zaczynam pisać to samo.

0

Ok z kodu wyczytuje że:

  • masz 4 zestawy jakichśtam "stałych" dla każdego z M zestawów danych
  • dla każdego zestawu stałych liczysz sobie wartość swojego wyrażenia
  • wybierasz maksimum z tych wartości
  • następnie dla każdego zestawu stałych dla którego wynikiem była maksymalna wartość wyrażenia sprawdzasz czy jego indeks (tego zestawu stałych) jest zgodny z takim zapisanym w jakiejś innej tablicy i jeśli tak podbijasz jakis licznik

W efekcie wiesz w ilu z M zestawów danych było tak, że indeks "stałych" dla których wartość była największa zgodził się z indeksem zapisanym gdzieśtam.

Tylko że z tego wynika że wcale nie interesują cie parametry A-F dające maksymalną wartość wyrażenia! Ciebie interesuje dla jakich parametrów połączenych ze stałymi z i-tej tablicy uzyskamy największą z 4 możliwych wartości kiedy tablica wyniki wskazuje na indeks i. Czy tak?

0
Shalom napisał(a):

Ok z kodu wyczytuje że:

  • masz 4 zestawy jakichśtam "stałych" dla każdego z M zestawów danych
  • dla każdego zestawu stałych liczysz sobie wartość swojego wyrażenia
  • wybierasz maksimum z tych wartości
  • następnie dla każdego zestawu stałych dla którego wynikiem była maksymalna wartość wyrażenia sprawdzasz czy jego indeks (tego zestawu stałych) jest zgodny z takim zapisanym w jakiejś innej tablicy i jeśli tak podbijasz jakis licznik

W efekcie wiesz w ilu z M zestawów danych było tak, że indeks "stałych" dla których wartość była największa zgodził się z indeksem zapisanym gdzieśtam.

  • mam 4 zestawy zmiennych(SumaM, SumaD, CiagM, CiagD, Max - przy czym zmienna[1] nie musi się równać zmienna[2]) dla każdego z M zestawów danych
  • dla każdego zestawu stałych liczysz cztery wartości swojego wyrażenia
  • wybierasz maksimum z tych wartości
  • następnie dla każdego z M zestawów porównuje indeks największej wartości z liczbą podana w innej tablicy Wyniki i jeśli jest taki sam podbijam jakis licznik

a więc tych liczników jest tyle ile kombinacji parametrów A-F, a więc 200^6. mnie interesuję to, aby licznik był jak największy. A-F maja być takie, aby właśnie licznik był najwyższy.

Shalom napisał(a):

Tylko że z tego wynika że wcale nie interesują cie parametry A-F dające maksymalną wartość wyrażenia! Ciebie interesuje dla jakich parametrów połączenych ze stałymi z i-tej tablicy uzyskamy największą z 4 możliwych wartości kiedy tablica wyniki wskazuje na indeks i. Czy tak?

chodzi o to, że tablica Wyniki wskazuje właśnie na indeks w którym rzeczywiście ta najwyższa wartość się pojawia. kwestia w tym, czy ten wzór przy paramtrach A-F najwyższą wartość ma właśnie przy indeksie który wskazuje Wyniki. a nie jest to idealne i niemożliwe jest aby policzyć to w 100%. ja muszę policzyć jak największy %. a to oznacza, że jeśli Wyniki wskazuje na 1 to wcale niekoniecznie dla M = 1 najwyższa wartość musi mieć indeks 1. jeśli ma inny indeks to po prostu ten licznik nie jest zwiększany. co ważne Wyniki dla każdego M jest w przedziale <1; 4>, a więc nie można tego też policzyć, jak często najwyższa jest np. wartość dla indeksu 1.

0

W takim razie nie ma na to szybkiego sposobu, bo zwyczajnie musisz sprawdzić te wszystkie mozliwości, innej rady nie ma.
Można to niby trochę przyspieszyć biorąc pod uwagę nasze obserwacje ->

Należy zaobserwować że w takim razie ilosć potencjalnych wyników twojego wyrażenia jest MOCNO ograniczona. Dzieje sie tak dlatego że ilość potencjalnych wyników dla każdej z funkcji f(A), g(B) itd jest ograniczona do co najwyżej M4200 różnych wartości. No bo mamy M*4 stałych w tablicach i 200 wartości dla parametru. To jest raptem 53600 wartości dla każdej z funkcji. Nawet jeśli parametrów masz 8 to nadal daje nam niecałe 0,5 mln wartości.
Więc teoretycznie mógłbyś sobie stablicować wszystkie wartości pośrednie funkcji bo to raptem 2MB ramu.

Niemniej to niewiele zmienia bo później i taj musisz wyliczać sobie wszystkie wariacje i innej rady nie ma. Więc nawet to tablicowanie guzik da.

0

No to wracamy do punktu wyjścia. OpenCL albo rozbicie tego na kilka wątków. Ja proponuje by rozbić na 4 wątki i niech jeden liczy od 1 do 50 drugi od 51 do 100 trzeci od 101 do 150 i czwarty od 151 do 200. Bo najprostsze w implementacji będzie

0

Ale to chyba i tak by nie zadziałało taki podział. Bo nie można podzielić, że będzie sprawdzane od 51 do 100, dlatego że trzeba sprawdzać wszystkie możliwości, a więc 5 parametrów może być z zakresu <51; 100> ale 6 musi być zawsze od 1 do 200. A tak na prawdę z każdym parametrem tak będzie.

0

dobra. nie załapałeś :P to może inaczej. Z tego co widziałem to wynik jest to suma różnych funkcji. Zrób liczenie każdej funkcji w oddzielnym wątku.

0

Czy dobrze rozumiem?
Masz policzyć liczbę miejsc zerowych funkcji liniowej 6-ciu zmiennych, które muszą być całkowite i z zadanego zakresu!

0
babubabu napisał(a):

dobra. nie załapałeś :P to może inaczej. Z tego co widziałem to wynik jest to suma różnych funkcji. Zrób liczenie każdej funkcji w oddzielnym wątku.

A więc nie do końca. Wynik nie jest sumą funkcji. Dla każdej kombinacji są liczone cztery wartości. A spośród nich wybierana największa. A więc, jeżeli każdą wartość bym liczył oddzielnie to później i tak musiałbym je porównywać.

MarekR22 napisał(a):

Czy dobrze rozumiem?
Masz policzyć liczbę miejsc zerowych funkcji liniowej 6-ciu zmiennych, które muszą być całkowite i z zadanego zakresu!

I tu też nie do końca. Bo tak na prawdę nie liczę miejsc zerowych. Wydaje mi się, że najlepiej będzie jak wstawię tutaj pliki programu. Wtedy będzie łatwiej wam zrozumieć. Bo słownie na prawdę jest to trudne.

0
dani17 napisał(a):
babubabu napisał(a):

dobra. nie załapałeś :P to może inaczej. Z tego co widziałem to wynik jest to suma różnych funkcji. Zrób liczenie każdej funkcji w oddzielnym wątku.

A więc nie do końca. Wynik nie jest sumą funkcji. Dla każdej kombinacji są liczone cztery wartości. A spośród nich wybierana największa. A więc, jeżeli każdą wartość bym liczył oddzielnie to później i tak musiałbym je porównywać.

Tak do końca.
Dokładnie chodzi Ci o przyspieszenie działania tego kodu

TabliceWartosci[M].Wartosc[N] := ((A / 100) * (TabliceZmiennych[M].SumaD[N] - TabliceZmiennych[M].SumaM[N])) + ((B / 100) / TabliceZmiennych[M].CiagD[N] * TabliceZmiennych[M].CiagM[N]) + ((C / 100) * TabliceZmiennych[M].SumaM[N]) + ((D / 100) * TabliceZmiennych[M].SumaD[N]) + ((E / 100) / TabliceZmiennych[M].Max[N] * TabliceZmiennych[M].CiagM[N]) + ((F / 100) * (0.25 - TabliceZmiennych[M].SumaM[N]));

A tu dokładnie widać, że można to zapisać tak:

TabliceWartosci[M].Wartosc[N] = f(a) + f(b) + f(c) + f(d) + f(e) + f(f)

gdzie

f(a) = ((A / 100) * (TabliceZmiennych[M].SumaD[N] - TabliceZmiennych[M].SumaM[N]))
f(b) = ((B / 100) / TabliceZmiennych[M].CiagD[N] * TabliceZmiennych[M].CiagM[N])
f(c) = ((C / 100) * TabliceZmiennych[M].SumaM[N])
f(d) = ((D / 100) * TabliceZmiennych[M].SumaD[N])
f(e) = ((E / 100) / TabliceZmiennych[M].Max[N] * TabliceZmiennych[M].CiagM[N])
f(f) = ((F / 100) * (0.25 - TabliceZmiennych[M].SumaM[N]));

i A,B,C,D,E,F ma być z przedziału <1..200>

Więc piszesz sobie 6 klas wątków które wyliczają poszczególne składowe f(a), f(b), f(c), f(d), f(e), f(f) w zadanym przedziale. a potem sumujesz.

A przy okazji można te funkcje zoptymalizować by działania były szybsze. Na przykład na wejściu nie dzielić przez 100.


A najlepiej pokaż kod.

`dodanie znaczników i ``` - @furious programming

0

Cały kod wygląda prawie tak jak przedstawiłem wcześniej.

WczytajTabliceZmiennych;
SumaMax := 0;
for A := 1 to 200 do
  for B := 1 to 200 do
    for C:= 1 to 200 do
      for D := 1 to 200 do
        for E := 1 to 200 do
          for F := 1 to 200 do
            begin
              Suma := 0; 
              for M := 1 to IloscWynikow do
                begin
                  NajwiekszaWartosc := 0;
                  for N := 1 to 4 do
                    TabliceWartosci[M].Wartosc[N] := ((A / 100) * (TabliceZmiennych[M].SumaD[N] - TabliceZmiennych[M].SumaM[N])) + ((B / 100) / TabliceZmiennych[M].CiagD[N] * TabliceZmiennych[M].CiagM[N]) + ((C / 100) * TabliceZmiennych[M].SumaM[N]) + ((D / 100) * TabliceZmiennych[M].SumaD[N]) + ((E / 100) / TabliceZmiennych[M].Max[N] * TabliceZmiennych[M].CiagM[N]) + ((F / 100) * (0.25 - TabliceZmiennych[M].SumaM[N]));
                  for N := 1 to 4 do
                    if TabliceWartosci[M].Wartosc[N] > NajwiekszaWartosc then
                      NajwiekszaWartosc := TabliceWartosci[M].Wartosc[N];
                  for N := 1 to 4 do
                    if TabliceWartosci[M].Wartosc[N] = NajwiekszaWartosc then
                      if N = Wyniki[M] then
                        Inc(Suma);
                end;
              if Suma > SumaMax then
                begin
                  SumaMax := Suma;
                  ZapiszParametry;
                end;
          end;
WypiszParametry;
1

@babubabu to jest to o czym pisałem. Można sobie spokojnie stablicować wyniki funkcji f(A), g(B) itd. bo ich będzie raptem 0,5 mln. Problem w tym że potem potrzebne nam są WSZYTKIE możliwe kombinacje tych wartości! Bo autor źle to na początku opisał. Jego nie interesuje wartość maksymalna tej funkcji po wszystkich parametrach (tą można policzyć na kartce nawet :P).
On ma tablicę stałych dla funkcji. Każdy zestaw danych ma 4 zestawy stałych i informacje który zestaw powinien dać największą wartość funkcji. I on teraz chciałby znać wszystkie kombinacje parametrów dla których funkcja z i-tymi stałymi faktycznie daje wartość większą od funkcji z pozostałymi 3 zestawami parametrów. Siłą rzeczy konieczne jest przetestowanie wszystkich kombinacji parametrów ;]

0

@Shalom No i dla każdego for A,b,c,d,e,f := 1 to 200 napisać oddzielny wątek. To już mamy (wzglednie) szybkie wyliczenie. A potem do kolejnej (64 biliony pozycji) tablicy zsumować wszystko, co też można zrobić w wątkach, samo sumowanie jest w miarę szybkie.

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