Farklı olasılıklara göre random seçme

Merhaba, yazdığım kodda belli miktarda (10 ila 20 tane olacak şekilde, ve hepsinin toplamı %100 olacak şekilde, örneğin %0.024 , %1.876, %24,122…vb gibi) olasılık çıktısı alıyorum. Bu olasılıklar kesirli olarak da mevcut. Bu olasılıklar arasında random choice gibi bir komut kullanabilir miyim? random seçtiğinde yukarda örnek verdiğim olasılıklara göre seçtirebilir miyim?

Olasiliklari belirli bir siraya koyup, kismi toplamlarini alip (%0.024, %0.024 + %1.876, %0.024 + %1.876 + %24,122, …, 1), 0 ila 1 arasindaki rastgele sayinin ilk hangisinden kucuk oldugunu bulup secerseniz, o sirayi o olasilikla secmis olursunuz.

Off-by-1 hatasi yapmis olabilirim (liste 0 ile mi baslayacak? en son hangisinden buyuk oldugunu mu bulacagiz?) ama algoritma bu.

hayır, liste 0 la başlamıyor demek istediğim birbiriyle orantılı olasılıklar var. (plinko kodluyorum)

mesela %0.025, 0.128, 1.276, 7.56, 20.1, 26.3, 20.1 ,7.56… diye devam ediyor ve bunların toplamı %100 yani paydaları aynı olacak şekilde yüzde hesaplamaları yapılıyor.

benim demek istediğim şu. her olasılığa bir harf atayalım mesela
%0.025 = a durumu
%0.128 = b durumu
%1.276 = c durumu gibi
ve random bir şekilde bu olasılıklara göre seçsin yani çıktıyı belirttiğim olasılığa göre alayım.

ilk başta pay/payda şeklinde olduğundan her olasılığın pay değeri kadar harfi (ya da karakteri, örneğin aaaaaa,bbb,c gibi) .txt dosyasına yazdırmak ve oradan seçtirmek gibi bir fikrim vardı ama daha basit bir yolu var mı diye size sormak istedim.

Anladığım kadarıyla bu rakamlar rasgele oluşturulmuyor. hali hazırda elinde var.
0.025, 0.128, 1.276, 7.56, 20.1, 26.3, 20.1 ,7.56

0 - 100 000 arasında random bir sayı alıp. 1000 e bölüp küsuratlı bir sayı elde ediyoruz. (bunu doğrudan yapma yolu da vardır bakmadım)

if ile kırılım yaparak
eğer sayı 0 - 0,025 arasında ise sonuç a
eğer sayı 0,025 - 1,153 arasında ise sonuç b
eğer sayı 1,153 - 2,429 arasında ise sonuç c gibi çıkarım yapabiliriz.

pay payda olayını hiç anlamadım. tabi konuyu çok yanlış anlamış da olabilirim.

hocam verdiğim yüzdeler örnek olaraktı plinko kodluyorum ya olasılık her programı başlattığımda benim girdiğim parametreye göre değişiyor. O bahsettiğim a,b,c,d,e…vb olasılıkların sayısını ben belirliyorum. Bazen min 10, max 20 tane olacak şekilde.

ortak paydadan kastım da şuydu. Ben % olarak yazdım ama hepsini toplayınca %100 olmasının sebebi şöyle
1/3268+ 7/3268+29/3268+89/3268…= 3268/3268 (1 =%100) gibi (verilen sayıların hepsi tamamen örnek)

işte bu bahsettiğim orana göre nasıl seçtiricem hiçbir fikrim yok her olasılığı ayrı bir karakter ya da durum gibi seçtirmek istiyorum fakat bir algoritma kuramıyorum

sanırım doğru anlamışım.

import random

payda = int(input("payda ne olacak: "))
kalan_pay = payda
rasgele_sayi = random.random() * payda  # demin bakmadım demiştim şimdi baktım böyle yapmak uygun
print("rasgele_sayi", rasgele_sayi)

secenek_sayisi = int(input("kaç seçenek olacak: "))
secenekler = list()  # sözlük de kullanabilirsin


for _ in range(secenek_sayisi):
    secenek_adi = input("yeni seçenek için isim :")
    secenek_pay = int(input(f"yeni seçenek için pay (maks. {kalan_pay}) :"))
    secenekler.append((secenek_adi, secenek_pay))
    kalan_pay -= secenek_pay

pay_sinir = 0
for ad, pay in secenekler:
    pay_sinir += pay
    if rasgele_sayi <= pay_sinir:
        secim = ad
        break

print(f"Yapılan seçim {pay}")

tahminimce görsel arayüz kullanıyorsunuz. ona göre ayarlarsınız sadece secenekler listesi, pay_sinir değişkeni ve altındaki for döngüsü işinizi çözebilir diye düşünüyorum.

random.choices fonksiyonununda cum_weights parametresini kullanarak bunu ayarlayabilirsin.

import random
 
sampleList = [100, 200, 300, 400, 500]
randomList = random.choices(
  sampleList, cum_weights=(5, 15, 35, 65, 100), k=5)
 
print(randomList)

Kaynak: How to get weighted random choice in Python? - GeeksforGeeks

2 Beğeni

Tamam, dedigim sekilde yapabilirsiniz.

Parantez icindeki sorular, algoritmanin dogru veya 1 fark hatali calismasini saglayacak parametrelerdi:
Kumulatif toplamlarin yaninda, ya basta 0, ya da sonra 1 olabilir.
Rastgele sayi < veya > islemleriyle kontrol edilebilir.
Kontrolun sonucu dogru cikan ilk eleman veya son eleman, veya bunlarin sagindaki veya solundaki elemanlar alinabilir.

orn:

cs = [.1, .2, .8, 1] # %10, %10, %60, %20
r = random.random()
rastgele_index = [r <= e for e in cs].index(True)

veya

cs = [0, .1, .2, .8]
r = random.random()
rastgele_index = [r > e for e in cs].index(False)

random.choices da boyle calistigini soyluyor.
Hatta dogrudan agirliklari da alabiliyormus, muthis.

2 Beğeni

sizin çözümlerinizi de deneyeceğim ama dün akşam şöyle bir çözüm geliştirdim, hangisi hızlıysa onu kullanacağım.

bir list’e her olasılığın , her kesrin sayısı kadar bir karakter yazdırdım
mesela 1/342 -->1
8/342 --------------->22222222

şeklinde ve onların içinden rastgele seçtirdim. böylece seçtiğim sayıyla olasılık arasında bağlantı kurdum.
bahsettiğiniz random modülüne de bakacağım

konu çözülmüştür.