Losowanie Z Zbioru ?

0

Szukalem na forum, ale nie znalazlem... w jaki sposob mozna wylosowac cos z zbioru ? zbior: sef of byte

zbior:=[23,43,12,45,65,23,123,53,123,456]

Jak ?? :)

Zwykle

a:=random(zbior);

nie dziala...

0

Ze zbioru się nie losuje!!! Jedyne co można to sprawdzić przynależność do zbioru. Zbiór nie ma kolejności, nie mozna go sortować. Nic.

Kuba, proponuję jezcze ze 3 razy napisać ten sam temat w różnych wersjach. Odpuść sobie zbiory. Od tego są tablice. Poczytaj najpierw jakieś kursy, kompendium Adama Boducha, które jesy na forum.

// @Dopisane do postu niżej: g... szukasz. Piszesz ciągle te same bzdury i jesteś głuchy na nasze rady. Wiem dobra metoda. Tak długo będę trzaskać głupoty aż ktoś nie wytrzyma. Metoda skuteczna.

0

po prostu szukam rozwiazania na wiele sposobow jezeli inne zawodza i nie daje za wygrana, poniewaz potrzebuje napisac ten program...

0

Dobra, przepisałem program na Pascala przy użyciu TP, ale źródło w C++ (a raczej w "C ze strumieniami" :]) też zachowam, tak na wszelki wypadek, może jutro jakiś geniusz będzie o to samo pytał w C/C++...

#include <iostream>
#include <cmath>

using namespace std;

const int RangeMax = 50;
const int Numbers = 10;
const int Tests = 10000;

int counts[RangeMax];
int positions[RangeMax];
int range[RangeMax];
int rangeSize = RangeMax;

int get() {
    int pos = rand()%rangeSize--;
    int temp = range[rangeSize];
    range[rangeSize] = range[pos];
    range[pos] = temp;
    return range[rangeSize];
    }
    
void fill(bool order=false) {
    rangeSize  = RangeMax;
    if(order) for(int i=0; i<RangeMax; i++) range[i]=i;
    }


int main() {
    fill(true);
    for(int test = 0; test<Tests; test++) {
        for(int i=0; i<Numbers; i++) {
            int n = get();
            counts[n]++;
            positions[n]+=(i+1);
            }
        fill(false);
        }
       
    cout << "Czestosc losowania (%):" << endl;
    for(int i=0; i<RangeMax; i++)
        cout << round(100.0*counts[i]/Tests) << "\t";

    cout << endl << "Srednio na pozycji:" << endl;
    for(int i=0; i<RangeMax; i++)
        cout << positions[i]/counts[i] << "\t";

    system("pause>nul");
    return 0;
    }

Samo losowanie zawiera się 10 linijkach, pozostałe 40 służy temu, żebyś w końcu uwierzył, że masz dobry rozkład, czyli żadne liczby nie są preferowane, nie są też losowane rzadziej. Żadna liczba nie pojawia się w preferowanej kolejności. Losuję 10 liczb z 50. Po 100 000 losowań okazuje się, że prawdopodobieństwo wylosowania każdej liczby wynosi 20%, a średnia pozycja to 5, czyli żadna liczba nigdy nie wbija się na początek ani na koniec serii. Sorry, ambitniejszych testów statystycznych nie chciało mi się robić, lol. Tej samej metody używam pisząc symulacje Monte Carlo (tylko wtedy nie używam wbudowanego rand), więc chyba działa....

// Już drugi raz to piszę na tym forum... ja przy was się Pascala nauczę - a raczej przypomnę po 8 latach nieużywania, lol

uses crt;

const RangeMax = 50;
const Numbers = 10;
const Tests = 100000;

var counts, positions, range : array[0..RangeMax-1] of longint;
    rangeSize : integer;


function get:longint;
   var pos, temp: longint;
begin
   pos := random(rangeSize);
   rangeSize := rangeSize-1;
   temp := range[rangeSize];
   range[rangeSize] := range[pos];
   range[pos] := temp;
   get := range[rangeSize];
end;

procedure fill(order : boolean);
   var i : longint;
begin
   rangeSize := RangeMax;
   if order = true then for i:=0 to RangeMax-1 do range[i] := i;
end;

var i, n, test : longint;

begin
   fill(true);
   for test:=0 to Tests-1 do begin
       for i:=0 to Numbers-1 do begin
          n := get;
          counts[n] := counts[n]+1;
          positions[n] := positions[n] + i + 1;
       end;
       fill(false);
   end;

   writeln('Czestosc losowanie (%):');
   for i:=0 to RangeMax-1 do
      write( (100*counts[i]) div Tests : 8);

   writeln;
   writeln('Srednio na pozycji:');
   for i:=0 to RangeMax-1 do
      write(positions[i] div counts[i] : 8);

   readkey;
end.

btw: to, że funkcja fill wypełnia tablicę liczbami od 0 do RangeMax nie ma nic do rzeczy. Tablica Range może zawierać dowolne wartości. Wartości mogą się również powtarzać. Jeśli element powtarza się n razy, to szansa jego wylosowania rośnie n razy oczywiście.

0

@Ranides: Ja również nie wytrzymałem, ale rozwiązanie wkleiłem do drugiego wątku. Jak teraz nie zatrybi to normalnie kupię flaszkę i się nap... bo. Mimo iz moja cierpliwość jest duża to jednak ma ona swoje granice.
Tasowanie tablicy

0

Jak mieszkasz w promieniu 80 km od Krakowa, to się nawalimy razem, lol

0

Adam: ze zbioru da się wyciągnąć dane. Wystarczy użyć rzutowania.

0

Formalnie rzecz biorąc, to po rzutowaniu wyciągasz dane z tego czegoś, na co rzutowałeś, a nie ze zbioru ;P Za pomocą kilkakrotnych rzutowań to ja sobie exponentę dla zbioru policzyć mogę, lol

0

mylisz się, zbiór to po prostu ciąg bitów z którego jak najbardziej można wyciągnąć informacje.
popatrz na to:

type
   TSet = set of (a,b,c);

var
  s : TSet;
  i : byte;

begin
  i := 1;
  s := TSet(i);
end.

i zobacz w debugerze co zawiera s gdy i = 1, 2, 3. Możesz też rzutować w drugą stronę, czyli wyciągnąć że a = 1, b = 2, c = 4 itp.

0

Wiem, wiem, że to jest tak zrealizowane. W zasadzie to ględzę bez potrzeby, ale postaram się przedstawić, o co mi chodziło, gdy napisałem formalnie :)

Rzutowanie typu A na typ B, to operacja mówiąca: mam gdzieś, jakiego typu jest zmienna; kompilatorze masz tę zmienną traktować, jakby była typu B. Kompilator więc traktuje zmienną jak B i zachowuje się, jakby pracował z B. W ten sposób robisz z A coś, czego interfejs A nie udostępnia. Robisz to, dzięki interfejsowi B. Gdyby nie B, nigdy byś takiego czegoś nie zrobił. Wszystko: kontrola zakresów, typów itd myśli, że pracujesz z B. Nikogo nie obchodzi, na co de facto wskazuje obszar w pamięci. Kompilator myśli: pracuję z B, wyciągam dane z B, zapisuję do B. Tylko ty jeden wiesz, że to ściema :P

Poględziłbym jeszcze ale to nudzenie akademickie, a mi nie zależy na uwypuklaniu jakichś nieuchwytnych niuansów mojego myślenia ;P Więc EOT raczej.

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