আমি কীভাবে নকল ছাড়াই এলোমেলো সংখ্যার একটি তালিকা তৈরি করব?


110

আমি ব্যবহার করার চেষ্টা করেছি random.randint(0, 100), তবে কিছু নম্বর একই ছিল। একটি তালিকা অনন্য এলোমেলো সংখ্যা তৈরি করার জন্য কি কোনও পদ্ধতি / মডিউল আছে?

দ্রষ্টব্য: নীচের কোডটি একটি উত্তরের ভিত্তিতে এবং উত্তর পোস্ট করার পরে যুক্ত করা হয়েছে। এটি প্রশ্নের অংশ নয়; এটি সমাধান।

def getScores():
    # open files to read and write
    f1 = open("page.txt", "r");
    p1 = open("pgRes.txt", "a");

    gScores = [];
    bScores = [];
    yScores = [];

    # run 50 tests of 40 random queries to implement "bootstrapping" method 
    for i in range(50):
        # get 40 random queries from the 50
        lines = random.sample(f1.readlines(), 40);

1
যদি তারা অনন্য হয় তবে তারা সঠিক প্রসঙ্গে সত্যই এলোমেলো হতে পারে। প্রতিস্থাপন ছাড়াই সূচিগুলির একটি এলোমেলো নমুনার মতো এখনও সম্পূর্ণ এলোমেলো হতে পারে।
gbtimmon

উত্তর:


180

এটি ডুপ্লিকেট ছাড়াই 0 থেকে 99 ব্যাপ্তি থেকে নির্বাচিত 10 সংখ্যার একটি তালিকা ফেরত দেবে।

import random
random.sample(range(100), 10)

আপনার নির্দিষ্ট কোড উদাহরণের সাথে উল্লেখ করে আপনি সম্ভবত ফাইলটি সমস্ত লাইন একবারে পড়তে চান এবং তারপরে মেমোরিতে সংরক্ষিত তালিকা থেকে এলোমেলো লাইনগুলি নির্বাচন করতে চান। উদাহরণ স্বরূপ:

all_lines = f1.readlines()
for i in range(50):
    lines = random.sample(all_lines, 40)

এইভাবে, আপনার লুপের আগে আপনাকে কেবল একবার ফাইলটি পড়তে হবে। ফাইলটির শুরুতে ফিরে যাওয়া এবং f1.readlines()প্রতিটি লুপ পুনরাবৃত্তির জন্য আবার কল করার চেয়ে এটি করা অনেক বেশি দক্ষ ।


2
এই কৌশলটি বিশেষত বড় নমুনাগুলির জন্য স্মৃতি অপচয় করে। আমি নীচে আরও অনেক মেমরি এবং গণনা দক্ষ সমাধানের জন্য কোড পোস্ট করেছি যা লিনিয়ার কগ্রুভেনিয়াল জেনারেটর ব্যবহার করে।
থমাস লাক্স

এটি আমার দিকে ইঙ্গিত করা হয়েছিল যে এলসিজি পদ্ধতিটি যদিও "র্যান্ডম" কম, সুতরাং আপনি যদি অনেকগুলি অনন্য এলোমেলো ক্রম উত্পন্ন করতে চান তবে বিভিন্নটি এই সমাধানের চেয়ে কম হবে। আপনার যদি কেবল কয়েকটি মুঠোয় এলোমেলো ক্রম দরকার হয় তবে এলসিজি হবার উপায়!
থমাস লাক্স

আপনাকে গ্রেগ ধন্যবাদ, এটি দরকারী ছিল
এন শিরাম

15

আপনি ব্যবহার করতে পারেন এলোমেলো থেকে ফাংশন র্যান্ডম ভালো মডিউল:

import random

my_list = list(xrange(1,100)) # list of integers from 1 to 99
                              # adjust this boundaries to fit your needs
random.shuffle(my_list)
print my_list # <- List of unique random numbers

এখানে নোট করুন যে বদলানো পদ্ধতিটি কোনও প্রত্যাশার মতো কোনও তালিকা ফেরত দেয় না, এটি কেবল রেফারেন্স দিয়ে পাস করা তালিকাটি বদলে দেয়।


এখানে উল্লেখ করা ভাল যে এক্সরেঞ্জ কেবল পাইথন 2 এ কাজ করে এবং পাইথন 3 এ নয়
শায়ান শফিক

10

আপনিই প্রথম থেকে সংখ্যার একটি তালিকা তৈরি করতে পারেন aথেকে b, যেখানে aএবং bযথাক্রমে আপনার তালিকায় ক্ষুদ্রতম এবং সর্বশ্রেষ্ঠ সংখ্যা, তারপর সঙ্গে এটি অদলবদল ফিশার-ইয়েটস আলগোরিদিম বা পাইথন এর ব্যবহার random.shuffleপদ্ধতি।


