ঠিক এন সেট বিট সহ নম্বর উত্পন্ন করার জন্য পিআরএনজি


12

বাইনারি ডেটা উত্পন্ন করার জন্য আমি বর্তমানে কিছু কোড লিখছি। আমি নির্দিষ্টভাবে সেট বিটের একটি নির্দিষ্ট সংখ্যার সাথে 64৪-বিট নম্বর উত্পন্ন করতে চাই; আরও স্পষ্টভাবে, পদ্ধতিতে কিছু নেওয়া উচিত 0<n<64এবং সিউডো-এলোমেলো 64৪-বিট নম্বরটি ঠিক n বিট সেট করা উচিত 1এবং বাকী 0 তে সেট করা উচিত।

আমার বর্তমান পদ্ধতির মধ্যে এরকম কিছু জড়িত:

  1. সিউডোরানডম 64৪-বিট নম্বর উত্পন্ন করুন k
  2. বিট গণনা k , এ ফলাফলের সংরক্ষণকারী b
  3. যদি b=n , আউটপুট k ; অন্যথায় 1 এ যান।

এটি কাজ করে তবে এটি অনুপযুক্ত মনে হয়। এখানে কি এমন কোনও পিআরএনজি অ্যালগরিদম রয়েছে যা এর চেয়ে আরও মার্জিতভাবে n সেট বিট দিয়ে সংখ্যা তৈরি করতে পারে ?

উত্তর:


12

আপনার যা দরকার তা হল 0 এবং between এর মধ্যে একটি এলোমেলো সংখ্যা । সমস্যাটি তখন বিট প্যাটার্নে পরিণত করা into(64n)1

এটি এনুমারিটিভ কোডিং হিসাবে পরিচিত এবং এটি প্রাচীনতম মোতায়েন করা সংক্ষেপণ অ্যালগরিদমগুলির মধ্যে একটি। সম্ভবত সবচেয়ে সহজ অ্যালগরিদম থমাস কভার থেকে। এটি সাধারণ পর্যবেক্ষণের উপর ভিত্তি করে যে আপনার যদি এমন একটি শব্দ থাকে যা বিট দীর্ঘ হয়, যেখানে সেট বিটগুলি সর্বাধিক উল্লেখযোগ্য বিট ক্রমে হয়, তবে এই সম্পত্তিটির সাথে সমস্ত শব্দের এই শব্দের অবস্থান হল:এক্স কেএক্স 1nxkx1

1ik(xii)

সুতরাং, উদাহরণস্বরূপ, 7-বিট শব্দের জন্য:

আই(0001011)= ( 3

i(0000111)=(23)+(12)+(01)=0
আমি(0001101)= ( 3
i(0001011)=(33)+(12)+(01)=1
i(0001101)=(33)+(22)+(01)=2

... ইত্যাদি।

অর্ডিনাল থেকে বিট প্যাটার্নটি পেতে, আপনি প্রতিটি বিটকে ঘুরে ফিরে ডিকোড করুন। সি-জাতীয় ভাষায় এরকম কিছু:

uint64_t decode(uint64_t ones, uint64_t ordinal)
{
    uint64_t bits = 0;
    for (uint64_t bit = 63; ones > 0; --bit)
    {
        uint64_t nCk = choose(bit, ones);
        if (ordinal >= nCk)
        {
            ordinal -= nCk;
            bits |= 1 << bit;
            --ones;
        }
    }
    return bits;
}

নোট করুন যেহেতু আপনার কেবলমাত্র 64৪ অবধি দ্বিপদী সহগের প্রয়োজন, আপনি সেগুলি প্রতিরোধ করতে পারেন।


  • কভার, টি।, গণনার উত্স এনকোডিং । তথ্য তত্ত্ব সম্পর্কিত আইইইই লেনদেন, ভোল আইটি -১৯, নং 1, জানু 1973।

সুন্দর এবং মার্জিত! এনুমারেটিভ কোডিং এমন কিছুর মতো লাগে যা খুব দরকারী - এটিতে কি কোনও ভাল সংস্থান রয়েছে (পছন্দমত পাঠ্যপুস্তকের আকারে)?
কোজ রস

এটি কি অনুশীলনে আরও ভাল পারফরম্যান্স দেয়? (অবশ্যই এটি আরএনজির গতির উপর নির্ভর করে)) যদি না হয় তবে আরও জটিল কোড ব্যবহার করার কোনও মানে নেই।
গিলস'স'- দুষ্ট হওয়া বন্ধ করুন '

1
@ গাইলস আমি এটি কম্পিউটার বিজ্ঞানের প্রশ্ন হিসাবে ব্যাখ্যা করেছি, যেহেতু এটি CS.se. আমি কেবল উত্স কোডটি দিয়েছি কারণ আমার কাছে এটি আরআরআর অ্যারে বাস্তবায়ন থেকে প্রায় পড়ে আছে। (উদাহরণস্বরূপ, এর অর্থ কী তা বোঝার জন্য alexbowe.com/rrr দেখুন ))
ছদ্মনাম

1
@ গিলস আপনার প্রশ্নের অনুসরণ করতে, আমি আমার নিষ্পাপ পদ্ধতি এবং ফোরডে সিউডনাম দ্বারা সরবরাহিত উভয়ই কার্যকর করেছি। সরল পদ্ধতিটি এমনকি খুব সাধারণ জর্শিফ্ট পিআরএনজি ব্যবহার করার সময়, সংখ্যা অনুসারে 20 সেকেন্ডের ক্রম হিসাবে কিছু নিয়েছিল , যখন সিউডনামের পদ্ধতিটি প্রায় তাত্ক্ষণিক ছিল। আমি এর জন্য প্রাক্পম্পিউটেড বাইনোমিয়ালের টেবিল ব্যবহার করেছি।
কোজ রস

