2010-05-08 23 views
15

तक जोड़ती हैं मैं सामान्य रूप से PHP - प्रोग्रामिंग के लिए बिल्कुल नया हूं। तो बुनियादी तौर पर मैं क्या पूरा करने के लिए किया जाता है, एक (बेतरतीब ढंग से बनाई गई) संख्या के एक्स राशि की सरणी जिसका मूल्य के लिए n जोड़ बनाने की जरूरत है:एक सरणी के भीतर संख्याएं बनाएं जो सेट राशि

मान लें, मैं 4 संख्या है कि 30 को जोड़ बनाने के लिए मुझे बस पहले यादृच्छिक डेटासेट की आवश्यकता है। यहां 4 और 30 वेरिएबल्स हैं जो उपयोगकर्ता द्वारा सेट किए जाएंगे।

अनिवार्य रूप से की तरह

x = amount of numbers; 
n = sum of all x's combined; 

// create x random numbers which all add up to n; 

$row = array(5, 7, 10, 8) // these add up to 30 

इसके अलावा कुछ नहीं, कोई डुप्लिकेट अनुमति दी जाती है और सभी नंबरों को धनात्मक पूर्णांक होना है।

मुझे किसी सरणी के भीतर मानों की आवश्यकता है। मैं कभी-कभी इसके साथ गड़बड़ कर रहा हूं, हालांकि, मेरा ज्ञान काफी सीमित है। किसी भी प्रकार की सहायता सराहनीय होगी।

+0

डुप्लिकेट की अनुमति दी है? – Gumbo

+0

नहीं। क्षमा करें, मैं अपनी पोस्ट संपादित करूंगा। –

+3

* (संबंधित) * http://en.wikipedia.org/wiki/Partition_%28number_theory%29 – Gordon

उत्तर

7

एफ प्यास बंद, यह वास्तव में एक अच्छी समस्या है। मुझे पूरा यकीन है कि मेरा दृष्टिकोण संख्याओं को पूरी तरह से वितरित नहीं करता है, लेकिन यह यहां कुछ अन्य दृष्टिकोणों से बेहतर होना चाहिए।

मैंने सबसे कम संख्या से सरणी बनाने का अंत तय किया (और अंत में उन्हें घुमाएं)। यह मुझे हमेशा यादृच्छिक रेंज चुनने की अनुमति देता है जो उपज वैध परिणामों की अनुमति देगा। चूंकि संख्याओं को हमेशा बढ़ाना चाहिए, इसलिए मैंने उच्चतम संभावित संख्या के लिए हल किया है जो सुनिश्चित करता है कि एक वैध समाधान अभी भी मौजूद है (यानी, यदि n = 4 और अधिकतम = 31, यदि पहली संख्या 7 हो गई थी, तो यह नहीं होगा 7 से अधिक संख्याओं को चुनना संभव है कि 4 संख्याओं का योग 31 के बराबर होगा)।

$n = 4; 
$max = 31; 
$array = array(); 

$current_min = 1; 
while($n > 1) { 
    //solve for the highest possible number that would allow for $n many random numbers 
    $current_max = floor(($max/$n) - (($n-1)/2)); 
    if($current_max < $current_min) throw new Exception("Can't use combination"); 
    $new_rand = rand($current_min, $current_max); //get a new rand 
    $max -= $new_rand; //drop the max 
    $current_min = $new_rand + 1; //bump up the new min 
    $n--; //drop the n 
    $array[] = $new_rand; //add rand to array 
} 
$array[] = $max; //we know what the last element must be 
shuffle($array); 

संपादित करें: $n के बड़े मूल्यों के लिए आप सरणी के अंत में वर्गीकृत किया मूल्यों की एक बहुत कुछ के साथ खत्म हो जाएगा के बाद से वहाँ एक अच्छा मौका है कि आप अधिकतम मूल्य के लिए मजबूर कर के पास एक यादृच्छिक मूल्य प्राप्त होगा एक साथ बहुत करीब होने के लिए आराम करो। एक भारित रैंड होना एक संभावित फिक्स है, लेकिन यह मेरे बाहर है।

+0

धन्यवाद दोस्त :) मैंने अभी कुछ मामूली बदलाव किए हैं और यह एक आकर्षण की तरह काम करता है :) –

+0

मुझे लगता है कि आपको पता है कि यह पूरी तरह से यादृच्छिक श्रृंखला उत्पन्न नहीं करता है, अन्यथा अंत में शफल की आवश्यकता नहीं होगी;) वहां निश्चित रूप से यादृच्छिकता बहुत है, लेकिन पिछली रैंडों और योगों की प्रतिक्रिया में रैंड बनाने से प्रवृत्तियों को शुरू किया जा सकता है- वितरण में वृद्धि- जो कुछ परीक्षणों और अनुप्रयोगों में प्रकट हो सकती है। – strainer

+0