1
সূচকগুলির একটি সম্পূর্ণ তালিকা তৈরি করা স্মৃতিশক্তি অপচয়, বিশেষত বড় নমুনাগুলির জন্য। আমি নীচে আরও অনেক মেমরি এবং গণনা দক্ষ সমাধানের জন্য কোড পোস্ট করেছি যা লিনিয়ার কগ্রুভেনিয়াল জেনারেটর ব্যবহার করে।
থমাস লাক্স

8

এই উত্তরের উপস্থাপিত সমাধানটি কাজ করে, তবে নমুনার আকার ছোট হলে এটি মেমরির সাথে সমস্যাযুক্ত হতে পারে, তবে জনসংখ্যা বিশাল (উদাঃ random.sample(insanelyLargeNumber, 10))।

এটি ঠিক করার জন্য, আমি এটি দিয়ে যাব:

answer = set()
sampleSize = 10
answerSize = 0

while answerSize < sampleSize:
    r = random.randint(0,100)
    if r not in answer:
        answerSize += 1
        answer.add(r)

# answer now contains 10 unique, random integers from 0.. 100

এখন random.sampleএকটি বৃহত জনসংখ্যার থেকে অল্প সংখ্যক নমুনার জন্য এই পদ্ধতির ব্যবহার করে, তাই মেমরির সাথে এই সমস্যাটি আর উপস্থিত থাকে না। যদিও, এই সময়ে এই উত্তরটি লেখা হয়েছিল, এর বাস্তবায়ন random.shuffleঅন্যরকম হতে পারে।
কিরিল

5

লিনিয়ার সম্মিলিত সিউডো-এলোমেলো সংখ্যা জেনারেটর

ও (1) স্মৃতি

ও (কে) অপারেশনস

একটি সাধারণ লিনিয়ার ক্রেগ্রুভেনিয়াল জেনারেটর দিয়ে এই সমস্যাটি সমাধান করা যেতে পারে । এর জন্য ধ্রুবক মেমরি ওভারহেড (8 টি পূর্ণসংখ্যার) এবং সর্বাধিক 2 * (ক্রম দৈর্ঘ্য) গণনা প্রয়োজন।

অন্যান্য সমস্ত সমাধান আরও মেমরি এবং আরও গণনা ব্যবহার করে! আপনার যদি কেবল কয়েকটি র্যান্ডম সিকোয়েন্সগুলির প্রয়োজন হয় তবে এই পদ্ধতিটি উল্লেখযোগ্যভাবে সস্তা হবে। আকারের ব্যাপ্তির জন্য N, যদি আপনি অনুক্রম জেনারেট করতে চান Nঅনন্য kআরো -sequences বা, আমি গৃহীত সমাধান builtin পদ্ধতি ব্যবহার করে সুপারিশ random.sample(range(N),k)হিসাবে এই অপ্টিমাইজ করা হয়েছে গতির জন্য পাইথন হবে।

কোড

