ও (1) এ অনন্য (পুনরাবৃত্তি না করা) এলোমেলো সংখ্যা?


179

আমি 0 এবং 1000 এর মধ্যে অনন্য এলোমেলো সংখ্যা তৈরি করতে চাই যা কখনই পুনরাবৃত্তি করে না (অর্থাত 6 বার দু'বার প্রদর্শিত হয় না) তবে এটি করতে পূর্ববর্তী মানগুলির ও (এন) অনুসন্ধানের মতো কিছু অবলম্বন করে না। এটা কি সম্ভব?



2
0 0 এবং 1000 এর মধ্যে?
পিট কিরখাম

4
আপনি যদি অবিচ্ছিন্ন সময়ের সাথে ( O(n)যথা সময় বা স্মৃতিতে) কোনও কিছুকে নিষিদ্ধ করছেন , তবে নীচের অনেকগুলি উত্তর গ্রহণযোগ্য উত্তর সহ ভুল।
jww

আপনি কীভাবে এক কার্ডের প্যাকেট বদল করবেন?
কর্নেল আতঙ্ক

9
সতর্কবার্তা! সত্যিকারের এলোমেলো ক্রম উত্পাদন না করার জন্য নীচে দেওয়া উত্তরগুলির অনেকগুলি ও (এন) এর চেয়ে ধীর বা অন্যথায় ত্রুটিযুক্ত! কোডিংহরর.কম / ব্লগ / আর্কাইভস / ১০০১১১৫ এইচটিএমএল আপনি যে কোনও একটি ব্যবহার করার আগে বা আপনার নিজের মনস্থির করার চেষ্টা করার আগে একটি আবশ্যক পঠন!
ivan_pozdeev

উত্তর:


247

0-1000 মানগুলির সাথে 1001 পূর্ণসংখ্যার অ্যারের সূচনা করুন এবং অ্যারের বর্তমান সর্বাধিক সূচীতে (1000 দিয়ে শুরু) একটি পরিবর্তনশীল, সর্বোচ্চ সেট করুন। 0 এবং সর্বাধিকের মধ্যে একটি এলোমেলো সংখ্যা বাছুন, পজিশন সর্বাধিক সংখ্যার সাথে পজিশন আরে নম্বরটি স্যুপ করুন এবং সর্বাধিক পজিশনে পজিশনটি ফিরিয়ে দিন। 1 দ্বারা সর্বোচ্চ হ্রাস এবং চালিয়ে যান। যখন সর্বোচ্চ 0 হয়, অ্যারের আকারে সর্বাধিক পিছনে সেট করুন - 1 এবং অ্যারেটিকে পুনরায় পুনর্নির্মাণের প্রয়োজন ছাড়াই আবার শুরু করুন।

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

অ্যারে থেকে 11 টি উপাদান শুরু করে অ্যারে শুরু হয় [n] = n, সর্বোচ্চ 10 থেকে শুরু হবে:

+--+--+--+--+--+--+--+--+--+--+--+
| 0| 1| 2| 3| 4| 5| 6| 7| 8| 9|10|
+--+--+--+--+--+--+--+--+--+--+--+
                                ^
                               max    

প্রতিটি পুনরাবৃত্তির সময়, 0 এবং সর্বোচ্চের মধ্যে একটি এলোমেলো সংখ্যা আর নির্বাচন করা হয়, অ্যারে [আর] এবং অ্যারে [সর্বাধিক] অদলবদল করা হয়, নতুন অ্যারে [সর্বাধিক] ফিরে আসে এবং সর্বোচ্চ হ্রাস হয়:

max = 10, r = 3
           +--------------------+
           v                    v
+--+--+--+--+--+--+--+--+--+--+--+
| 0| 1| 2|10| 4| 5| 6| 7| 8| 9| 3|
+--+--+--+--+--+--+--+--+--+--+--+

max = 9, r = 7
                       +-----+
                       v     v
+--+--+--+--+--+--+--+--+--+--+--+
| 0| 1| 2|10| 4| 5| 6| 9| 8| 7: 3|
+--+--+--+--+--+--+--+--+--+--+--+

max = 8, r = 1
     +--------------------+
     v                    v
+--+--+--+--+--+--+--+--+--+--+--+
| 0| 8| 2|10| 4| 5| 6| 9| 1: 7| 3|
+--+--+--+--+--+--+--+--+--+--+--+

max = 7, r = 5
                 +-----+
                 v     v
+--+--+--+--+--+--+--+--+--+--+--+
| 0| 8| 2|10| 4| 9| 6| 5: 1| 7| 3|
+--+--+--+--+--+--+--+--+--+--+--+

...

১১ টি পুনরাবৃত্তির পরে অ্যারেতে সমস্ত সংখ্যা নির্বাচন করা হয়েছে, সর্বোচ্চ == 0 এবং অ্যারের উপাদানগুলি পরিবর্তন করা হয়েছে:

+--+--+--+--+--+--+--+--+--+--+--+
| 4|10| 8| 6| 2| 0| 9| 5| 1| 7| 3|
+--+--+--+--+--+--+--+--+--+--+--+

এই মুহুর্তে, সর্বোচ্চ 10 এ পুনরায় সেট করা যেতে পারে এবং প্রক্রিয়াটি চালিয়ে যেতে পারে।



14
@ পিটার রাউন: আমার মনে হয় না; এটি আমার কাছে ফিশার ইয়েটস অ্যালগরিদমের মতো দেখতেও জেফের পোস্টে উদ্ধৃত হয়েছে (ভাল লোক হিসাবে)।
ব্রেন্ট.লংবোরো

3
@ আরবার্ট: আমি কেবল ইঙ্গিত করতে চেয়েছিলাম যে এটি উত্পাদন করে না, যেমন প্রশ্নের নামে, "ও (1) এ অনন্য এলোমেলো সংখ্যা"।
চার্লস

3
@ মিকেরা: সম্মত, যদিও প্রযুক্তিগতভাবে আপনি স্থির আকারের পূর্ণসংখ্যার ব্যবহার করছেন তবে পুরো তালিকাটি ও (1) এ তৈরি করা যেতে পারে (একটি বৃহত ধ্রুবক সহ, যেমন 2 ^ 32)। এছাড়াও, ব্যবহারিক উদ্দেশ্যে, "এলোমেলো" সংজ্ঞাটি গুরুত্বপূর্ণ - আপনি যদি সত্যই আপনার সিস্টেমের এনট্রপি পুল ব্যবহার করতে চান তবে সীমাটি হ'ল এলোমেলো বিটের গণনা নিজেই গণনার চেয়ে, এবং সেই ক্ষেত্রে n লগ এন প্রাসঙ্গিক আবার। তবে সম্ভবত আপনি / dev / এলোমেলো পরিবর্তে / dev / urandom ব্যবহার করবেন (আপনি সম্ভবত 'O' (N) এ ফিরে আসবেন।
চার্লস

4
আমি কিছুটা বিভ্রান্ত হয়ে পড়েছি, Nপ্রতিটি বারের পছন্দসই ফলাফলটি পাওয়ার জন্য আপনাকে পুনরাবৃত্তি করতে হবে (এই উদাহরণে ১১) আপনি কি তা বোঝাতে চান O(n)? একই প্রাথমিক অবস্থা থেকে সংমিশ্রণের জন্য যেমন আপনাকে Nপুনরাবৃত্তিগুলি করতে হবে N!, অন্যথায় আপনার আউটপুট কেবল এন স্টেটগুলির মধ্যে একটি হবে।
Seph

71

তুমি এটি করতে পারো:

  1. একটি তালিকা তৈরি করুন, 0..1000।
  2. তালিকা বদলান। ( ফিশার-ইয়েটস এটি করার ভাল উপায়ের জন্য বদলে দেখুন ))
  3. বদলানো তালিকা থেকে ক্রমানুসারে নম্বরগুলি প্রদান করুন।

