简体   繁体   English

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

[英]PHP: Select random weighted index from Array

I know there are many similar questions here, but I am having trouble implementing it correctly in my code. 我知道这里有很多类似的问题,但是我在代码中正确实现它时遇到了麻烦。

I am pulling in id, ip, port and weight from a database and from there I want to be able to select a random ip that has a very low weight (not used recently). 我从数据库中提取ID,IP,端口和权重,然后从那里我希望能够选择一个权重非常低的随机IP(最近未使用)。

Here is a subset of a result set. 这是结果集的子集。 The full list is 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

Going down the list I have many ip's that just aren't being selected and with a majority few being used over and over again. 在列表中,我有很多IP未被选中,而大多数IP却被一遍又一遍地使用。

Thanks to Yaniro, I came up with a better solution. 感谢Yaniro,我想出了一个更好的解决方案。

My code: 我的代码:

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

Can anyone offer a better piece of code? 谁能提供更好的代码?

Thanks 谢谢

You could sort the array by the weight in ascending order and then select the first element which will guarantee the selection of the least busy server. 您可以按权重升序对阵列进行排序,然后选择第一个元素,这将确保选择最不繁忙的服务器。

You code seems fine and you could also use: usort() or uasort() like so: 您的代码看起来不错,您也可以使用: usort()uasort()如下所示:

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

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

usort( $fruits, "cmp" );

If you want the comparison function to be a part of you class do something like this: 如果您希望比较函数成为类的一部分,请执行以下操作:

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

Or just loop through the array, find the lowest weight and return its index: 或者只是遍历数组,找到最小的权重并返回其索引:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM