Liczba pi (Metoda Monte Carlo)

Odpowiedz Nowy wątek
2010-05-26 20:43
0

Witam , nie jestem fachowcem w C# dlatego prosilbym was o pomoc w napisaniu nastepujacego programu w tym jezyku.

Kod w javie:

import java.util.Scanner;
public class ZahlPI {
public static void main(String [] args){

            Scanner s = new Scanner(System.in);
            System.out.println("Ile liczb losowych wygenerowac");
            int g = s.nextInt();

            int v = 0;

            double x,y;
            for (int i = 1; i <= g; i++)   {        
                x = Math.random();
                y = Math.random();
                if (Math.hypot(x,y) <= 1)        
                  v++;
                double pi = 4*(float)v / i;
                if (i%100 == 0)  
                  System.out.printf(" Po%6d  liczbach losowych  Pi wynosi %g%n",i,pi);         
            }  
          }

}

Czy moglby mi ktos napisac ten sam program(badz podobny do obliczenia liczby pi za pomoca metody monte carlo) w c#?
Z gory wielkie dzieki!!!

Pozostało 580 znaków

2010-05-26 20:55
msm
0

Nie chce mi się sprawdzać ani kompilować, ale to będzie coś mniej więcej tak:

using System;
 
public class ZahlPI
{
public static void main(string[] args)
{
            int g = Int.Parse(Console.Readline());
 
            int v = 0;
 
            double x,y;
            Random r = new Random();
            for (int i = 1; i <= g; i++)   {       
                x = r.Next()
                y = r.Next()
                if (Math.hypot(x,y) <= 1) // nie tłumaczyłem. Chodzi tu o x*x + y*y?
                  v++;
                double pi = 4*(float)v / i;
                if (i%100 == 0) 
                  Console.Readlinef(" Po " + i.ToString() + " liczbach losowych  Pi wynosi " + pi.ToString());         
            } 
          }
}

Pozostało 580 znaków

2010-05-26 21:00
0

ok , dzeki wielkie. Mialbym jednak jescze prozbe , jakby ktos mial 30s wolnego czasu , aby sprawdzic
czy metoda dziala w 100% :-)

Pozostało 580 znaków

2010-05-26 21:10
msm
0

Ja :]

Heh, narobiłem trochę błędów i jeden całkiem poważny - nie wiedziałem że random() w javie to co innego niż w C# (w C# zwraca liczbę całkowitą z całego zakresu, w javoe najwyraźniej nie).

Sprawdzone rozwiązanie (VS specjalnie dla ciebie samodzielnie poprawiło formatowanie)

using System;
 
public class ZahlPI
{
    public static void Main(string[] args)
    {
        int g = int.Parse(Console.ReadLine());
 
        int v = 0;
 
        double x, y;
        Random r = new Random();
        for (int i = 1; i <= g; i++)
        {
            x = r.NextDouble();
            y = r.NextDouble();
            if ((x*x + y*y) <= 1)
                v++;
            double pi = 4 * (float)v / (float)i;
            if (i % 100 == 0)
                Console.WriteLine(" Po " + i.ToString() + " liczbach losowych  Pi wynosi " + pi.ToString());
        }
 
        Console.ReadLine();
    }
}

edit: albo ja coś źle przepisałem albo niedokładny ten algorytm :/ po 100 000 przebiegów wyszło że pi = 3.1400017(...) . A przy mniejszych zakresach potrafi się mylić o 2-3 części dziesiętne.

Pozostało 580 znaków

2010-05-26 23:32
0

Moje niezależne tłumaczenie (funkcja hypot wzięta z przykładu na msdn.microsoft.com):

using System;
 
public class ZahlPI {
 
    public static double hypot(double a, double b)
    {
        a = Math.Abs(a);
        b = Math.Abs(b);
        if (a < b)
        {
            double temp = a;
            a = b;
            b = temp;
        }
        if (a == 0.0)
            return 0.0;
        else
        {
            double ba = b / a;
            return a * Math.Sqrt(1.0 + ba * ba);
        }
    }
 
    public static void Main(string[] args) {               
 
        Random random=new Random();
        Console.WriteLine("Ile liczb losowych wygenerowac");
        int g = int.Parse(Console.ReadLine());
 
        int v = 0;
 
        double x,y;
        for (int i = 1; i <= g; i++)   {        
            x = random.NextDouble();
            y = random.NextDouble();
            if (hypot(x,y) <= 1)        
              v++;
            double pi = 4*(float)v / i;
            if (i%1000000 == 0)  
              Console.WriteLine(" Po {0} liczbach losowych Pi wynosi {1}",i,pi); 
        }  
      }
}

i wynik:

Po 1000000000 liczbach losowych Pi wynosi 3,141591552

Czyli metoda, ogólnie, do d__y.
Ale coś liczy.

Pozostało 580 znaków

2010-05-27 12:10
bo
0

@MSM, gdybyś jeszcze kiedyś tłumaczył kod losujący z Javy na C#:
W klasie Math jest metoda static random(), która zwraca liczbę typu double z przedziału [0,1).
W klasie Random są metody (niestatyczne!): nextDouble(), nextFloat(), nextLong(), nextInt() i nextInt(int zakres). Pierwsze dwie zwracają liczbę z [0,1), co do następnych to łatwo zgadnąć.

Pozostało 580 znaków

2010-05-27 20:01
bo
0

Że ta metoda liczenia liczby \pi jest do d..y wiedziałem od razu. Postanowiłem sprawdzić jak bardzo jest do d..y.
ilość losowań stosunek przybliżonego \pi do dokładnego
10 0,763943726841
100 0,980394449446
1000 0,993126844893
10000 1,008278395476
100000 0,998996479195
1000000 0,998544479156
10000000 0,999935748007
100000000 0,999985506208
1000000000 0,999989401048
10000000000 0,999999066973
100000000000 0,999998778343
BTW. Funkcja hypot(x,y)=\sqrt{x<sup>2+y</sup>2} bez przepełnienia, które grozi jeśli x,y są bardzo duże. W tym zadaniu jej użycie jest zbędne (i chyba szkodliwe) \sqrt{x<sup>2+y</sup>2}<=1 <==> x<sup>2+y</sup>2<=1.

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

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