সুতরাং এটির জন্য প্রতিবার পুরানো মানগুলির সন্ধানের প্রয়োজন হয় না, তবে প্রাথমিক শফলের জন্য এটি এখনও ও (এন) প্রয়োজন। নীল যেমন মন্তব্যগুলিতে ইঙ্গিত করেছেন, এটি হে মোরিটেড হে (1)।


5
@ জাস্ট কিছু গাই এন = 1000, তাই আপনি বলছেন যে এটি ও (এন / এন) যা ও (1)
গুভান্তে

1
যদি বদলানো অ্যারেতে প্রতিটি সন্নিবেশ কোনও ক্রিয়াকলাপ হয় তবে 1 টি মান সন্নিবেশ করার পরে আপনি 1 টি এলোমেলো মান পেতে পারেন। 2 টি 2 টি মানের জন্য এবং আরও অনেকগুলি জন্য n মানগুলি। তালিকাটি তৈরি করতে n অপারেশনগুলি লাগে, সুতরাং পুরো অ্যালগরিদমটি হ'ল (এন)। আপনার যদি 1,000,000 এলোমেলো মান প্রয়োজন হয় তবে এটির জন্য 1,00,000 অপস নেবে
কিব্বি

3
এটিকে নিয়ে এভাবে ভাবুন, যদি এটি ধ্রুবক সময় হয় তবে এটি 10 ​​এলোমেলো সংখ্যার জন্য একই পরিমাণে সময় নেবে যেমনটি 10 ​​বিলিয়ন হবে। তবে ও (এন) নেওয়ার কারণে এলোমেলো হওয়ার কারণে আমরা জানি যে এটি সত্য নয়।
কিবিবে

1
এটি আসলে এমোরিটাইজড সময় নেবে (লগ এন), যেহেতু আপনাকে এন এলজি এন র্যান্ডম বিট তৈরি করতে হবে।
চার্লস

2
এবং এখন, এটি করার সমস্ত যুক্তি আমার আছে! meta.stackoverflow.com/q/252503/13
ক্রিস জাস্টার-ইয়ং

60

সর্বাধিক লিনিয়ার প্রতিক্রিয়া শিফট রেজিস্টার ব্যবহার করুন ।

এটি সি এর কয়েকটি লাইনে বাস্তবায়নযোগ্য এবং রানটাইমের সময় কয়েকটি পরীক্ষা / শাখা, কিছুটা সংযোজন এবং বিট শিফটিংয়ের চেয়ে সামান্য কিছু করে। এটি এলোমেলো নয়, তবে বেশিরভাগ লোককে বোকা বানাবে।


12
"এটি এলোমেলো নয়, তবে বেশিরভাগ লোককে বোকা বানায়"। এটি সমস্ত ছদ্ম-এলোমেলো সংখ্যা জেনারেটর এবং এই প্রশ্নের সমস্ত সম্ভাব্য উত্তরের ক্ষেত্রে প্রযোজ্য। তবে বেশিরভাগ লোক এ নিয়ে ভাববে না। সুতরাং এই নোটটি বাদ দেওয়ার ফলে আরও বেশি উত্স হতে পারে ...
f3lix

3
@ বোবোবো: ও (1) স্মৃতি কেন।
অ্যাশ

3
নিত: এটি ও (লগ এন) মেমরি।
পল হানকিন

2
এই পদ্ধতিটি ব্যবহার করে, আপনি 0 এবং 800000 এর মধ্যে কীভাবে সংখ্যা উত্পন্ন করবেন? কেউ কেউ এলএফএসআর ব্যবহার করতে পারেন যা পিরিয়ডটি 1048575 (2 ^ 20 - 1) হয় এবং নম্বরটি সীমার বাইরে থাকলে পরবর্তীটি পেতে পারে তবে এটি কার্যকর হবে না।
টাইগার করুন

1
এলএফএসআর হিসাবে, এটি সমানভাবে বিতরণ করা ক্রমগুলি উত্পাদন করে না : উত্পন্ন হবে পুরো ক্রমটি প্রথম উপাদান দ্বারা সংজ্ঞায়িত করা হয়েছে।
ivan_pozdeev

21

আপনি একটি লিনিয়ার কগ্রুভেন্সি জেনারেটর ব্যবহার করতে পারেন । যেখানে m(মডিউলাস) 1000 এর চেয়ে নিকটতম প্রধানতম হবে When আপনি যখন একটি নম্বর সীমার বাইরে পান, কেবলমাত্র পরবর্তীটি পান। সমস্ত উপাদান উপস্থিত হয়ে গেলে ক্রমটি কেবল পুনরাবৃত্তি করবে এবং আপনাকে কোনও সারণী ব্যবহার করতে হবে না। যদিও এই জেনারেটরের অসুবিধাগুলি সম্পর্কে সচেতন হন (এলোমেলোতার অভাব সহ)।


1
1009 প্রথম প্রধানমন্ত্রী হয় 1000. পরে
Teepeemm

একটি এলসিজির পরপর সংখ্যার মধ্যে উচ্চতর সম্পর্ক থাকে, সুতরাং সংমিশ্রণগুলি বড় পরিমাণে এলোমেলো হবে না (উদাহরণস্বরূপ সংখ্যার চেয়ে আরও বেশি সংখ্যাগুলি kকখনও একসাথে ঘটতে পারে না)।
ivan_pozdeev

মি এর উপাদানগুলির সংখ্যা 1001 (শূন্যের জন্য 1000 + 1) হওয়া উচিত এবং আপনি নেক্সট = (1002 * কারেন্ট + 757) মোড 1001 ব্যবহার করতে পারেন;
সর্বোচ্চ আব্রামোভিচ

21

কাউন্টারকে এনক্রিপ্ট করতে আপনি ফর্ম্যাট-সংরক্ষণের এনক্রিপশন ব্যবহার করতে পারেন । আপনার কাউন্টারটি কেবল 0 থেকে উপরের দিকে চলে যায় এবং এনক্রিপশনটি আপনার পছন্দের একটি কী ব্যবহার করে যা আপনি চান তার মূল এবং প্রস্থের আপাতদৃষ্টিতে এলোমেলো মান হিসাবে রূপান্তর করতে পারেন। উদাহরণস্বরূপ, এই প্রশ্নের উদাহরণস্বরূপ: 10 মূল, প্রস্থ 3।

ব্লক সিফারগুলিতে সাধারণত একটি নির্দিষ্ট ব্লক আকার থাকে যেমন 64৪ বা 128 বিট। তবে ফর্ম্যাট-সংরক্ষণ সংরক্ষণ এনক্রিপশন আপনাকে এইএসের মতো মানক সাইফার নিতে এবং একটি অ্যালগোরিদম সহ যা এখনও ক্রিপ্টোগ্রাফিকভাবে মজবুত, একটি অ্যালগোরিদম সহ আপনাকে এএসএসের মতো একটি আদর্শ সাইফার নিতে এবং একটি ছোট-প্রস্থের সাইফার তৈরি করতে দেয়।

এটি কখনও সংঘর্ষ না হওয়ার গ্যারান্টিযুক্ত (কারণ ক্রিপ্টোগ্রাফিক অ্যালগোরিদমগুলি 1: 1 ম্যাপিং তৈরি করে)। এটি বিপরীতমুখীও (একটি দ্বি-উপায়ে ম্যাপিং), যাতে আপনি ফলাফলটি নিতে পারেন এবং আপনার শুরু হওয়া পাল্টা মানটিতে ফিরে আসতে পারেন।

