[C++] Modana (dominanta) jak?

0

Witam.
Mam na statystyke do napisania program który wylicza modanę(dominantę)
Dokładnie program ma czytać dane z pliku tektowego i z nich wyliczyć ową dominantę.
I borykam się z obliczeniem dominanty całą reszte zrobiłem.
Problem polega na wyliczeniu dominanty z dużego zbioru liczb zmiennoprzecinkowych np.
0.0456 , 1.342 , -0.321 .... i tak naprzykład ze 100;
Mój kod wyliczający dominante:

double maks = 0.;
double licz ;
double liczba;
for ( int i2 = 0 ; i2 < licznik ; i2++)
{
licz = 0;
for ( int i3 = 0 ; i3 < licznik; i3++)
{
  if (tablica[i2] == tablica[i3])
  licz++;
}
if (licz > maks)
{
maks = licz;
liczba = tablica[i2];
}
}

cout << "Dominanta wynosi : " << liczba << endl;

Proszę napiszcie jakbyście to rozwiązali lub chociaż jakiąś podpowiedz

POZDRAWIAM

0

Ale ty chcesz rozwiązanie optymalne? Bo można to zrobić tak jak tu napisałeś w czasie O(n^2). Ale można też zrobić w O(nlogn)+O(n)=O(nlogn). Jak? Sortujac dane wejściowe a następnie zliczając jednym, liniowym przejściem ilosć wystąpień danych liczb :)
Twoje rozwiazanie (troche ulepszone ;) ):

#include <iostream>
using namespace std;

int main()
{
  const int licznik =10;
  double tablica[licznik];
  for(int i=0;i<licznik;i++)
    cin>>tablica[i];
  int maks = 0; //licznik jest całkowity...
  int licz = 0; //jw.
  int indeks = 0; //ty na prawdę lubisz marnowac pamięć i utrudniac sobie pracę...
  for ( int i = 0 ; i < licznik ; i++)
    {
      licz = 0;
      for ( int j = i+1 ; j < licznik; j++) //wcześniejsze i tak już są zliczone, więc utniemy troche porównań
        {
          if (tablica[i] == tablica[j])
            licz++;
        }
      if (licz > maks)
        {
          maks = licz;
          indeks = i;
        }
    }
  cout << "Dominanta wynosi : " << tablica[indeks] << endl;
  return 0;
}

Rozwiązanie optymalniejsze (asymptotycznie przynajmniej):

#include <iostream>
#include <algorithm>
using namespace std;

int main()
{
  const int licznik =10;
  int licz=0;
  int max=0;
  int indeks;
  double tablica[licznik];
  for(int i=0;i<licznik;i++)
    cin>>tablica[i];

  sort(tablica,tablica+licznik);
  for(int i=0;i<licznik-1;i++)
  {
    if(tablica[i]==tablica[i+1])
      licz++;
    if(licz>max)
    {
      max=licz;
      indeks=i;
    }
  }

  cout << "Dominanta wynosi : " << tablica[indeks] << endl;
  return 0;
}

0

Dzięki za pomoc ale właściwie program działa tak samo jeśli chodzi o wynik.
Moje dane:

0.9871
0.7121
0.181
0.9502
0.5506
-0.1618
-0.0848
0.8731
0.4549
0.1833
0.7623
0.611
0.1909
0.5604
0.6663
0.1698
-0.0611
0.4848
-0.0101
1.0205
0.5721
0.3385
0.0893
-0.3983
0.8604
0.6759
0.2137
1.0122
0.1262
0.0553
0.0104
0.3509
0.0807
0.1614
0.1415
1.0528
-0.0208
0.9294
0.1734
0.9526
1.0373
0.6364
0.3083
0.8431
0.6211
0.9209
0.3837
0.9944
0.3226
0.6901
0.05
0.1905
0.8027
0.2975
1.1537
0.3256
0.2207
0.3802
0.0216
0.4433
1.1421
0.4062
0.7606
0.8059
-0.0343
0.5875
1.0202
0.42
0.3202
0.1348
0.0736
1.0917
1.1305
0.4175
-0.0703
0.413
0.6381
0.4437
0.6463
0.5905
0.2174
0.693
0.5407
0.1805
0.84
0.453
-0.092
1.1007
0.003

... sorki za zawalenie ekranu.

Właściwie to są wskaźniki rentowności .. ale to nie ma znaczenia.

Według wzoru (nie bede go pisał bo jest strasznie pokręcony) wychodzi: 0,4848 ! na pewno!

I to jest właśnie ból bo zarówno twoja wersja jak i moja daje wynik 1!

POZDRAWIAM

0

Mam wrażenie, że coś ci umknęło. Dominanta to wartość która jest najbardziej prawdopodobna w wylosowaniu.
Czyli jeśli zmienna losowa jest dyskretna, to jest to wartość, która ma największe prawdopodobieństwo wystąpienia.
W takim wypadku liczyłbyś ile razy wystąpienia dana wartość i odnalazł tą z największą liczbą zliczeń.
Ty w danych wejściowych masz najwyraźniej ciągła zmienną losową.
Czyli szukasz wartości dla której gęstość prawdopodobieństwa jest największa!
A co to oznacza? Dla takiej małej liczby próbek musisz znać typ tego rozkładu!
Przykładowo dominanta dla rozkładu normalnego jest równa średniej.
Przy braku wiedzy na temat typu rozkładu zmiennej losowej, dla większej liczby próbek należy wykonać histogram i w ten sposób sprowadzić problem do sytuacji jak z dyskretną zmienną losową.