@ स्ट्रेनर जैसा कि मैंने "EDIT" में उल्लेख किया है जब $ n मान बड़ा हो जाता है, मान अंत के करीब गिरते प्रतीत होते हैं। यह शायद भारित रैंड द्वारा हल किया जा सकता है। क्लंपिंग समस्या के बिना हल करने के लिए यह एक बहुत ही मुश्किल मुद्दा है। –

0

मुझे यकीन है कि क्या मैं आप सही तरीके से समझा नहीं गया हूँ, लेकिन इस प्रयास करें:

$n = 4; 
$max = 30; 
$array = array(); 

do { 
    $random = mt_rand(0, $max); 

    if (!in_array($random, $array)) { 
     $array[] = $random; 
     $n--; 
    } 
} while (n > 0); 
+0

मुझे चार संख्याओं की आवश्यकता है जो आपके द्वारा उपयोग किए गए $ अधिकतम चर में जोड़ें। उदाहरण के जैसा मैंने ऊपर उपयोग किया है: सरणी (5, 7, 10, 8) // ये 30 तक अस्पष्ट साथी होने के लिए खेद है। –

+1

यह गारंटी नहीं देगा कि संख्याएं वास्तव में 30 तक बढ़ जाती हैं। आप अंतिम संख्या को गैर-यादृच्छिक बना सकते हैं ताकि वे सही राशि तक जोड़ सकें .. आखिरकार, वे सभी यादृच्छिक नहीं हो सकते हैं। यदि वह संख्या पहले से ही सरणी में है, तो आपको एक छोटी सी समस्या है :) – Thorarin

-2

आशा इस आप और अधिक मदद मिलेगी ....

approch-1

$aRandomarray = array(); 
for($i=0;$i<100;$i++) 
{ 
    $iRandomValue = mt_rand(1000, 999); 
    if (!in_array($iRandomValue , $aRandomarray)) { 
     $aRandomarray[$i] = $iRandomValue; 
    } 
} 

एप्रोच -2

$aRandomarray = array(); 
for($i=0;$i<100;$i++) 
{ 
    $iRandomValue = mt_rand(100, 999); 
    $sRandom .= $iRandomValue; 
} 
array_push($aRandomarray, $sRandom); 
+0

मुझे पूरा यकीन नहीं है कि यह एक विशिष्ट राशि को जोड़ने के लिए संख्याओं की संख्या कैसे बनाता है? –

0

खेद है कि मैं याद किया 'कोई डुप्लिकेट' भी
है, ताकि एक 'Deduplicator' पर हमले के लिए की जरूरत है ... मैं अन्य question

में रख एक निश्चित राशि के साथ यादृच्छिक संख्या की एक श्रृंखला बनाने के लिए:

  • यादृच्छिक संख्याओं की श्रृंखला बनाएं (ग्रैन्युलरिटी को छिपाने के लिए सबसे बड़ी व्यावहारिक परिमाण ...)
  • desiredsum/योग

(मूल रूप से अपने नए आकार के लिए एक यादृच्छिक श्रृंखला पैमाने पर करने के)

तो फिर वहाँ त्रुटि गोलाई है के लिए समायोजित करने के लिए से श्रृंखला में गुणा प्रत्येक अपने योग

  • गणना:

    • पुनर्गणना योग और वांछित राशि
    • से अपने अंतर एक को sumdiff जोड़ने श्रृंखला में यादृच्छिक तत्व यदि यह नकारात्मक में परिणाम नहीं देता है, तो यह ठीक होने तक यादृच्छिक तत्व को लूप करता है।
    • जोड़ सकते हैं या बजाय ultratight किए जाने की घटाना 1 यादृच्छिक तत्वों के लिए थोड़ा तक sumdiff = 0

    कुछ गैर अनियमितता इस तरह यह कर से उत्पन्न करता है, तो स्रोत randoms की भयावहता बहुत छोटा विवरण के स्तर को पैदा कर रहा है नतीजतन

    मैं php है न, लेकिन यहाँ एक शॉट है -

    $n = ;    //size of array 
    $targsum = ;  //target sum 
    $ceiling = 0x3fff; //biggish number for rands 
    $sizedrands = array(); 
    
    $firstsum=0; 
    $finsum=0; 
    
    //make rands, sum size 
    for($count=$n; $count>0; $count--) 
    { $arand=rand(0, $ceiling); 
        $sizedrands($count)=$arand; 
        $firstsum+=$arand; } 
    
    //resize, sum resize 
    for($count=$n; $count>0; $count--) 
    { $sizedrands($count)=($sizedrands($count)*$targsum)/$firstsum; 
        $finsum+=$sizedrands($count); 
        } 
    
    //redistribute parts of rounding error randomly until done 
    $roundup=$targsum-$finsum; 
    
    $rounder=1; if($roundup<0){ $rounder=-1; } 
    
    while($roundup!=0) 
    { $arand=rand(0, $n); 
        if(($rounder+$sizedrands($arand)) > 0) 
        { $sizedrands($arand)+=$rounder; 
        $roundup-=$rounder; } 
        } 
    
  • संबंधित मुद्दे