এই কৌশলটিতে কোনও বদলানো অ্যারে ইত্যাদি সঞ্চয় করতে মেমরির প্রয়োজন হয় না, যা সীমিত মেমরির সিস্টেমে সুবিধা হতে পারে।

এটি অর্জনের জন্য এইএস-এফএফএক্স একটি প্রস্তাবিত মানক পদ্ধতি standard আমি কিছু বেসিক পাইথন কোড পরীক্ষা করেছি যা এইএস-এফএফএক্স ধারণার উপর ভিত্তি করে তৈরি করা হয়েছে, যদিও এটি সম্পূর্ণরূপে উপযুক্ত নয় - পাইথন কোডটি এখানে দেখুন । এটি উদাহরণস্বরূপ এলোমেলো-দেখায় digit-সংখ্যার দশমিক সংখ্যা, বা একটি 16-বিট সংখ্যার একটি কাউন্টার এনক্রিপ্ট করতে পারে। প্রশ্নটি বর্ণিত হিসাবে এখানে 10 মুলক, প্রস্থ 3 (0 এবং 999 সহ একটি নম্বর দেওয়ার জন্য) উদাহরণ রয়েছে:

000   733
001   374
002   882
003   684
004   593
005   578
006   233
007   811
008   072
009   337
010   119
011   103
012   797
013   257
014   932
015   433
...   ...

বিভিন্ন অ-পুনরাবৃত্তি ছদ্ম-এলোমেলো ক্রমগুলি পেতে, এনক্রিপশন কীটি পরিবর্তন করুন। প্রতিটি এনক্রিপশন কী আলাদা-পুনরাবৃত্তি ছদ্ম-এলোমেলো ক্রম উত্পাদন করে produces


এটি মূলত একটি সরল ম্যাপিং, এইভাবে সমস্ত প্রাসঙ্গিক কিঙ্কের সাথে এলসিজি এবং এলএফএসআর থেকে আলাদা নয় (উদাহরণস্বরূপ kক্রমগুলির চেয়ে আলাদা মানগুলি কখনই একসাথে ঘটতে পারে না)।
ivan_pozdeev

@ আইভান_পোজদেদেভ: আপনার মন্তব্যের অর্থ বুঝতে আমার অসুবিধা হচ্ছে। আপনি কী এই ম্যাপিংয়ে ভুল, "সমস্ত প্রাসঙ্গিক কিঙ্কস" কী এবং কী কী তা ব্যাখ্যা করতে পারেন k?
ক্রেগ ম্যাককুইন

কার্যকরভাবে এখানে সমস্ত "এনক্রিপশন" হ'ল 1,2,...,Nক্রমটি অন্য কয়েকটিতে একই সংখ্যার ক্রমের সাথে প্রতিস্থাপন করা হয়েছে , তবে এখনও স্থির, ক্রম। একের পর এক এই ক্রম থেকে সংখ্যাগুলি টানা হয়। kবাছাই করা মানগুলির সংখ্যা (ওপি কোনও চিঠি নির্দিষ্ট করে নি তাই আমাকে একটি পরিচয় করিয়ে দিতে হবে)।
ivan_pozdeev

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

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

7

0 ... 1000 এর মতো কম সংখ্যার জন্য, এমন একটি তালিকা তৈরি করুন যাতে সমস্ত নম্বর থাকে এবং এগুলি বদলে যায় সরাসরি এগিয়ে forward তবে অঙ্কনের সংখ্যাগুলির সেটটি যদি খুব বড় হয় তবে অন্য একটি মার্জিত উপায় আছে: আপনি একটি কী এবং একটি ক্রিপ্টোগ্রাফিক হ্যাশ ফাংশন ব্যবহার করে সিউডোরডম ক্রমান্বতি তৈরি করতে পারেন। নিম্নলিখিত সি ++ দেখুন - সিউডো কোডের উদাহরণ উদাহরণ:

unsigned randperm(string key, unsigned bits, unsigned index) {
  unsigned half1 =  bits    / 2;
  unsigned half2 = (bits+1) / 2;
  unsigned mask1 = (1 << half1) - 1;
  unsigned mask2 = (1 << half2) - 1;
  for (int round=0; round<5; ++round) {
    unsigned temp = (index >> half1);
    temp = (temp << 4) + round;
    index ^= hash( key + "/" + int2str(temp) ) & mask1;
    index = ((index & mask2) << half1) | ((index >> half2) & mask1);
  }
  return index;
}

এখানে, hashকেবল কিছু স্বেচ্ছাসেবী ছদ্ম র্যান্ডম ফাংশন যা একটি বিশাল অক্ষরযুক্ত সংখ্যায় একটি অক্ষরের স্ট্রিং মানচিত্র করে। ফাংশনটি randperm0 ... পাও (2, বিট) -1 এর মধ্যে একটি নির্দিষ্ট কী ধরে ধরে সমস্ত সংখ্যার ক্রমবর্ধমান। এটি নির্মাণ থেকে অনুসরণ করে কারণ প্রতিটি পদক্ষেপ যা পরিবর্তনশীল পরিবর্তন করে indexতা বিপরীত। এটি একটি ফেস্টেল সাইফার দ্বারা অনুপ্রাণিত ।


স্ট্যাকওভারফ্লো.com / a / 16097246 / 648265 হিসাবে একই , সিকোয়েন্সগুলির জন্য একই রকমের এলোমেলো ব্যর্থতা।
ivan_pozdeev

1
@ আইভান_পোজদেদেভ: তত্ত্ব অনুসারে, অসীম কম্পিউটিং শক্তি ধরে, হ্যাঁ। যাইহোক, যে অভিমানী hash(), যেমন উপরের কোড ব্যবহৃত একটি নিরাপদ সিউডোরান্ডম ফাংশন, এই নির্মাণ provably (Luby & Rackoff, 1988) একটি সমর্পণ করা হবে সিউডোরান্ডম বিন্যাস , যা একটি সত্য র্যান্ডম এলোমেলো একটি সম্পূর্ণ তুলনায় উল্লেখযোগ্যভাবে কম প্রচেষ্টার ব্যবহার থেকে আলাদা করা যাবে না সমগ্র দৈর্ঘ্যের কী স্পেস অনুসন্ধান করুন যা কী দৈর্ঘ্যের ক্ষেত্রে সূচকীয়। এমনকি যুক্তিসঙ্গত আকারের কীগুলির জন্য (বলুন, 128 বিট), এটি পৃথিবীতে উপলব্ধ মোট কম্পিউটিং পাওয়ারের বাইরে।
ইলমারি করোনেন

