Bir dizi miktarda ekleyebilirsiniz bir dizi içindeki sayıları oluşturma

4 Cevap php

PHP oldukça yeniyim - Genel programlama. Böylece temelde gerçekleştirmek için gereken, değer n ekleyebilirsiniz numaraları x miktarı (rastgele oluşturulan) bir dizi oluşturmak olduğunu:

Ben 30 kadar eklemek 4 sayı oluşturmak zorunda, diyelim. Ben sadece ilk rastgele veri kümesi gerekir. 4 ve burada 30 kullanıcı tarafından ayarlanabilir olacaktır değişkenler vardır.

Gibi bir şey aslında

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

Ayrıca, hiçbir çiftleri izin ve tüm sayılar pozitif tamsayılar olması vardır.

Bir dizi içindeki değerleri gerekir. Ben onunla düşünsen olmuştur bazen, ancak, benim bilgi oldukça sınırlıdır. Herhangi bir yardım büyük takdir edilecektir.

4 Cevap

Öncelikle, bu gerçekten harika bir sorundur. Benim yaklaşım bile mükemmel numaralarını dağıtmak değil neredeyse eminim, ama burada başka yaklaşımlar biraz daha iyi olmalı.

Ben düşük sayıda dizi oluşturmak (ve sonunda onları shuffle) karar verdi. Bu beni her zaman olacak verim geçerli sonuçlar sağlar rastgele bir dizi seçim yapmanızı sağlar. Sayılar her zaman arttırmak olmalı beri, geçerli bir çözüm hala (bulunmasını sağlar mümkün olan en yüksek sayıda çözülmüş yani, ilk sayı 7 olmak tutuklanmıştı eğer n = 4 ve max = 31, o olmaz ise ) 4 sayıların toplamı 31 eşit olacağını 7 gibi daha büyük numaralarını almak mümkün olacak.

$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 );

EDIT: Eğer kalan zorlayarak maksimum değere yakın rasgele bir değer alacak iyi bir şans var çünkü büyük değerleri için $n sen, dizinin sonuna doğru gruplandırılmış değerler bir sürü ile bitireceğiz birbirine çok yakın olması. Olası bir düzeltme ağırlıklı rand var, ama bu beni aşar.

Ben doğru anladım mı emin değilim, ama bu deneyin:

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

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

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

sorry i missed 'no duplicates' too
-so need to tack on a 'deduplicator' ...i put it in the other question

Sabit bir toplamı ile rasgele sayılar bir dizi oluşturmak için:

  • rasgele sayılar bir dizi yapmak (zerreliğini gizlemek için büyük pratik büyüklük ...)
  • bunların toplamını hesaplamak
  • desiredsum / sum tarafından serisinin her çarpmak

(Basicaly yeni boyutuna rastgele bir dizi ölçekli)

Ardından ayarlamak için yuvarlama hatası var:

  • recalculate sum and its difference from desired sum
  • add the sumdiff to a random element in series if it doesnt result in a negative, if it does loop to another random element until fine.
  • to be ultratight instead add or subtract 1 bit to random elements until sumdiff=0

Kaynak randoms büyüklüğü sonucunda zerreliğini neden çok küçük ise bu gibi yapıyor kaynaklanan bazı non-rasgelelik değildir.

Ben php yok, ama burada bir çekim -

$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; }
  }

Bu size daha fazla yardımcı olacağını umuyoruz ....

Approch-1

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

Approch-2

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