ghergedan adlı üyeden alıntı: mesajı görüntüle
Muhtemelen tam olarak çalışıyor olması lazım. Biraz sinirimi bozdu ama keyifliydi Kolay gelsin.

// dağıtılacak sayı
$num = 10000;

$array = [

    ['sayi_miktar' => 2500, 'sayi_oran' => 13],
    ['sayi_miktar' => 4000, 'sayi_oran' => 13],
    ['sayi_miktar' => 3500, 'sayi_oran' => 15],
    ['sayi_miktar' => 1000, 'sayi_oran' => 14],
    ['sayi_miktar' => 2500, 'sayi_oran' => 13],
];

usort($array, function($a, $b){
    if($a['sayi_oran'] == $b['sayi_oran'])
        return $a['sayi_miktar'] < $b['sayi_miktar'];
    return $a['sayi_oran'] < $b['sayi_oran'];
});

$array = array_map(function($i) use($array){
    $f = array_filter($array, function($a) use($i){
        return $a['sayi_miktar'] == $i['sayi_miktar'] && $a['sayi_oran'] == $i['sayi_oran'];
    });
    return count($f) > 1 ? array_merge($i, ['esit' => count($f), 'varsay' => $i['sayi_miktar']/count($f)]) : $i;
}, $array);

$log = [];
$end = false;

foreach ($array as $k => $a) {

    $prev = $num;

    if($end){
        $calc = $end;
    } else{
        if(isset($a['esit'])){
            if($num < $a['sayi_miktar']){
                $calc = $end = $num/$a['esit'];
            } else{
                $calc = $a['varsay'];
            }
        } else{
            $calc = $num < $a['sayi_miktar'] ? $num : $a['sayi_miktar'];
        }
    }

    $num -= $calc;

    if($calc <= 0 ||$num < 0) break;

    $log[] = [
        'adim' => $k+1,
        'oran' => $a['sayi_oran'],
        'miktar' => $a['sayi_miktar'],
        'islem' => $prev.'-'.$calc,
        'cikan' => $calc,
        'kalan' => $num
    ];
}

print_r($log);
Array
(
    [0] => Array
    (
        [adim] => 1
        [oran] => 15
        [miktar] => 3500
        [islem] => 10000-3500
        [cikan] => 3500
        [kalan] => 6500
    )
    [1] => Array
    (
        [adim] => 2
        [oran] => 14
        [miktar] => 1000
        [islem] => 6500-1000
        [cikan] => 1000
        [kalan] => 5500
    )
    [2] => Array
    (
        [adim] => 3
        [oran] => 13
        [miktar] => 4000
        [islem] => 5500-4000
        [cikan] => 4000
        [kalan] => 1500
    )
    [3] => Array
    (
        [adim] => 4
        [oran] => 13
        [miktar] => 2500
        [islem] => 1500-750
        [cikan] => 750
        [kalan] => 750
    )
    [4] => Array
    (
        [adim] => 5
        [oran] => 13
        [miktar] => 2500
        [islem] => 750-750
        [cikan] => 750
        [kalan] => 0
    )
)
Çok teşekkürler baya işime yaradı.
Elinize sağlık.

Test ederken bir sıkıntı fark ettim.
// dağıtılacak sayı
$num = 3500;

$array = [
 
    ['sayi_miktar' => 2500, 'sayi_oran' => 15],
    ['sayi_miktar' => 1000, 'sayi_oran' => 13],
    ['sayi_miktar' => 1000, 'sayi_oran' => 13],
  
];
böyle bi veri girişi yaptığımda, dağıtılacak sayının tam 0 olması gerekiyordu.
oran 15 olandan -2500; 13 olanlardan ise -500 -500 alıp 0 olması lazım. Ama sonuç böyle çıkıyor.

Array ( [0] => Array ( [adim] => 1 [oran] => 15 [miktar] => 2500 [islem] => 3500-2500 [cikan] => 2500 [kalan] => 1000 ) [1] => Array ( [adim] => 2 [oran] => 13 [miktar] => 1000 [islem] => 1000-500 [cikan] => 500 [kalan] => 500 ) [2] => Array ( [adim] => 3 [oran] => 13 [miktar] => 1000 [islem] => 500-250 [cikan] => 250 [kalan] => 250 ) )