(বিটিডাব্লু, এই যুক্তিটিকে আরও কিছুটা কঠোর করার জন্য, আমি hash( key + "/" + int2str(temp) )উপরের অ্যাডহক নির্মাণকে এইচএমএসি দিয়ে প্রতিস্থাপন করতে পছন্দ করব , যার সুরক্ষা পরিবর্তিতভাবে অন্তর্নিহিত হ্যাশ সংক্ষেপণের ফাংশনকে হ্রাস করা যেতে পারে Also এছাড়াও, এইচএমএসি ব্যবহার করতে পারে কোনও অনিরাপদ নন-ক্রিপ্টো হ্যাশ ফাংশন দিয়ে ভুল করে এই
নির্মাণটি

6

আপনি এখানে বর্ণিত আমার Xincrol অ্যালগরিদম ব্যবহার করতে পারেন:

http://openpatent.blogspot.co.il/2013/04/xincrol-unique-and-random-number.html

এটি অ্যারে, তালিকাগুলি, ক্রমান্বয়ে বা ভারী সিপিইউ লোড ছাড়াই এলোমেলো তবে অনন্য সংখ্যা উত্পন্ন করার খাঁটি অ্যালগরিদমিক পদ্ধতি।

সর্বশেষ সংস্করণটি সংখ্যার পরিসীমাও সেট করতে দেয়, উদাহরণস্বরূপ, যদি আমি 0-1073741821 এর পরিসরে অনন্য র্যান্ডম সংখ্যা চাই want

আমি এটি ব্যবহারিকভাবে ব্যবহার করেছি

  • এমপি 3 প্লেয়ার যা প্রতিটি গান এলোমেলোভাবে বাজায় তবে কেবলমাত্র অ্যালবাম / ডিরেক্টরি প্রতি একবার
  • পিক্সেল অনুযায়ী ভিডিও ফ্রেমগুলি দ্রবীভূত প্রভাব (দ্রুত এবং মসৃণ)
  • স্বাক্ষর এবং চিহ্নিতকারীদের জন্য চিত্রের উপর একটি গোপন "শব্দ" কুয়াশা তৈরি করা হচ্ছে (স্টেগনোগ্রাফি)
  • ডেটাবেসগুলির মাধ্যমে বিপুল পরিমাণ জাভা অবজেক্টের ক্রমিককরণের জন্য ডেটা অবজেক্ট আইডি
  • ট্রিপল মেজরিটি মেমরি বিট সুরক্ষা
  • ঠিকানা + মান এনক্রিপশন (প্রতিটি বাইট কেবল এনক্রিপ্ট করা হয় না তবে বাফারে একটি নতুন এনক্রিপ্ট করা স্থানে স্থানান্তরিত হয়)। এটি সত্যই আমার উপর ক্রিপ্ট্যানালাইসিস ফেলোদের উন্মাদ করেছে :-)
  • প্লেইন টু প্লেন টু প্লেন যেমন ক্রিপ্ট টেক্সট এনক্রিপশন এসএমএস, ইমেল ইত্যাদির জন্য
  • আমার টেক্সাস হোল্ডেম পোকার ক্যালকুলেটর (টিএইচসি)
  • সিমুলেশনগুলির জন্য আমার বেশ কয়েকটি গেম, "শিফলিং", র‌্যাঙ্কিং
  • অধিক

এটি উন্মুক্ত, বিনামূল্যে। একবার চেষ্টা করে দেখো...


এই পদ্ধতিটি কোনও দশমিক মানের জন্য কাজ করতে পারে, উদাহরণস্বরূপ, 3-অঙ্কের দশমিক ফলাফলের জন্য 3-অঙ্কের দশমিক কাউন্টারকে ঘৃণা করতে পারে?
ক্রেগ ম্যাককুইন

জোরশিফ্ট অ্যালগরিদমের উদাহরণ হিসাবে , এটি সম্পর্কিত একটি এলএফএসআর, সম্পর্কিত সমস্ত কিঙ্কস ( উদাহরণস্বরূপ পৃথকীকরণের চেয়ে বেশি মানগুলি kকখনই একসাথে ঘটতে পারে না)।
ivan_pozdeev

5

এটি সমাধান করার জন্য আপনার এমনকি অ্যারেরও প্রয়োজন নেই।

আপনার একটি বিটমাস্ক এবং একটি কাউন্টার দরকার।

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

নিশ্চিত হয়ে নিন যে যখন কাউন্টারটি 1000 কেটে যাবে, আপনি এটিকে শূন্যতে পুনরায় সেট করুন। এই সময়ে আপনি অন্য একটি ক্রমবর্ধমান বিটমাস্ক নির্বাচন করতে পারেন - যদি আপনি চান - একই সাথে একই সংখ্যার সেট আলাদা ক্রমে তৈরি করতে পারেন।


2
এটি একটি এলএফএসআর থেকে কম লোককে বোকা বানাবে।
স্টার ব্লু

"বিটমাস্ক" 512 এর মধ্যে ... 1023 ঠিক আছে। আরও কিছু জাল এলোমেলো জন্য আমার উত্তর দেখুন। :-)
সেলিবিটজেট

মূলত স্ট্যাকওভারফ্লো.com / a / 16097246 / 648265 এর সমতুল্য , সিকোয়েন্সগুলির জন্য এলোমেলোভাবে ব্যর্থ হয়।
ivan_pozdeev

4

আমি মনে করি লিনিয়ার কংগ্রেসিভ জেনারেটর হ'ল সহজ সমাধান।

এখানে চিত্র বর্ণনা লিখুন

এবং a , c এবং m মানগুলিতে কেবল 3 টি বিধিনিষেধ রয়েছে

  1. মি এবং সি তুলনামূলকভাবে প্রধান,
  2. a-1 মি এর সমস্ত প্রধান কারণ দ্বারা বিভাজ্য
  3. a-1 4 দ্বারা বিভাজ্যযদি মি 4 দ্বারা বিভাজ্য হয়

পিএস পদ্ধতিটি ইতিমধ্যে উল্লেখ করা হয়েছিল তবে ধ্রুবক মানগুলি সম্পর্কে পোস্টটির একটি ভুল অনুমান রয়েছে। নীচের স্থিরদের আপনার ক্ষেত্রে উপযুক্ত কাজ করা উচিত

আপনার যদি আপনি ব্যবহার করতে পারেন a = 1002, c = 757,m = 1001

X = (1002 * X + 757) mod 1001

3

এখানে আমি টাইপ করা কিছু কোড যা প্রথম সমাধানের যুক্তি ব্যবহার করে। আমি জানি এটি "ভাষা অজ্ঞেয়বাদী" তবে যে কেউ দ্রুত ব্যবহারিক সমাধানের সন্ধান করছে সে ক্ষেত্রে এটি কেবল # # তে উদাহরণ হিসাবে উপস্থাপন করতে চেয়েছিলাম।

// Initialize variables
Random RandomClass = new Random();
int RandArrayNum;
int MaxNumber = 10;
int LastNumInArray;
int PickedNumInArray;
int[] OrderedArray = new int[MaxNumber];      // Ordered Array - set
int[] ShuffledArray = new int[MaxNumber];     // Shuffled Array - not set

// Populate the Ordered Array
for (int i = 0; i < MaxNumber; i++)                  
{
    OrderedArray[i] = i;
    listBox1.Items.Add(OrderedArray[i]);
}

// Execute the Shuffle                
for (int i = MaxNumber - 1; i > 0; i--)
{
    RandArrayNum = RandomClass.Next(i + 1);         // Save random #
    ShuffledArray[i] = OrderedArray[RandArrayNum];  // Populting the array in reverse
    LastNumInArray = OrderedArray[i];               // Save Last Number in Test array
    PickedNumInArray = OrderedArray[RandArrayNum];  // Save Picked Random #
    OrderedArray[i] = PickedNumInArray;             // The number is now moved to the back end
    OrderedArray[RandArrayNum] = LastNumInArray;    // The picked number is moved into position
}

for (int i = 0; i < MaxNumber; i++)                  
{
    listBox2.Items.Add(ShuffledArray[i]);
}

3

সীমাটি বেশি হলে এই পদ্ধতিটি অ্যাপ্রোপিয়েট ফলাফল করে এবং আপনি কেবল কয়েকটি এলোমেলো সংখ্যা তৈরি করতে চান।

#!/usr/bin/perl

($top, $n) = @ARGV; # generate $n integer numbers in [0, $top)

