Select a user according to set probability

给你一囗甜甜゛ 提交于 2019-12-12 03:03:16

问题


My database stores info about users, their groups, and relationships. One of the columns, fcount, in the users table tracks the number of relationships each user has had within their current group; it starts at 0, and I increment it when appropriate.
I need to write a script that selects all users in a given group and then randomly selects one of them with the probability of being selected being based on the number of relationships one has had; fewer relationships means a greater probability.

Currently, I accomplish this, minus the probability part, with this code:

$query = "SELECT uid FROM users WHERE groupid=:gid AND status='1'";
...
while ($row = $stmt->fetch(PDO::FETCH_NUM)) {
    $friends[] = $row[0];
}

foreach ($users as $value) {
    $key = array_search($value, $friends);
    unset($friends[$key]);
    shuffle($friends);
    $newrel = end($friends);
    $user = $value;
    $friends[] = $value;

    $query = "UPDATE users SET rel=:newrel WHERE uid=:uid";
    $query_params = array(':newrel' => $newrel, ':uid' => $user );
... }

I am thinking that the easiest way to adjust probability would be to edit the $friends array so that users show up more than once. So, users with an fcount of 0 will be repeated in the array 5 times, and users with an fcount of 1 are repeated 3 times. [Maybe this isn't the best way to handle it, but it makes sense to me and fits with the code I already have. You're free to offer a better scheme.]

What I haven't managed to figure out is how to take the array of users and multiply the entries of the users who ought to be multiplied.

SELECT uid, fcount FROM users WHERE groupid=:gid AND status='1';

returns an array reflective of this table:

+-----+--------+
| uid | fcount |
+-----+--------+
| 105 |      3 |
| 106 |      2 |
| 107 |      0 |
| 108 |      0 |
| 109 |      1 |
+-----+--------+

which then turns into an array like this:

array(15) { 
[0]=> string(3) "105" 
[1]=> string(3) "106" 
[2]=> string(3) "107" 
[3]=> string(3) "107" 
[4]=> string(3) "107" 
[5]=> string(3) "107" 
[6]=> string(3) "107" 
[7]=> string(3) "108" 
[8]=> string(3) "108" 
[9]=> string(3) "108" 
[10]=> string(3) "108" 
[11]=> string(3) "108"
[12]=> string(3) "109" 
[13]=> string(3) "109" 
[14]=> string(3) "109" 
}  

It seems to me that this could be accomplished with a foreach that pushes each userid n times into a new array according to if statements in the loop. I'll try to construct it, even though I'm likely to fail.


回答1:


$problist = array();
foreach ($row as $value) {
    if ($value['fcount'] == 0) {
        array_push($problist, $value['uid'], $value['uid'], $value['uid'], $value['uid'], $value['uid']);
    } elseif ($value['fcount'] == 1) {
        array_push($problist, $value['uid'], $value['uid'], $value['uid']);
    } elseif ($value['fcount'] >= 2) {
        $problist[] = $value['uid'];
    }
}



回答2:


Easiest way calculating a probability in a general occasion

$relations = 10;
$chance = rand(1,100);
if ($chance <= $relations) {
// success
}

In this case, the more the relations are, the bigger the probability comes, it's like if $relations = 99, you will have like 99% probability to hit this user with relations=99



来源:https://stackoverflow.com/questions/16082020/select-a-user-according-to-set-probability

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!