2011-03-19 14 views
5

में एक अंतराल में अद्वितीय यादृच्छिक संख्याओं की सूची मुझे आपको परेशान करने के लिए खेद है, मुझे पता है कि this question को बहुत कुछ पूछा गया है लेकिन कभी भी एडा के साथ नहीं ... मैं सोच रहा था कि अगर एडा मानक लाइब्रेरी में कोई तरीका था ओ (एन) में अद्वितीय यादृच्छिक संख्याओं की एक सूची उत्पन्न करें (आप कभी भी एक ही संख्या में दो बार नहीं चुनते) एडा में Knuth-Fisher-Yates एल्गोरिदम का एक कार्यान्वयन है?एडा

+2

मैं पहले से ही यह है कि किसी भी पुस्तकालय के बारे में पता नहीं कर रहा हूँ, लेकिन यह है कि कश्मीर एफ वाई एल्गोरिथ्म बहुत लागू करने के लिए सरल लग रहा है। –

उत्तर

5

Fisher–Yates शफल here को लागू करने की चर्चा है। मूल रूप से, आपको प्रत्येक पुनरावृत्ति में Discrete_Random की एक अलग श्रृंखला की आवश्यकता है, जैसा कि here दिखाया गया है; Float_Random एक विकल्प है, जैसा कि A.5.2(50), Note 16 में उल्लिखित है। यदि पूर्वाग्रह महत्वपूर्ण नहीं है, तो यह example पर्याप्त हो सकता है।

किसी भी मामले में, फेरबदल हे (एन), लेकिन का चयन हो सकता है हे (1)

परिशिष्ट: की जटिलता सेट implementation पर निर्भर करती है। उदाहरण के लिए, Containers.Hashed_Sets, A.18.8(88/2) और Containers.Ordered_Sets, A.18.9(116/2)

+0

संख्या ओ (एन) भी लेनदेन/उत्पन्न नहीं कर रहा है? सभी को यह जांचने की आवश्यकता है कि संख्या अद्वितीय है या नहीं? (एक सरणी पर दोहराया रैखिक खोज) – NWS

+0

@NWS: अच्छा बिंदु। मैंने _dealing_ लापरवाही शब्द का इस्तेमाल किया; मेरा मतलब _selecting_ था। IIUC, विशिष्टता कार्यान्वयन के आधार पर जटिलता के साथ प्रारंभिक सेट _creating_ के साथ संयोग है। – trashgod

+0

प्रश्न पर वापस आना, अगर हम एक क्रमबद्ध सूची उत्पन्न करते हैं और डालते हैं, तो _Before_ हम संख्याओं को छोटा कर सकते हैं थोड़ा कम हो सकता है :)। – NWS

2

यह देखते हुए कि आप चाहते हैं: 0 से 1000 और ख को क) रैंडम संख्या) संख्या लिंक आपके द्वारा दी गई के अनुसार दोहराने के लिए नहीं कर रहे हैं, तो आप इस बल्कि आसानी से कर सकता है।

बस मानों की सीमा के साथ एक सरणी भरें और यादृच्छिक रूप से चुने गए तत्वों पर कुछ स्वैप करें; यह गारंटी देता है कि दोनों आवश्यकताओं को बरकरार रखा गया है।

+0

+1 यह सीधा दृष्टिकोण है, लेकिन "स्वैप की कुछ संख्या" का चयन पूर्वाग्रह का स्रोत हो सकता है। – trashgod

+0

यह सच है। हालांकि आप अपने एरे की रेंज (शायद एमओडी का उपयोग करके) के बराबर एक चक्र/रेंज के साथ एक आरएनजी का उपयोग कर थोड़ा सा कम करने में सक्षम हो सकते हैं और सभी तत्वों के लिए 'वर्तमान' तत्व के साथ उस इंडेक्स को स्वैप कर सकते हैं। तब मुख्य बात यह है कि पूर्वाग्रह से आएगा आरएनजी स्वयं ही होगा। – Shark8

+0

[उदाहरण उद्धृत] में (http://home.roadrunner.com/~jbmatthews/war.html) [पूर्वाग्रह] (http://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle# कार्यान्वयन_एरर्स) प्रत्येक पुनरावृत्ति पर वैध सरणी अनुक्रमणिका की पूरी श्रृंखला से "j 'चुनने पर निर्भर करता है।" अफसोस की बात है, यह पीआरएनजी से किसी भी पूर्वाग्रह से ऊपर है। – trashgod

1

मैंने इसे कोडिंग की स्वतंत्रता ली। आपको Ada.Numerics.Discrete_Random के साथ आवश्यकता होगी।

Generic 
     Low, High : Integer; 
    Package Initialization is 
     SubType Element is Integer Range Low..High; 
     Function Incrementor Return Element; 
     Type Element_Array is Array(Element) of Element; 

     Values : Element_Array; 
     Procedure Print; 
    End Initialization; 

    Package Body Initialization is 
     Count : Element := Element'Last; 

     Function Incrementor Return Element is 
     begin 
     Return Result : Element:= Count do 
      Null; 
      Count:= Element'Pred(Result); 
     Exception 
       When Constraint_Error => Count:= Element'Last; 
     End Return; 
     end Incrementor; 

     Procedure Swap(Index_1, Index_2 : In Integer) is 
     Temp : Constant Element:= Values(Integer(Index_1)); 
     begin 
     Values(Integer(Index_1)):= Values(Integer(Index_2)); 
     Values(Integer(Index_2)):= Temp; 
     end Swap; 

     Procedure Print is 
     begin 
     Put_Line("Length: " & Values'Length'Img); 
     Put("("); 
     For Index in Values'First..Integer'Pred(Values'Last) loop 
      Put(Values(Index)'Img & ','); 
     end loop; 
     Put(Values(Values'Last)'Img); 
     Put_Line(")"); 
     end Print; 


    Begin 
     Shuffle: 
     Declare 
     Package Random_Element is New 
     Ada.Numerics.Discrete_Random(Element); 
     Number : Random_Element.Generator; 
     Use Random_Element; 
     Begin 
     Values:= Element_Array'(Others => Incrementor); 
     Reset(Number); 
     For Index in Element'Range loop 
      Swap(Integer(Index), Integer(Random(Number))); 
     end loop; 
     End Shuffle; 
    End Initialization; 

और आप की तरह कुछ के साथ इसे बाहर का परीक्षण कर सकते हैं:

Test: 
    Declare 
     Package Q is new 
    Initialization(Low => 0, High => 1000); 
    Begin 
     Q.Print; 
    End Test; 
+0

Becasue यह "हर पुनरावृत्ति पर मान्य सरणी अनुक्रमणिका की पूरी श्रृंखला" से चुनता है, मुझे डर है कि यह वही है [पूर्वाग्रह] (http://en.wikipedia.org/wiki/ फिशर% E2% 80% 93Yates_shuffle # Implementation_errors)। – trashgod

+0

लेकिन एक अमान्य अनुक्रमणिका का चयन करना, एक शब्द में, गलत है। – Shark8

+0

चयन सीमा से बाहर नहीं है; यह सिर्फ कुछ शफल दूसरों की तुलना में अधिक संभावना बनाता है। आपको प्रत्येक पुनरावृत्ति में _remaining_ तत्वों से चयन करना होगा। यह [आलेख] (http://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle#Implementation_errors) अंत में मुझे यह देखने में मदद मिली कि कैसे। – trashgod

संबंधित मुद्दे