$last = -1;
for $i (0 .. $n-1) {
    $range = $top - $n + $i - $last;
    $r = 1 - rand(1.0)**(1 / ($n - $i));
    $last += int($r * $range + 1);
    print "$last ($r)\n";
}

মনে রাখবেন যে সংখ্যাগুলি আরোহী ক্রমে উত্পন্ন হয়েছে, তবে আপনি পরে পরিবর্তন করতে পারবেন।


যেহেতু এই বিনিময়ের বদলে সমন্বয় উৎপাদন করে, আরো সঠিক stackoverflow.com/questions/2394246/...
ivan_pozdeev

1
পরীক্ষা শো এই নিম্ন সংখ্যার দিকে পক্ষপাত আছে: সঙ্গে 2M নমুনার জন্য মাপা সম্ভাব্যতা (top,n)=(100,10)আছেন: (0.01047705, 0.01044825, 0.01041225, ..., 0.0088324, 0.008723, 0.00863635)। আমি পাইথনে পরীক্ষা করেছি, সুতরাং গণিতে সামান্য পার্থক্য এখানে ভূমিকা নিতে পারে (আমি নিশ্চিত করেছিলাম যে গণনা করার জন্য সমস্ত অপারেশনগুলি rভাসমান-পয়েন্ট)।
ivan_pozdeev

হ্যাঁ, এই পদ্ধতিটি সঠিকভাবে কাজ করার জন্য, ওপরের সীমাটি বের করা মানগুলির সংখ্যার চেয়ে অনেক বড় হতে হবে।
সালভা

"ওপরের সীমা [মানের] সংখ্যার চেয়ে অনেক বড় " এমনকি এটি "সঠিকভাবে" কাজ করবে না । সম্ভাবনাগুলি এখনও অল্প ব্যবধানে অসম হবে une
ivan_pozdeev

2

আপনি 10 টি বিট সহ একটি ভাল সিউডো-এলোমেলো নম্বর জেনারেটর ব্যবহার করতে পারেন এবং 0 থেকে 1000 রেখে 1001 থেকে 1023 ফেলে দিতে পারেন।

থেকে এখানে আমরা একটি 10 বিট PRNG জন্য নকশা পেতে ..

  • 10 বিট, প্রতিক্রিয়ার বহুপদী x ^ 10 + x ^ 7 + 1 (সময়কাল 1023)

  • দ্রুত কোড পেতে গ্যালোস এলএফএসআর ব্যবহার করুন


@ ফোব না যা হবেনা, কারণ লিনিয়ার ফিডব্যাক শিফট রেজিস্টার ভিত্তিক 10 বিট পিআরএনজি সাধারণত প্রথম মানটিতে ফিরে আসার আগে একবারে সমস্ত মান (এক ব্যতীত) ধরে নেওয়া হয় from অন্য কথায়, এটি চক্রের সময় ঠিক একবারে 1001 বাছাই করে।
নুওজি

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

1
একমাত্র সমস্যাটি হ'ল একটি প্রদত্ত এলএফএসআর এর কেবল একটি ক্রম থাকে, এইভাবে বাছাই করা সংখ্যার মধ্যে শক্তিশালী সম্পর্ক দেয় - বিশেষত, প্রতিটি সম্ভাব্য সংমিশ্রণ তৈরি করে না।
ivan_pozdeev

2
public static int[] randN(int n, int min, int max)
{
    if (max <= min)
        throw new ArgumentException("Max need to be greater than Min");
    if (max - min < n)
        throw new ArgumentException("Range needs to be longer than N");

    var r = new Random();

    HashSet<int> set = new HashSet<int>();

    while (set.Count < n)
    {
        var i = r.Next(max - min) + min;
        if (!set.Contains(i))
            set.Add(i);
    }

    return set.ToArray();
}

N নন-পুনরাবৃত্তি করা এলোমেলো সংখ্যার প্রয়োজন হিসাবে ও (এন) জটিলতার হবে।
দ্রষ্টব্য: থ্রেড সুরক্ষা প্রয়োগের সাথে এলোমেলো স্ট্যাটিক হওয়া উচিত।


ও (এন ^ 2), পুনরায় চেষ্টা করার সংখ্যাটি এখনও পর্যন্ত নির্বাচিত উপাদানগুলির সংখ্যার সাথে আনুপাতিক।
ivan_pozdeev

এটি সম্পর্কে চিন্তা করুন, আপনি যদি মিনিট = 0 সর্বোচ্চ = 10000000 এবং এন = 5 নির্বাচন করেন তবে কতজন নির্বাচিতই হোক না কেন ~ = 0 পুনরায় চেষ্টা করুন। তবে হ্যাঁ আপনার একটি বক্তব্য রয়েছে যে সর্বোচ্চ-মিনিট ছোট হলে, ও (এন) বিচ্ছেদ হয়।
এরেজ রবিনসন

যদি এন << (সর্বোচ্চ-মিনিট) হয় তবে এটি এখনও সমানুপাতিক, এটি কেবল সহগ খুব কম very এবং সহগগুলি অ্যাসিপটোটিক অনুমানের জন্য কোনও বিষয় নয়।
ivan_pozdeev

এটি ও (এন) নয়। প্রতিটি সময় সেটটিতে এই মানটি এবং অতিরিক্ত লুপ থাকে।
পাপারাজ্জো

2

ধরা যাক আপনি একবারে O(n)আবারও এলোমেলো শুরু করতে দেরি না করেই আপনি বার বার পরিবর্তিত তালিকার উপরে যেতে চান, সেক্ষেত্রে আমরা এটি করতে পারি:

  1. 0 এবং 1000 সহ 2 টি তালিকা A এবং B তৈরি করুন, 2nস্থান নেয় ।

  2. ফিশার-ইয়েটস ব্যবহার করে শাফল তালিকাটি nসময় নেয় ।

  3. একটি সংখ্যা অঙ্কনের সময়, অন্য তালিকায় 1-পদক্ষেপের ফিশার-ইয়েটস বদল করুন।

  4. কার্সার তালিকার শেষে থাকলে অন্য তালিকায় স্যুইচ করুন।

Preprocess

cursor = 0

selector = A
other    = B

shuffle(A)

আঁকা

temp = selector[cursor]

swap(other[cursor], other[random])

if cursor == N
then swap(selector, other); cursor = 0
else cursor = cursor + 1

return temp

এটি 2 টি তালিকাগুলি রাখার প্রয়োজন নেই - বা স্টারিংয়ের আগে কোনও তালিকা ছাড়িয়ে দেবে। ফিশার-ইয়েটস যে কোনও প্রাথমিক অবস্থা থেকে অভিন্ন র্যান্ডম ফলাফল দেয়। ব্যাখ্যার জন্য স্ট্যাকওভারফ্লো . com/a/158742/648265 দেখুন ।
ivan_pozdeev

@ আইভান_পোজদেদেভ হ্যাঁ, এটি একই ফলাফল, তবে আমার ধারণা এখানে অঙ্কন ক্রিয়াকলাপের অংশবদল করে এটিকে ()) স্বতন্ত্র করে তোলা।
খালেদ.কে

আপনি বুঝতে পারেন নি। আপনাকে আবার বদলে দেওয়ার আগে তালিকাটি পুনরায় সেট করার দরকার নেই । বদলে [1,3,4,5,2]যাওয়া একই রকম ফলাফল বদলে দেবে [1,2,3,4,5]
ivan_pozdeev

2

