PHP:从数组中选择随机加权索引


PHP: Select random weighted index from Array

我知道这里有很多类似的问题,但我在代码中无法正确实现它。

我从数据库中提取id、ip、端口和权重,我希望能够从中选择一个权重非常低的随机ip(最近没有使用)。

这是一个结果集的子集。完整的名单在这里。

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没有被选中,其中大多数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;
}   

有人能提供更好的代码吗?

感谢

您可以按权重升序对数组进行排序,然后选择第一个元素,这将保证选择最不繁忙的服务器。

你的代码看起来很好,你也可以使用: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 ];