# Return a randomized "range" using a Linear Congruential Generator
# to produce the number sequence. Parameters are the same as for 
# python builtin "range".
#   Memory  -- storage for 8 integers, regardless of parameters.
#   Compute -- at most 2*"maximum" steps required to generate sequence.
#
def random_range(start, stop=None, step=None):
    import random, math
    # Set a default values the same way "range" does.
    if (stop == None): start, stop = 0, start
    if (step == None): step = 1
    # Use a mapping to convert a standard range into the desired range.
    mapping = lambda i: (i*step) + start
    # Compute the number of numbers in this range.
    maximum = (stop - start) // step
    # Seed range with a random integer.
    value = random.randint(0,maximum)
    # 
    # Construct an offset, multiplier, and modulus for a linear
    # congruential generator. These generators are cyclic and
    # non-repeating when they maintain the properties:
    # 
    #   1) "modulus" and "offset" are relatively prime.
    #   2) ["multiplier" - 1] is divisible by all prime factors of "modulus".
    #   3) ["multiplier" - 1] is divisible by 4 if "modulus" is divisible by 4.
    # 
    offset = random.randint(0,maximum) * 2 + 1      # Pick a random odd-valued offset.
    multiplier = 4*(maximum//4) + 1                 # Pick a multiplier 1 greater than a multiple of 4.
    modulus = int(2**math.ceil(math.log2(maximum))) # Pick a modulus just big enough to generate all numbers (power of 2).
    # Track how many random numbers have been returned.
    found = 0
    while found < maximum:
        # If this is a valid value, yield it in generator fashion.
        if value < maximum:
            found += 1
            yield mapping(value)
        # Calculate the next value in the sequence.
        value = (value*multiplier + offset) % modulus

ব্যবহার

এই ফাংশন "এলোমেলো_আরঞ্জ" এর ব্যবহার যে কোনও জেনারেটরের জন্য একই (যেমন "রেঞ্জ")। একটি উদাহরণ:

# Show off random range.
print()
for v in range(3,6):
    v = 2**v
    l = list(random_range(v))
    print("Need",v,"found",len(set(l)),"(min,max)",(min(l),max(l)))
    print("",l)
    print()

নমুনা ফলাফল

Required 8 cycles to generate a sequence of 8 values.
Need 8 found 8 (min,max) (0, 7)
 [1, 0, 7, 6, 5, 4, 3, 2]

Required 16 cycles to generate a sequence of 9 values.
Need 9 found 9 (min,max) (0, 8)
 [3, 5, 8, 7, 2, 6, 0, 1, 4]

Required 16 cycles to generate a sequence of 16 values.
Need 16 found 16 (min,max) (0, 15)
 [5, 14, 11, 8, 3, 2, 13, 1, 0, 6, 9, 4, 7, 12, 10, 15]

Required 32 cycles to generate a sequence of 17 values.
Need 17 found 17 (min,max) (0, 16)
 [12, 6, 16, 15, 10, 3, 14, 5, 11, 13, 0, 1, 4, 8, 7, 2, ...]

Required 32 cycles to generate a sequence of 32 values.
Need 32 found 32 (min,max) (0, 31)
 [19, 15, 1, 6, 10, 7, 0, 28, 23, 24, 31, 17, 22, 20, 9, ...]

Required 64 cycles to generate a sequence of 33 values.
Need 33 found 33 (min,max) (0, 32)
 [11, 13, 0, 8, 2, 9, 27, 6, 29, 16, 15, 10, 3, 14, 5, 24, ...]

1
এটা খুব সুন্দর! তবে আমি নিশ্চিত যে এটি সত্যই প্রশ্নের উত্তর দিয়েছে; বলুন যে আমি 0 থেকে 4 পর্যন্ত 2 টি মানকে নমুনা করতে চাই prime, নিজের তৈরি না করে ফাংশনটি আমাকে কেবল 4 টি সম্ভাব্য উত্তর প্রদান করবে, কারণ valueআমাদের যখন কমপক্ষে (4 চয়ন 2) = প্রয়োজন তখন 4 সম্ভাব্য মানগুলির সাথে এলোমেলোভাবে বেছে নেওয়া জিনিস = 6, (নন-এলোমেলো অর্ডার দেওয়ার জন্য অনুমতি দেওয়া)। random_range(2,4)মানগুলি 1 (1, 0), (3, 2), (2, 1), (0, 3) return প্রদান করবে, তবে কখনও এই জুটি (3,1) (বা (1,3)) আসবে না। আপনি কি প্রতিটি ফাংশন কল এলোমেলোভাবে উত্পাদিত বড় প্রাইমগুলি আশা করছেন?
wowserx

1
(এছাড়াও আমি ধরেই নিচ্ছি যে লোকেরা এলোমেলো ক্রম চাইলে আপনার ফাংশনটি ফেরত দেওয়ার পরে ক্রমটি বদলে random_range(v)vv!
ফেলবে

সম্পূর্ণ সত্য! পূর্ণসংখ্যা ওভারফ্লো এড়ানো এবং পর্যাপ্ত এলোমেলো ক্রম উত্পন্ন করার মধ্যে ভারসাম্য বজায় রাখা শক্ত। আমি আরও কিছু এলোমেলোভাবে অন্তর্ভুক্ত করার জন্য ফাংশনটি আপডেট করেছি তবে এটি এখনও ভি এর মতো এলোমেলো নয়। আপনি যদি একাধিকবার ফাংশনটি ব্যবহার করতে চান তবে এটি নির্ভর করে। এই সমাধানটি তখন ব্যবহার করা হয় যখন আপনি বড় আকারের মানগুলি তৈরি করেন (যখন অন্যের মেমরির খরচ অনেক বেশি হবে)। আমি এটি আরও চিন্তা করব, ধন্যবাদ!
থমাস লাক্স

4

যদি 1 থেকে N পর্যন্ত N সংখ্যার তালিকাটি এলোমেলোভাবে উত্পন্ন হয় তবে হ্যাঁ, কিছু সংখ্যার পুনরাবৃত্তি হওয়ার সম্ভাবনা রয়েছে।

আপনি যদি এলোমেলো ক্রমে 1 থেকে N পর্যন্ত সংখ্যার একটি তালিকা চান তবে 1 থেকে N পর্যন্ত পূর্ণসংখ্যার সাথে একটি অ্যারে পূরণ করুন এবং তারপরে ফিশার-ইয়েটস সাফল্য বা পাইথন ব্যবহার করুন random.shuffle()


3

আপনার যদি অত্যন্ত সংখ্যক নমুনার প্রয়োজন হয় তবে আপনি ব্যবহার করতে পারবেন না range

random.sample(range(10000000000000000000000000000000), 10)

কারণ এটি ছুড়ে:

OverflowError: Python int too large to convert to C ssize_t

এছাড়াও, random.sampleপরিসীমা খুব কম হওয়ার কারণে যদি আপনার পছন্দসই আইটেমগুলির সংখ্যা উত্পাদন করতে না পারে

 random.sample(range(2), 1000)

এটি ছুড়ে:

 ValueError: Sample larger than population

এই ফাংশন উভয় সমস্যার সমাধান করে:

import random

def random_sample(count, start, stop, step=1):
    def gen_random():
        while True:
            yield random.randrange(start, stop, step)

    def gen_n_unique(source, n):
        seen = set()
        seenadd = seen.add
        for i in (i for i in source() if i not in seen and not seenadd(i)):
            yield i
            if len(seen) == n:
                break

    return [i for i in gen_n_unique(gen_random,
                                    min(count, int(abs(stop - start) / abs(step))))]

অত্যন্ত সংখ্যক সংখ্যার সাথে ব্যবহার:

print('\n'.join(map(str, random_sample(10, 2, 10000000000000000000000000000000))))

নমুনা ফলাফল:

7822019936001013053229712669368
6289033704329783896566642145909
2473484300603494430244265004275
5842266362922067540967510912174
6775107889200427514968714189847
9674137095837778645652621150351
9969632214348349234653730196586
1397846105816635294077965449171
3911263633583030536971422042360
9864578596169364050929858013943

অনুরোধ করা আইটেমগুলির সংখ্যার চেয়ে পরিসর ছোট যেখানে ব্যবহার:

print(', '.join(map(str, random_sample(100000, 0, 3))))

নমুনা ফলাফল:

2, 0, 1

এটি নেতিবাচক ব্যাপ্তি এবং পদক্ষেপগুলির সাথেও কাজ করে:

print(', '.join(map(str, random_sample(10, 10, -10, -2))))
print(', '.join(map(str, random_sample(10, 5, -5, -2))))

নমুনা ফলাফল:

2, -8, 6, -2, -4, 0, 4, 10, -6, 8
-3, 1, 5, -1, 3

আপনি যদি 8 বিলিয়ন সংখ্যক জেনারেট করেন তবে তাড়াতাড়ি বা পরে দেখা খুব বড় হয়ে উঠবে
ডেভিড_অ্যাডার

এই উত্তরের বড় নমুনাগুলির জন্য মারাত্মক ত্রুটি রয়েছে। সংঘর্ষের সম্ভাবনা প্রতিটি পদক্ষেপের সাথে রৈখিকভাবে বৃদ্ধি পায়। আমি লিনিয়ার কংগ্রুভেন্সি জেনারেটর ব্যবহার করে একটি সমাধান পোস্ট করেছি যাতে ও (1) মেমরির ওভারহেড এবং কে সংখ্যা উত্পন্ন করার জন্য প্রয়োজনীয় ও (কে) পদক্ষেপ রয়েছে। এটি আরও কার্যকরভাবে সমাধান করা যেতে পারে!
থমাস লাক্স

এই উত্তরটি অবশ্যই যদি আপনি সিকোয়েন্সের দৈর্ঘ্যের ক্রম অনুসারে বেশ কয়েকটি এলোমেলো সিক্যুয়েন্স তৈরি করতে চান তবে অবশ্যই ভাল! যখন একাধিক অনন্য ক্রম উত্পন্ন করার ক্ষেত্রে এলসিজি পদ্ধতিটি কম "এলোমেলো" থাকে।
থমাস লাক্স

"এই ফাংশনটি উভয় সমস্যার সমাধান করে " এটি দ্বিতীয় সমস্যাটি কীভাবে সমাধান করবে? আপনি এখনও 2 জনসংখ্যার থেকে 1000 নমুনা নিতে পারবেন না একটি ব্যতিক্রম ছুঁড়ার পরিবর্তে আপনি একটি ভুল ফলাফল তৈরি করেন; এটি "সমস্যার" এর সমাধান খুব কমই (যা আসলেই কোনও সমস্যা নয় যেহেতু এন <কে এর জনসংখ্যার থেকে কে অনন্য নমুনার অনুরোধ করা মোটেও যুক্তিসঙ্গত নয় )।
কিরিল

1

আপনি নীচের মত দ্রুত উত্তর জন্য নম্পি গ্রন্থাগার ব্যবহার করতে পারেন -

প্রদত্ত কোড স্নিপেট 0 থেকে 5 এর মধ্যে 6 টি স্বতন্ত্র সংখ্যা নীচে তালিকাভুক্ত করে your আপনি নিজের আরামের জন্য প্যারামিটারগুলি সামঞ্জস্য করতে পারেন।

import numpy as np
import random
a = np.linspace( 0, 5, 6 )
random.shuffle(a)
print(a)

আউটপুট

[ 2.  1.  5.  3.  4.  0.]

এখানে যেমন উল্লেখ করা হয়েছে তা এলোমেলোভাবে দেখায় এটি কোনও বাধা দেয় না ।

আশা করি এটা কিছুটা সাহায্য করবে।


1

প্রদত্ত উত্তর এখানে সময় এবং সেইসাথে মেমরির কিন্তু একটি বিট আরো জটিল যেমন যেমন ফলন উন্নত পাইথন নির্মান ব্যবহার থেকে সম্মান সঙ্গে খুব ভাল কাজ করে। সহজ উত্তর অনুশীলন ভাল কাজ করে কিন্তু যে উত্তর সঙ্গে সমস্যাটি হল এই যে এটা আসলে প্রয়োজনীয় সেট নির্মাণের আগে অনেক কৃত্রিম পূর্ণসংখ্যার উৎপন্ন হতে পারে। জনসংখ্যার সাইজ = 1000, স্যাম্পল সাইজ = 999 দিয়ে চেষ্টা করে দেখুন theory

নীচের উত্তর দুটি বিষয়কেই সম্বোধন করে, কারণ এটি নির্বিচারবাদী এবং কিছুটা দক্ষ যদিও বর্তমানে অন্য দুটির মতো দক্ষ নয়।

def randomSample(populationSize, sampleSize):
  populationStr = str(populationSize)
  dTree, samples = {}, []
  for i in range(sampleSize):
    val, dTree = getElem(populationStr, dTree, '')
    samples.append(int(val))
  return samples, dTree

যেখানে ফাংশনগুলি ইলেম, পারকোলেটআপ হয় নীচে সংজ্ঞায়িত করা হয়

import random

def getElem(populationStr, dTree, key):
  msd  = int(populationStr[0])
  if not key in dTree.keys():
    dTree[key] = range(msd + 1)
  idx = random.randint(0, len(dTree[key]) - 1)
  key = key +  str(dTree[key][idx])
  if len(populationStr) == 1:
    dTree[key[:-1]].pop(idx)
    return key, (percolateUp(dTree, key[:-1]))
  newPopulation = populationStr[1:]
  if int(key[-1]) != msd:
    newPopulation = str(10**(len(newPopulation)) - 1)
  return getElem(newPopulation, dTree, key)

def percolateUp(dTree, key):
  while (dTree[key] == []):
    dTree[key[:-1]].remove( int(key[-1]) )
    key = key[:-1]
  return dTree

শেষ অবধি, নীচের হিসাবে নীচের হিসাবে এন এর বৃহত মানটির জন্য গড় সময়কাল প্রায় 15 মিমি ছিল,

In [3]: n = 10000000000000000000000000000000

In [4]: %time l,t = randomSample(n, 5)
Wall time: 15 ms

In [5]: l
Out[5]:
[10000000000000000000000000000000L,
 5731058186417515132221063394952L,
 85813091721736310254927217189L,
 6349042316505875821781301073204L,
 2356846126709988590164624736328L]

আপনি যে উত্তর জটিল বলে মনে করেন ? এটা তাহলে কি ?! এবং তারপরে অন্য উত্তর রয়েছে , যা অনেকগুলি "উত্সাহী পূর্ণসংখ্যার" উত্পন্ন করে। আপনি প্রদত্ত উদাহরণ ইনপুট দিয়ে আমি আপনার বাস্তবায়ন চালিয়েছি (জনসংখ্যার আকার = 1000, স্যাম্পল সাইজ = 999)। আপনার সংস্করণটি random.randintফাংশনটিকে 3996 বার কল করেছে , অন্যদিকে একটি সিসিএ। 6000 বার। উন্নতি হাহ যে বড় না?
কিরিল

@ ক্যারিল, আপনার এই উত্তরটি
aak318

1

একটি প্রোগ্রাম প্রাপ্ত করার জন্য যা ডুপ্লিকেট ছাড়াই এলোমেলো মানগুলির একটি তালিকা তৈরি করে যা ডিস্ট্রিমেন্টিক, দক্ষ এবং বেসিক প্রোগ্রামিং কনস্ট্রাক্টস দিয়ে নির্মিত extractSamplesনীচের সংজ্ঞায়িত ফাংশনটি বিবেচনা করে ,

def extractSamples(populationSize, sampleSize, intervalLst) :
    import random
    if (sampleSize > populationSize) :
        raise ValueError("sampleSize = "+str(sampleSize) +" > populationSize (= " + str(populationSize) + ")")
    samples = []
    while (len(samples) < sampleSize) :
        i = random.randint(0, (len(intervalLst)-1))
        (a,b) = intervalLst[i]
        sample = random.randint(a,b)
        if (a==b) :
            intervalLst.pop(i)
        elif (a == sample) : # shorten beginning of interval                                                                                                                                           
            intervalLst[i] = (sample+1, b)
        elif ( sample == b) : # shorten interval end                                                                                                                                                   
            intervalLst[i] = (a, sample - 1)
        else :
            intervalLst[i] = (a, sample - 1)
            intervalLst.append((sample+1, b))
        samples.append(sample)
    return samples

মূল ধারণাটি হ'ল intervalLstসম্ভাব্য মানগুলির জন্য অন্তরগুলি ট্র্যাক করা যা থেকে আমাদের প্রয়োজনীয় উপাদানগুলি নির্বাচন করতে হবে। এটি নির্ধারিত অর্থে যে আমরা একটি নির্দিষ্ট সংখ্যক পদক্ষেপের মধ্যে একমাত্র নমুনা তৈরির গ্যারান্টিযুক্ত (পুরোপুরি নির্ভরশীল populationSizeএবং sampleSize)।

আমাদের প্রয়োজনীয় তালিকা তৈরি করতে উপরের ফাংশনটি ব্যবহার করতে,

In [3]: populationSize, sampleSize = 10**17, 10**5

In [4]: %time lst1 = extractSamples(populationSize, sampleSize, [(0, populationSize-1)])
CPU times: user 289 ms, sys: 9.96 ms, total: 299 ms
Wall time: 293 ms

আমরা পূর্বের সমাধানের সাথে তুলনা করতে পারি (জনসংখ্যার নিম্ন মানের জন্য)

In [5]: populationSize, sampleSize = 10**8, 10**5

In [6]: %time lst = random.sample(range(populationSize), sampleSize)
CPU times: user 1.89 s, sys: 299 ms, total: 2.19 s
Wall time: 2.18 s

In [7]: %time lst1 = extractSamples(populationSize, sampleSize, [(0, populationSize-1)])
CPU times: user 449 ms, sys: 8.92 ms, total: 458 ms
Wall time: 442 ms

দ্রষ্টব্য যে সমাধানটি populationSizeব্যবহার করার সময় উচ্চতর মানগুলির জন্য মেমরি ত্রুটি তৈরি করার সাথে সাথে আমি মান হ্রাস করেছি random.sample(পূর্ববর্তী উত্তরে এখানে এবং এখানেও উল্লিখিত )। উপরে মান জন্য, আমরা যে মান্য করতে পারেন extractSamplesতূলনায় random.sampleপদ্ধতির।

পিএস: যদিও মূল দৃষ্টিভঙ্গি আমার আগের উত্তরগুলির সাথে সমান , তবুও বাস্তবায়নের ক্ষেত্রে যথেষ্ট পরিবর্তন রয়েছে পাশাপাশি স্বচ্ছতার উন্নতির পাশাপাশি পদ্ধতিরও রয়েছে।


0

একটি খুব সাধারণ ফাংশন যা আপনার সমস্যার সমাধানও করে

from random import randint

data = []

def unique_rand(inicial, limit, total):

        data = []

        i = 0

        while i < total:
            number = randint(inicial, limit)
            if number not in data:
                data.append(number)
                i += 1

        return data


data = unique_rand(1, 60, 6)

print(data)


"""

prints something like 

[34, 45, 2, 36, 25, 32]

"""

0

সেট ভিত্তিক পদ্ধতির সমস্যা ("যদি ফিরতি মানগুলিতে এলোমেলো মান হয় তবে আবার চেষ্টা করুন") সমস্যাটি হ'ল সংঘর্ষের কারণে তাদের রানটাইম নির্ধারিত হয় (যার জন্য আরও একটি "আবার চেষ্টা করুন" পুনরাবৃত্তি প্রয়োজন) বিশেষত যখন বিপুল পরিমাণে এলোমেলো মান ফিরে আসে পরিসীমা থেকে

একটি বিকল্প যা এই অ-নিরোধক রানটাইম প্রবণ নয় নিম্নলিখিতটি হল:

import bisect
import random

def fast_sample(low, high, num):
    """ Samples :param num: integer numbers in range of
        [:param low:, :param high:) without replacement
        by maintaining a list of ranges of values that
        are permitted.

        This list of ranges is used to map a random number
        of a contiguous a range (`r_n`) to a permissible
        number `r` (from `ranges`).
    """
    ranges = [high]
    high_ = high - 1
    while len(ranges) - 1 < num:
        # generate a random number from an ever decreasing
        # contiguous range (which we'll map to the true
        # random number).
        # consider an example with low=0, high=10,
        # part way through this loop with:
        #
        # ranges = [0, 2, 3, 7, 9, 10]
        #
        # r_n :-> r
        #   0 :-> 1
        #   1 :-> 4
        #   2 :-> 5
        #   3 :-> 6
        #   4 :-> 8
        r_n = random.randint(low, high_)
        range_index = bisect.bisect_left(ranges, r_n)
        r = r_n + range_index
        for i in xrange(range_index, len(ranges)):
            if ranges[i] <= r:
                # as many "gaps" we iterate over, as much
                # is the true random value (`r`) shifted.
                r = r_n + i + 1
            elif ranges[i] > r_n:
                break
        # mark `r` as another "gap" of the original
        # [low, high) range.
        ranges.insert(i, r)
        # Fewer values possible.
        high_ -= 1
    # `ranges` happens to contain the result.
    return ranges[:-1]

0
import random

sourcelist=[]
resultlist=[]

for x in range(100):
    sourcelist.append(x)

for y in sourcelist:
    resultlist.insert(random.randint(0,len(resultlist)),y)

print (resultlist)

1
স্ট্যাকওভারফ্লোতে আপনাকে স্বাগতম। আপনার উত্তরটি কেন এবং কীভাবে সমস্যার সমাধান করে তা ব্যাখ্যা করুন যাতে অন্যরা আপনার উত্তর সহজেই বুঝতে পারে।
অক্টোবাস

এই কোডটি কীভাবে এবং কেন এই সমস্যার সমাধান করে তার ব্যাখ্যা সহ প্রশ্নটি সমাধান করতে পারে যদিও আপনার পোস্টের গুণমান উন্নত করতে সত্যই সহায়তা করবে এবং সম্ভবত আরও বেশি ভোটের ফলাফল হবে। মনে রাখবেন যে আপনি ভবিষ্যতে পাঠকদের জন্য প্রশ্নের উত্তর দিচ্ছেন, কেবল এখন যে ব্যক্তি জিজ্ঞাসা করছেন তা নয়। দয়া করে সম্পাদনা ব্যাখ্যা যোগ করতে পারেন এবং সীমাবদ্ধতা এবং অনুমানের কি প্রয়োগ একটি ইঙ্গিত দিতে আপনার উত্তর। পর্যালোচনা থেকে
ডাবল-বীপ

-1

আপনি যদি নিশ্চিত করতে চান যে সংখ্যাগুলি যুক্ত হচ্ছে তা অনন্য, আপনি একটি সেট অবজেক্টটি ব্যবহার করতে পারেন

২.7 বা তার বেশি ব্যবহার করে, বা না থাকলে সেট মডিউল আমদানি করুন।

অন্যরা যেমন উল্লেখ করেছে, এর অর্থ সংখ্যাটি সত্যই এলোমেলো নয়।


-1

মধ্যে প্রতিস্থাপন ছাড়া নমুনা পূর্ণসংখ্যার minvalএবং maxval:

import numpy as np

minval, maxval, n_samples = -50, 50, 10
generator = np.random.default_rng(seed=0)
samples = generator.permutation(np.arange(minval, maxval))[:n_samples]

# or, if minval is 0,
samples = generator.permutation(maxval)[:n_samples]

জ্যাক্স সহ:

import jax

minval, maxval, n_samples = -50, 50, 10
key = jax.random.PRNGKey(seed=0)
samples = jax.random.shuffle(key, jax.numpy.arange(minval, maxval))[:n_samples]

আপনি কেন সম্ভাব্য সংখ্যক উপাদানের একটি পারমুটাইটন তৈরি করবেন এবং তারপরে কেবল n_samplesতাদের মধ্যে প্রথমটি নির্বাচন করবেন? এই পদ্ধতির পিছনে আপনার যুক্তি কী? বিপুল সংখ্যক বিদ্যমান উত্তরের তুলনায় আপনার পদ্ধতির সুবিধা কী কী তা ব্যাখ্যা করতে পারেন (এর বেশিরভাগটি 8 বছর আগে থেকেই)?
কিরিল

প্রকৃতপক্ষে আমার উত্তরটিতে অন্যান্য শীর্ষ ভোট প্রাপ্ত উত্তরের মতো জটিলতা রয়েছে এবং দ্রুততর কারণ এটি অসাধ্য ব্যবহার করে। অন্য, শীর্ষ-ভোট প্রাপ্ত পদ্ধতিগুলি ব্যবহার করে random.shuffle, যা মার্সেন টুইস্টার ব্যবহার করে, কিচিচ নম্পির (এবং সম্ভবত জ্যাক্স) প্রস্তাবিত আলগোসের তুলনায় অনেক ধীর। নম্পি এবং জ্যাক্স অন্যান্য এলোমেলো সংখ্যা জেনারেশন অ্যালগরিদমের জন্য অনুমতি দেয়। জ্যাকস জিট-সংকলন এবং পার্থক্যকেও মঞ্জুরি দেয় যা স্টোকাস্টিক পার্থক্যের জন্য দরকারী। এছাড়াও, "সম্ভবত বৃহত্তর" অ্যারে সম্পর্কিত, কিছু শীর্ষ ভোটের জবাব ঠিক একই জিনিসটি দিয়ে থাকে random.shuffle, যা আমি মনে করি না যে কোনও আত্মীয় বা এমনকি নিখুঁত অর্থে
পাপযুক্ত

1
আপনি " random.shuffleমার্সেন টোস্টার ব্যবহার করেন " এর অর্থ কী তা নিশ্চিত নন - এটি বেশ কয়েকটি উত্তরে উল্লিখিত ফিশার-ইয়েটস বদলানো। এটির লিনিয়ার টাইম জটিলতা রয়েছে তাই এটি অন্য কোনও লাইব্রেরি, ন্যালি বা অন্যথায় প্রদত্ত অ্যালগরিদমের চেয়ে asyptotically ধীর হতে পারে না। যদি ন্পিটি দ্রুত হয় তবে এটি কেবলমাত্র সিটিতে অন্তর্ভুক্ত থাকার কারণে, তবে এটির থেকে কয়েকটি উপাদান বাছাই করার জন্য এটি বিশাল আকারের (যেটি স্মৃতিতেও মাপসই করা যায় না) উত্পন্ন করার নিশ্চয়তা দেয় না। একটা নয় একক পুলিশের যা এই আছে ব্যতীত উত্তর।
কিরিল

আমার ক্ষমা, আমি পড়লাম যে অজগরটি এলোমেলোভাবে মার্সেন টুইস্টারকে প্রঙ হিসাবে ব্যবহার করেছে। আপনার কি এমন কোনও উত্স আছে যাতে আমি ফিশার ইয়েটস এবং এলোমেলো.স্যাফলের ভূমিকা সম্পর্কে আরও জানতে পারি?
গ্রিসাইটিস

এখানে দুটি পৃথক উত্তরের উইকিপিডিয়ায় ইতিমধ্যে দুটি পৃথক লিঙ্ক রয়েছে। উইকিপিডিয়া যদি আপনার পক্ষে যথেষ্ট ভাল উত্স না হয় তবে নিবন্ধের শেষে 14 টি উল্লেখ রয়েছে। এবং তারপরে গুগল আছে। এটা কি সাহায্য করে? ওহ, এবং randomমডিউলটি পাইথনে লেখা হয়েছে, যাতে আপনি সহজেই এর উত্সটি দেখতে পারেন (চেষ্টা করুন random.__file__)।
কিরিল

-3

উইন এক্সপি-তে সিএলআই থেকে:

python -c "import random; print(sorted(set([random.randint(6,49) for i in range(7)]))[:6])"

কানাডায় আমাদের 6/49 লোটো রয়েছে। আমি শুধু lotto.bat মধ্যে উপরের কোড মোড়ানো এবং চালানোর C:\home\lotto.batবা শুধু C:\home\lotto

কারণ random.randintপ্রায়ই একটি সংখ্যা পুনরাবৃত্তি, আমি ব্যবহার setসঙ্গে range(7)এবং তারপর 6 দৈর্ঘ্য তা কমান।

কখনও কখনও যদি কোনও সংখ্যা 2 বারের বেশি পুনরাবৃত্তি করে তবে ফলাফলের তালিকার দৈর্ঘ্য 6 এরও কম হবে।

সম্পাদনা: যাইহোক, random.sample(range(6,49),6)সঠিক উপায়।


-3
import random
result=[]
for i in range(1,50):
    rng=random.randint(1,20)
    result.append(rng)

1
আপনি কী ব্যাখ্যা করতে পারবেন যে এটি কীভাবে নকলগুলি এড়িয়ে চলে? এই কোড ডাম্প থেকে এটি সুস্পষ্ট নয়।
টবি স্পিড 14

এটা হয় না। print len(result), len(set(result))। আপনি আশা করতে পারেন যে resultপ্রতি 1.0851831788708547256608362340568947172111832359638926... × 10^20চেষ্টা করার পরে এটিতে অনন্য উপাদান থাকবে ।
Jedi
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.