প্রশ্নটি আপনি কীভাবে কে-অ-পুনরাবৃত্তি পূর্ণসংখ্যার একটি তালিকা 0 এবং একটি উচ্চতর বাউন্ড এন এর মধ্যে ডুপ্লিকেট হিসাবে যুক্ত করেছেন তা কীভাবে তৈরি করতে পারেন - এবং যদি আপনি এমন কিছু চান যা উত্পন্ন র্যান্ডম সংখ্যার চেয়ে ও (1) হয় (কোনও ও (এন) ছাড়াই) স্টার্টআপ ব্যয়)) স্বীকৃত উত্তরের একটি সহজ ঝাঁকুনি রয়েছে।

একটি খালি অর্ডারযুক্ত মানচিত্র তৈরি করুন (খালি অর্ডার করা মানচিত্রটি ইলিজার থেকে ওপেন (লগ কে)) পূর্ণসংখ্যা থেকে পূর্ণসংখ্যায় নিয়ে যাবে - প্রারম্ভিক অ্যারে ব্যবহারের পরিবর্তে। সর্বাধিক হলে 1000 এ সেট করুন,

  1. 0 এবং সর্বোচ্চের মধ্যে একটি এলোমেলো সংখ্যা বাছুন, আর।
  2. আনর্ডার্ড মানচিত্রে মানচিত্রের উপাদানগুলি r এবং সর্বোচ্চ উভয়ই বিদ্যমান রয়েছে তা নিশ্চিত করুন। যদি তাদের উপস্থিত না থাকে তবে তাদের সূচকের সমান মান সহ তাদের তৈরি করুন।
  3. আর ও সর্বাধিক উপাদানগুলি অদলবদল করুন
  4. উপাদান সর্বাধিক এবং হ্রাস সর্বাধিক 1 দ্বারা ফেরান (যদি সর্বাধিক নেতিবাচক হয় তবে আপনি সম্পন্ন করেছেন)।
  5. পদক্ষেপ 1 এ ফিরে যান।

একটি প্রাথমিক অ্যারে ব্যবহারের তুলনায় পার্থক্য কেবলমাত্র উপাদানগুলির সূচনা স্থগিত / এড়িয়ে যাওয়া - তবে এটি একই পিআরএনজি থেকে সঠিক একই সংখ্যা উত্পন্ন করবে।


1

আরেকটি সার্থকতা:

আপনি পতাকাগুলির একটি অ্যারে ব্যবহার করতে পারেন। এটি ইতিমধ্যে নির্বাচিত হয়ে গেলে পরেরটি নিন।

তবে, 1000 কলের পরে সাবধান থাকুন, ফাংশনটি কখনই শেষ হবে না তাই আপনাকে অবশ্যই একটি সুরক্ষার ব্যবস্থা করতে হবে।


এটি হ'ল হে (কে) 2), এখন পর্যন্ত নির্বাচিত মানগুলির সংখ্যার সাথে আনুপাতিক পরিমাণে আরও কয়েকটি পদক্ষেপের সাথে কী।
ivan_pozdeev

1

