2012-03-01 65 views
0

我知道這裏有很多類似的問題,但是我在代碼中無法正確實現它。PHP:從數組中選擇隨機加權索引

我拉從身份證,IP,端口和重量從數據庫,並從那裏我想能夠選擇一個具有非常低的權重(最近沒有使用)的隨機IP。

這裏是結果集的子集。完整列表是here

id ip port weight tries 
174 127.0.0.1 3128 906 0 
101 127.0.0.1 8080 629 2 
123 127.0.0.1 3128 433 3 
226 127.0.0.1 3128 393 1 
82 127.0.0.1 8080 333 2 
252 127.0.0.1 8080 276 3 
253 127.0.0.1 3128 209 0 
240 127.0.0.1 3129 204 1 
249 127.0.0.1 3128 190 0 
261 127.0.0.1 8888 165 1 
120 127.0.0.1 3128 161 3 
188 127.0.0.1 8080 149 0 
265 127.0.0.1 8080 108 1 
275 127.0.0.1 8080 104 0 
63 127.0.0.1 8080 95 2 
196 127.0.0.1 8080 79 2 
248 127.0.0.1 8080 73 1 
223 127.0.0.1 8000 72 3 
88 127.0.0.1 3128 69 3 
422 127.0.0.1 8080 47 0 

下鄉名單我有,只是沒有被選中,並一遍又一遍地被使用幾大部分多個IP的。

感謝Yaniro,我想出了一個更好的解決方案。

我的代碼:

private function _weighted_random_simple($proxies) 
{ 
    foreach ($proxies as $proxy) { 
     $weight[] = $proxy['weight'];   
    } 

    array_multisort($weight, SORT_ASC, $proxies); 

    // Define the custom sort function 
    $proxie = array(
     'id' => $proxies[0]['id'], 
     'ip' => $proxies[0]['ip'], 
     'port' => $proxies[0]['port'], 
     'weight' => $proxies[0]['weight'], 
     'tries' => $proxies[0]['tries'] 
    ); 

    return $proxie; 
} 

任何人都可以提供一個更好的代碼?

感謝

+1

您如何按升序排序重量的數組並選擇第一個條目?這不能保證你總會選擇最不繁忙的服務器嗎? – Yaniro 2012-03-01 13:56:47

+0

你爲什麼要挑一個隨機的?你不能只使用體重最輕的那個? – 2012-03-01 14:01:50

+0

Yaniro和EmilVikström,是的,我想我可以做到這一點。但是如果我有500排重量爲1的東西呢?它會總是隨便挑一個嗎? – PaulM 2012-03-01 14:12:08

回答

0

您可以通過重量升序排列進行排序,然後選擇將確保最不繁忙的服務器的選擇的第一要素。

你的代碼看起來很好,你也可以使用:usort()uasort()像這樣:

function cmp($a, $b) 
{ 
    if ($a[ 'weight' ] == $b[ 'weight' ]) 
    { 
     return 0; 
    } 

    return ($a[ 'weight' ] < $b[ 'weight' ]) ? -1 : 1; 
} 

usort($fruits, "cmp"); 

如果你想比較函數是你的類的一部分做這樣的事情:

class YourClass 
{ 
    static function cmp($a, $b) 
    { 
     if ($a[ 'weight' ] == $b[ 'weight' ]) 
     { 
      return 0; 
     } 

     return ($a[ 'weight' ] < $b[ 'weight' ]) ? -1 : 1; 
    } 

    private function _weighted_random_simple($proxies) 
    { 
     usort($proxies, array("YourClass", "cmp")); 
     return $proxies[ 0 ]; 
    } 
} 

或者只是通過陣列循環,找到最低的重量並返回其索引:

$lowest = -1; 
$index = 0; 

for ($i = 0; $i < count($proxies); ++$i) 
{ 
    if ($proxies[ $i ][ 'weight' ] < $lowest || $lowest == -1) 
    { 
     $lowest = $proxies[ $i ][ 'weight' ]; 
     $index = $i; 
    } 
} 

return $proxies[ $index ];