Jaki masz rozkład zmiennych losowych?

edit:
Moim zdaniem należy to zrobić tak.

  1. policzyć min i max
  2. na tej podstawie estymować epsilon (równe powiedzmy 1/10 (max-min))
  3. szukamy takiego x dla którego liczb próbek w przedziale (x-epsilon, x+epsilon) jest największa
  4. wartość wyznaczoną w punkcie 3 policzyłbym dla kilku epsilonów, by upewnić się, że dominanta policzona w ten sposób jest prawidłowa (za małe epsilon może być niebezpieczne), kryterium może być np. że w punkcie 3 w optymalnym przypadku w przedziale było minimum 15 próbek.

Z tego opisu wyraźnie widać, że powyższe kody są coś za krótkawe.

edit2:
Cha kolejny pomysł, jeszcze lepszy (a nawet the best, bo dokładniejszy i łatwiejszy w kodowaniu).

  1. posortować próbki a[0], ..., a[n]
  2. odszukać najmniejszą wartość a[i+10]-a[i] (10 bo to jest =sqrt(n=100))
  3. policzyć średnia dla próbek a[i], a[i+1], ... ,a[i+10]
0

Dane są wskaźniki procentowej rentowności netto 89 przedsiębiorstw: 54,23%; 18,33%; 73,45%; 98,71%; 71,21%; 18,1%; 95,02%; 55,06%; -16,18%; -8,48%; 87,31%; 45,49%; 18,33%; 76,23%; 61,1%; 19,09%; 56,04%; 66,63%; 16,98%; -6,11%; 48,48%; -1,01%; 102,05%; 57,21%; 33,85%; 8,93%; -39,83%; 86,04%; 67,59%; 21,37%; 101,22%; 12,62%; 5,53%; 1,04%; 35,09%; 8,07%; 16,14%; 14,15%; 105,28%; -2,08%; 92,94%; 17,34%; 95,26%; 103,73%; 63,64%; 30,83%; 84,31%; 62,11%; 92,09%; 38,37%; 99,44%; 32,26%; 69,01%; 5,00%; 19,05%; 80,27%; 29,75%; 115,37%; 32,56%; 22,07%; 38,02%; 2,16%; 44,33%; 114,21%; 40,62%; 76,06%; 80,59%; -3,43%; 58,75%; 102,02%; 42,00%; 32,02%; 13,48%; 7,36%; 109,17%; 113,05%; 41,75%; -7,03%; 41,30%; 63,81%; 44,37%; 64,63%; 59,05%; 21,74%; 69,30%; 54,07%; 18,05%; 84,00%; 45,30%; -9,20%; 110,07%; 0,3%. (Stan na grudzień 2007)

Tak wyglądają dane wejściowe w procentach.

a program ma wyliczać: Jaka jest typowa rentowność przedsiębiorstw czyli dominante(modę)

Niestety nie wiem jaka jest rozpiętość.... to moje początki ze statystyką opisowąa dokładnie z analizą danych opisowych.... znam tylko dopowiedz wyliczona ze wzoru i wynosi: 48,48%

Do innych obliczeń używam gretl-a ale on nie liczy dominanty... więc dostałem zadanie aby taki program napisać....

POZDRAWIAM

0

loooknij up druga moja propozycja jest tym czego ci trzeba.

0

Skoro gretl nie ma (w co wątpię) to może Weka ma: http://www.cs.waikato.ac.nz/ml/weka/ .

0

Mam dobry humor, więc tu jest kod zgodnie z moim pomysłem nr 2. Dobrze by było poeksperymentować z wartością d.

#include <algoritm>
#include <math>

double dominanta(double *a, int n, double d=1.0)
{
     std::sort(a,a+n);

     int dominantaCount = d * std::sqrt(n); // można to uzasadnić na podstawie statystyki

     assert(dominantaCount<n);
     assert(dominantaCount>0);

     int maxI=0;
     double maxDiff = a[dominantaCount]-a[0];

     for(int i = 1; i+dominantaCount<n; ++i) {
          double diff = a[dominantaCount+i]-a[i];
          if(diff>maxDiff) {
               maxDiff = diff;
               maxI = i;
          }
    }

    double sum=(a[dominantaCount+maxI]+a[maxI])*0.5; // skrajne próbki z do średniej z wagą 0.5

    for(int i = 1 ; i<dominantaCount; ++i) {
          sum += a[maxI + i]; // pozostałe próbki z do średniej z wagą 1
    }
    return sum / dominantaCount; // średnia
}
0

Dziekuje Ci bardzo bo przyznam że męczyłem się z tym... skoro jak już masz dobry humor :) i nie sprawiło by Ci kłopotu dopisz mi jak przekazać jakąś tablice tych danych wejściowych bo do tablicy czytam dane z pliku.

POZDRAWIAM

0
  1. łatwe (szczególnie w porównaniu z liczeniem dominanty)
  2. Shalom pokazał jak to można zrobić
  3. a czy próbowałeś w ogóle zrobić to sam (szczególnie, że pnkt 1)

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