এখানে কয়েকটি নমুনা সিওবিওএল কোড রয়েছে যার সাথে আপনি প্রায় খেলতে পারেন।
আমি আপনাকে RANDGEN.exe ফাইল পাঠাতে পারি যাতে আপনি এটি খেলতে চান কিনা তা দেখার জন্য আপনি এটি খেলতে পারেন।

   IDENTIFICATION DIVISION.
   PROGRAM-ID.  RANDGEN as "ConsoleApplication2.RANDGEN".
   AUTHOR.  Myron D Denson.
   DATE-COMPILED.
  * ************************************************************** 
  *  SUBROUTINE TO GENERATE RANDOM NUMBERS THAT ARE GREATER THAN
  *    ZERO AND LESS OR EQUAL TO THE RANDOM NUMBERS NEEDED WITH NO
  *    DUPLICATIONS.  (CALL "RANDGEN" USING RANDGEN-AREA.)
  *     
  *  CALLING PROGRAM MUST HAVE A COMPARABLE LINKAGE SECTION
  *    AND SET 3 VARIABLES PRIOR TO THE FIRST CALL IN RANDGEN-AREA     
  *
  *    FORMULA CYCLES THROUGH EVERY NUMBER OF 2X2 ONLY ONCE. 
  *    RANDOM-NUMBERS FROM 1 TO RANDOM-NUMBERS-NEEDED ARE CREATED 
  *    AND PASSED BACK TO YOU.
  *
  *  RULES TO USE RANDGEN:
  *
  *    RANDOM-NUMBERS-NEEDED > ZERO 
  *     
  *    COUNT-OF-ACCESSES MUST = ZERO FIRST TIME CALLED.
  *         
  *    RANDOM-NUMBER = ZERO, WILL BUILD A SEED FOR YOU
  *    WHEN COUNT-OF-ACCESSES IS ALSO = 0 
  *     
  *    RANDOM-NUMBER NOT = ZERO, WILL BE NEXT SEED FOR RANDGEN
  *    (RANDOM-NUMBER MUST BE <= RANDOM-NUMBERS-NEEDED)       
  *     
  *    YOU CAN PASS RANDGEN YOUR OWN RANDOM-NUMBER SEED
  *     THE FIRST TIME YOU USE RANDGEN.
  *     
  *    BY PLACING A NUMBER IN RANDOM-NUMBER FIELD
  *      THAT FOLLOWES THESE SIMPLE RULES:
  *        IF COUNT-OF-ACCESSES = ZERO AND 
  *        RANDOM-NUMBER > ZERO AND 
  *        RANDOM-NUMBER <= RANDOM-NUMBERS-NEEDED
  *       
  *    YOU CAN LET RANDGEN BUILD A SEED FOR YOU
  *     
  *      THAT FOLLOWES THESE SIMPLE RULES:
  *        IF COUNT-OF-ACCESSES = ZERO AND 
  *        RANDOM-NUMBER = ZERO AND 
  *        RANDOM-NUMBER-NEEDED > ZERO  
  *         
  *     TO INSURING A DIFFERENT PATTERN OF RANDOM NUMBERS
  *        A LOW-RANGE AND HIGH-RANGE IS USED TO BUILD
  *        RANDOM NUMBERS.
  *        COMPUTE LOW-RANGE =
  *             ((SECONDS * HOURS * MINUTES * MS) / 3).         
  *        A HIGH-RANGE = RANDOM-NUMBERS-NEEDED + LOW-RANGE
  *        AFTER RANDOM-NUMBER-BUILT IS CREATED 
  *        AND IS BETWEEN LOW AND HIGH RANGE
  *        RANDUM-NUMBER = RANDOM-NUMBER-BUILT - LOW-RANGE
  *               
  * **************************************************************         
   ENVIRONMENT DIVISION.
   INPUT-OUTPUT SECTION.
   FILE-CONTROL.
   DATA DIVISION.
   FILE SECTION.
   WORKING-STORAGE SECTION.
   01  WORK-AREA.
       05  X2-POWER                     PIC 9      VALUE 2. 
       05  2X2                          PIC 9(12)  VALUE 2 COMP-3.
       05  RANDOM-NUMBER-BUILT          PIC 9(12)  COMP.
       05  FIRST-PART                   PIC 9(12)  COMP.
       05  WORKING-NUMBER               PIC 9(12)  COMP.
       05  LOW-RANGE                    PIC 9(12)  VALUE ZERO.
       05  HIGH-RANGE                   PIC 9(12)  VALUE ZERO.
       05  YOU-PROVIDE-SEED             PIC X      VALUE SPACE.
       05  RUN-AGAIN                    PIC X      VALUE SPACE.
       05  PAUSE-FOR-A-SECOND           PIC X      VALUE SPACE.   
   01  SEED-TIME.
       05  HOURS                        PIC 99.
       05  MINUTES                      PIC 99.
       05  SECONDS                      PIC 99.
       05  MS                           PIC 99. 
  *
  * LINKAGE SECTION.
  *  Not used during testing  
   01  RANDGEN-AREA.
       05  COUNT-OF-ACCESSES            PIC 9(12) VALUE ZERO.
       05  RANDOM-NUMBERS-NEEDED        PIC 9(12) VALUE ZERO.
       05  RANDOM-NUMBER                PIC 9(12) VALUE ZERO.
       05  RANDOM-MSG                   PIC X(60) VALUE SPACE.
  *    
  * PROCEDURE DIVISION USING RANDGEN-AREA.
  * Not used during testing 
  *  
   PROCEDURE DIVISION.
   100-RANDGEN-EDIT-HOUSEKEEPING.
       MOVE SPACE TO RANDOM-MSG. 
       IF RANDOM-NUMBERS-NEEDED = ZERO
         DISPLAY 'RANDOM-NUMBERS-NEEDED ' NO ADVANCING
         ACCEPT RANDOM-NUMBERS-NEEDED.
       IF RANDOM-NUMBERS-NEEDED NOT NUMERIC 
         MOVE 'RANDOM-NUMBERS-NEEDED NOT NUMERIC' TO RANDOM-MSG
           GO TO 900-EXIT-RANDGEN.
       IF RANDOM-NUMBERS-NEEDED = ZERO
         MOVE 'RANDOM-NUMBERS-NEEDED = ZERO' TO RANDOM-MSG
           GO TO 900-EXIT-RANDGEN.
       IF COUNT-OF-ACCESSES NOT NUMERIC
         MOVE 'COUNT-OF-ACCESSES NOT NUMERIC' TO RANDOM-MSG
           GO TO 900-EXIT-RANDGEN.
       IF COUNT-OF-ACCESSES GREATER THAN RANDOM-NUMBERS-NEEDED
         MOVE 'COUNT-OF-ACCESSES > THAT RANDOM-NUMBERS-NEEDED'
           TO RANDOM-MSG
           GO TO 900-EXIT-RANDGEN.
       IF YOU-PROVIDE-SEED = SPACE AND RANDOM-NUMBER = ZERO
         DISPLAY 'DO YOU WANT TO PROVIDE SEED  Y OR N: '
           NO ADVANCING
           ACCEPT YOU-PROVIDE-SEED.  
       IF RANDOM-NUMBER = ZERO AND
          (YOU-PROVIDE-SEED = 'Y' OR 'y')
         DISPLAY 'ENTER SEED ' NO ADVANCING
         ACCEPT RANDOM-NUMBER. 
       IF RANDOM-NUMBER NOT NUMERIC
         MOVE 'RANDOM-NUMBER NOT NUMERIC' TO RANDOM-MSG
         GO TO 900-EXIT-RANDGEN.
   200-RANDGEN-DATA-HOUSEKEEPING.      
       MOVE FUNCTION CURRENT-DATE (9:8) TO SEED-TIME.
       IF COUNT-OF-ACCESSES = ZERO
         COMPUTE LOW-RANGE =
                ((SECONDS * HOURS * MINUTES * MS) / 3).
       COMPUTE RANDOM-NUMBER-BUILT = RANDOM-NUMBER + LOW-RANGE.  
       COMPUTE HIGH-RANGE = RANDOM-NUMBERS-NEEDED + LOW-RANGE.
       MOVE X2-POWER TO 2X2.             
   300-SET-2X2-DIVISOR.
       IF 2X2 < (HIGH-RANGE + 1) 
          COMPUTE 2X2 = 2X2 * X2-POWER
           GO TO 300-SET-2X2-DIVISOR.    
  * *********************************************************         
  *  IF FIRST TIME THROUGH AND YOU WANT TO BUILD A SEED.    *
  * ********************************************************* 
       IF COUNT-OF-ACCESSES = ZERO AND RANDOM-NUMBER = ZERO
          COMPUTE RANDOM-NUMBER-BUILT =
                ((SECONDS * HOURS * MINUTES * MS) + HIGH-RANGE).
       IF COUNT-OF-ACCESSES = ZERO        
         DISPLAY 'SEED TIME ' SEED-TIME 
               ' RANDOM-NUMBER-BUILT ' RANDOM-NUMBER-BUILT 
               ' LOW-RANGE  ' LOW-RANGE.          
  * *********************************************     
  *    END OF BUILDING A SEED IF YOU WANTED TO  * 
  * *********************************************               
  * ***************************************************
  * THIS PROCESS IS WHERE THE RANDOM-NUMBER IS BUILT  *  
  * ***************************************************   
   400-RANDGEN-FORMULA.
       COMPUTE FIRST-PART = (5 * RANDOM-NUMBER-BUILT) + 7.
       DIVIDE FIRST-PART BY 2X2 GIVING WORKING-NUMBER 
         REMAINDER RANDOM-NUMBER-BUILT. 
       IF RANDOM-NUMBER-BUILT > LOW-RANGE AND
          RANDOM-NUMBER-BUILT < (HIGH-RANGE + 1)
         GO TO 600-RANDGEN-CLEANUP.
       GO TO 400-RANDGEN-FORMULA.
  * *********************************************     
  *    GOOD RANDOM NUMBER HAS BEEN BUILT        *               
  * *********************************************
   600-RANDGEN-CLEANUP.
       ADD 1 TO COUNT-OF-ACCESSES.
       COMPUTE RANDOM-NUMBER = 
            RANDOM-NUMBER-BUILT - LOW-RANGE. 
  * *******************************************************
  * THE NEXT 3 LINE OF CODE ARE FOR TESTING  ON CONSOLE   *  
  * *******************************************************
       DISPLAY RANDOM-NUMBER.
       IF COUNT-OF-ACCESSES < RANDOM-NUMBERS-NEEDED
        GO TO 100-RANDGEN-EDIT-HOUSEKEEPING.     
   900-EXIT-RANDGEN.
       IF RANDOM-MSG NOT = SPACE
        DISPLAY 'RANDOM-MSG: ' RANDOM-MSG.
        MOVE ZERO TO COUNT-OF-ACCESSES RANDOM-NUMBERS-NEEDED RANDOM-NUMBER. 
        MOVE SPACE TO YOU-PROVIDE-SEED RUN-AGAIN.
       DISPLAY 'RUN AGAIN Y OR N '
         NO ADVANCING.
       ACCEPT RUN-AGAIN.
       IF (RUN-AGAIN = 'Y' OR 'y')
         GO TO 100-RANDGEN-EDIT-HOUSEKEEPING.
       ACCEPT PAUSE-FOR-A-SECOND.
       GOBACK.

1
এটি আসলে ওপিগুলির চাহিদা পূরণ করতে পারে কিনা আমার কোনও ধারণা নেই, তবে একটি সিওবিওএল অবদানের জন্য প্রপস!
ম্যাক

1

এখানে বেশিরভাগ উত্তর গ্যারান্টি দিতে ব্যর্থ হয় যে তারা একই সংখ্যার দুইবার ফেরত দেবে না। এখানে একটি সঠিক সমাধান:

int nrrand(void) {
  static int s = 1;
  static int start = -1;
  do {
    s = (s * 1103515245 + 12345) & 1023;
  } while (s >= 1001);
  if (start < 0) start = s;
  else if (s == start) abort();

  return s;
}