1
@ কোজরসস যদি আপনি এন বিট সংখ্যা উত্পন্ন করেন এবং কে বিটস সেট সহ সংখ্যাগুলি সন্ধান করেন তবে কে এন / ২ থেকে দূরে থাকলে এগুলি বেশ বিরল হবে; এটি এটি ব্যাখ্যা করবে।
gnasher729 20

3

ছদ্মনামের উত্তরের সাথে খুব মিল, অন্য উপায়ে প্রাপ্ত।

প্রাপ্তিসাধ্য সমাহারের মোট সংখ্যা দ্বারা বন্ধুত্বপরায়ণ নক্ষত্র এবং বার পদ্ধতি , তাই এটি হতে হবে । মোট 64৪-বিট সংখ্যা যা থেকে আপনি নিজের সংখ্যাটি নমুনা দেওয়ার চেষ্টা করছেন সেটি অবশ্যই এর চেয়ে অনেক বেশি হবে।c=(64n)

আপনার এখন যা দরকার তা হ'ল একটি ফাংশন যা আপনাকে সিউডোরেন্ডম সংখ্যা থেকে থেকে , সম্পর্কিত 64 বিট সংমিশ্রণে নিয়ে যেতে পারে।1 k1c

পাসকালের ত্রিভুজ আপনাকে এটিতে সহায়তা করতে পারে, কারণ প্রতিটি নোডের মান সেই নোড থেকে ত্রিভুজটির মূল পর্যন্ত সঠিক পথের সংখ্যা উপস্থাপন করে এবং সমস্ত পথ আপনি বাঁকানো স্ট্রিংগুলির মধ্যে একটির প্রতিনিধিত্ব করতে পারেন, যদি সমস্ত বাম বাঁক থাকে একটি দিয়ে লেবেলযুক্ত এবং দিয়ে প্রতিটি ডানদিকে ঘুরুন ।010

তাই দিন বিট নির্ধারণ করতে বাম সংখ্যা হতে, এবং ব্যবহার বামে বেশী সংখ্যা হতে।yxy

আমরা জানি যে , এবং আমরা সংখ্যার পরবর্তী বিটটি সঠিকভাবে নির্ধারণ করতে এটি ব্যবহার করতে পারি প্রতিটি পদক্ষেপে:(xy)=(x1y)+(x1y1)

whilex>0

ifx>y

ifk>(x1y):ss+"1",kk(x1y),yy1

else:ss+"0"

else:ss+"1",yy1

xx1


2

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

word randomKBits(int k) {
    word min = 0;
    word max = word(~word(0)); // all 1s
    int n = 0;
    while (n != k) {
        word x = randomWord();
        x = min | (x & max);
        n = popcount(x);
        if (n > k)
            max = x;
        else
            min = x;
    }
    return min;
}

আমি বিভিন্ন পদ্ধতির সাথে পারফরম্যান্স তুলনা করেছি এবং কে খুব ছোট হিসাবে পরিচিত না হলে এটি সাধারণত সবচেয়ে দ্রুত।


0

আপনি নিম্নলিখিতটি করতে পারেন:

1) থেকে মধ্যে এলোমেলো সংখ্যা, তৈরি করুন ।k164

2) ম থেকে সেট করুন ।k01

3) পদক্ষেপ 1 এবং 2 বার পুনরাবৃত্তি করুনn

A[] হয় সব বিট অ্যারে গুলি640

for(i=1 to n)
{
    k=ran(1,65-i) % random number between 1 and 65-i
    for(x=1;x<65;x++)
    {
        if(A[x]==0)k--;
        if(k==0)break;
    }
    A[x]=1;
}

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

@ বেরগি ইয়া লাইনটি ভুলে গেছেন ... এটি এখন যুক্ত করুন। এবং কে এর একাধিক সংঘর্ষ পরিচালনা করা হয়। দেখুন প্রথম সংখ্যাটি 1 এবং 64 এর মধ্যে, দ্বিতীয়টি 1 এবং "অবশিষ্ট" 63 এর মধ্যে নির্বাচিত হয়েছে So সুতরাং গণনা করার সময় এটি 1 টি এড়িয়ে যায় ... দেখুনলাইন। এবং এটি অভিন্ন বিতরণ। A[x]=1if(A[x]==0)k;
ব্যবহারকারী

আহ, আমি এখন দেখতে। গদ্য অ্যালগরিদম এড়িয়ে যাওয়ার কথা উল্লেখ করেনি।
বার্গি

@ অর্ঘ্যচক্রবর্তী আপনি কি সেখানে 1-ভিত্তিক সূচক ব্যবহার করছেন?
কোজ রস

কি হবে যদি সঙ্গে @KozRoss স্টার্ট (অবশ্যই সব শূণ্যসমূহ হবে) সুতরাং, চেক করবে এবং পেতে অর্থযা দেয় । সুতরাং, লুপের বাইরে সেট করে। হ্যাঁ এটি 1-ভিত্তিক সূচক। এটা 0 ভিত্তিক সব আপনাকে যা করতে হবে ভেতরের পরিবর্তন করতে অনুগ্রহ করে করতে[ 1 ] = = 0 টি আর ইউ কে - - ; কে = 0 [ 1 ] = 1 এফ আর ( x = 0 ; এক্স < 64 ; এক্স + + )i=1,k=1AA[1]==0truek;k=0A[1]=1for(x=0;x<64;x++)
ব্যবহারকারীর খোঁজ মেলেনি
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.