আমি নিশ্চিত নই যে সীমাবদ্ধতাটি সুনির্দিষ্টভাবে নির্দিষ্ট রয়েছে। একটি ধরে নেয় যে 1000 অন্যান্য আউটপুট পরে কোনও মান পুনরাবৃত্তি করার অনুমতি দেওয়া হয় তবে এগুলি দু'টি 1000 এর সেটগুলির শেষে এবং প্রারম্ভিকভাবে উপস্থিত হওয়া অবধি 0 এর সাথে সাথে অনুসরণ করতে দেয় verse বিপরীতভাবে, যখন এটির একটি দূরত্ব রাখা সম্ভব হয় পুনরাবৃত্তির মধ্যে 1000 অন্যান্য মান, এমনটি করার ফলে এমন পরিস্থিতি বাধ্য হয় যেখানে ক্রমটি প্রতি বারের মতো ঠিক একই ভাবে নিজেকে পুনরায় প্রতিস্থাপন করে কারণ এই সীমাটির বাইরে ঘটে যাওয়া অন্য কোনও মান নেই।

এখানে এমন একটি পদ্ধতি যা মানটি পুনরাবৃত্তি করার আগে সর্বদা কমপক্ষে 500 টি অন্যান্য মানের গ্যারান্টি দেয়:

int nrrand(void) {
  static int h[1001];
  static int n = -1;

  if (n < 0) {
    int s = 1;
    for (int i = 0; i < 1001; i++) {
      do {
        s = (s * 1103515245 + 12345) & 1023;
      } while (s >= 1001);
      /* If we used `i` rather than `s` then our early results would be poorly distributed. */
      h[i] = s;
    }
    n = 0;
  }

  int i = rand(500);
  if (i != 0) {
      i = (n + i) % 1001;
      int t = h[i];
      h[i] = h[n];
      h[n] = t;
  }
  i = h[n];
  n = (n + 1) % 1001;

  return i;
}

এটি স্ট্যাকওভারফ্লো.com / a / 196164 / 648265 এর মতো একটি এলসিজি, সিকোয়েন্সগুলির জন্য নন-এলোমেলো পাশাপাশি অন্যান্য সম্পর্কিত কিঙ্কস ঠিক একই।
ivan_pozdeev

@ আইভান_পোজদেদেভ খনিটি এলসিজির চেয়ে ভাল কারণ এটি নিশ্চিত করে যে এটি 1001 তম কলটিতে একটি সদৃশ ফেরত দেবে না।
sh1

1

যখন এন 1000 এর চেয়ে বেশি হয় এবং আপনার কে র্যান্ডম নমুনা আঁকার দরকার আপনি এখন পর্যন্ত নমুনা ধারণ করে এমন একটি সেট ব্যবহার করতে পারেন। প্রতিটি অঙ্কনের জন্য আপনি প্রত্যাখ্যানের নমুনা ব্যবহার করেন যা একটি "প্রায়" ও (1) অপারেশন হবে, সুতরাং মোট চলমান সময় ও (এন) স্টোরেজ সহ প্রায় ও (কে) হয়।

এই অ্যালগরিদম সংঘর্ষে চলে যখন কে "কাছাকাছি" এন এর অর্থ হল চলমান সময় ও (কে) এর চেয়ে অনেক খারাপ হবে। একটি সাধারণ ফিক্স হ'ল যুক্তিটি বিপরীত করা যাতে কে> এন / 2 এর জন্য, আপনি যে সমস্ত নমুনা এখনও আঁকেননি তার একটি রেকর্ড রাখেন। প্রতিটি অঙ্কন প্রত্যাখ্যান সেট থেকে একটি নমুনা সরিয়ে দেয়।

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


বলছি, প্লিজ! ফিশার-ইয়েটস পদ্ধতিটি নষ্ট হয়ে গেছে। আপনি সম্ভাব্যতা 1 / N এর সাথে প্রথমটি এবং দ্বিতীয়টি সম্ভাব্যতা 1 / (এন -1) দিয়ে নির্বাচন করুন! = 1 / এন। এটি একটি পক্ষপাতদুষ্ট নমুনা পদ্ধতি! পক্ষপাতদুটি সমাধান করার জন্য আপনার কাছে সত্যই ভিটারের অ্যালগরিদম দরকার।
ইমানুয়েল ল্যান্ডহোম

0

ফিশার ইয়েটস

for i from n−1 downto 1 do
     j ← random integer such that 0 ≤ j ≤ i
     exchange a[j] and a[i]

এটি আসলে ও (এন -1) কারণ আপনার শেষ দুটিটির জন্য কেবল একটি অদলবদল প্রয়োজন
এটি সি #

public static List<int> FisherYates(int n)
{
    List<int> list = new List<int>(Enumerable.Range(0, n));
    Random rand = new Random();
    int swap;
    int temp;
    for (int i = n - 1; i > 0; i--)
    {
        swap = rand.Next(i + 1);  //.net rand is not inclusive
        if(swap != i)  // it can stay in place - if you force a move it is not a uniform shuffle
        {
            temp = list[i];
            list[i] = list[swap];
            list[swap] = temp;
        }
    }
    return list;
}

ইতিমধ্যে এটির একটি উত্তর রয়েছে তবে এটি যথেষ্ট দীর্ঘ বায়ুযুক্ত এবং আপনি 1 (0 নয়) এ থামতে পারবেন তা বুঝতে পারে না
পাপারাজ্জো

0

দয়া করে আমার উত্তরটি https://stackoverflow.com/a/46807110/8794687 এ দেখুন

এটা তোলে সরলতম আলগোরিদিম আছে গড় সময় জটিলতা অন্যতম হে ( গুলি লগ গুলি ), নমুনা আকার বাচক। হ্যাশ টেবিল অ্যালগরিদমগুলির কয়েকটি লিঙ্ক রয়েছে যাদের জটিলতা ( গুলি ) বলে দাবি করা হচ্ছে ।


-1

কেউ পোস্ট করেছেন "এক্সেলের মধ্যে এলোমেলো সংখ্যা তৈরি করা"। আমি এই আদর্শ ব্যবহার করছি। স্ট্রেন্ড ইন্ডেক্স এবং স্ট্রিংরান 2 অংশ দিয়ে একটি কাঠামো তৈরি করুন; 10 এলোমেলো সংখ্যার জন্য 10 স্ট্রাকচারের একটি অ্যারে তৈরি করুন। 0 থেকে 9 এবং str.ran থেকে বিভিন্ন এলোমেলো সংখ্যায় str.index সেট করুন।

for(i=0;i<10; ++i) {
      arr[i].index = i;
      arr[i].ran   = rand();
}

অ্যারে মানগুলিতে অ্যারে বাছাই করুন [i] .ran। Str.index এখন এলোমেলো ক্রমে। নীচে সি কোড রয়েছে:

#include <stdio.h>
#include <stdlib.h>

struct RanStr { int index; int ran;};
struct RanStr arr[10];

int sort_function(const void *a, const void *b);

int main(int argc, char *argv[])
{
   int cnt, i;

   //seed(125);

   for(i=0;i<10; ++i)
   {
      arr[i].ran   = rand();
      arr[i].index = i;
      printf("arr[%d] Initial Order=%2d, random=%d\n", i, arr[i].index, arr[i].ran);
   }

   qsort( (void *)arr, 10, sizeof(arr[0]), sort_function);
   printf("\n===================\n");
   for(i=0;i<10; ++i)
   {
      printf("arr[%d] Random  Order=%2d, random=%d\n", i, arr[i].index, arr[i].ran);
   }

   return 0;
}

int sort_function(const void *a, const void *b)
{
   struct RanStr *a1, *b1;

   a1=(struct RanStr *) a;
   b1=(struct RanStr *) b;

   return( a1->ran - b1->ran );
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.