How do I go through the data of an array, to make a draw with odds proportions?

Asked

Viewed 436 times

1

Next guys, I was studying how I could create a small draw application that was simple and fair and at the same time has probabilities, in my researches I found several ways to make a random choice of data stored inside an array, using the Rand(), mt_rand() and array_rand() commands and even using the shuffle() function to help shuffling.

That’s where the question comes in, to make a normal draw where the data has the same chance (Probability) to be chosen these functions by itself is enough and works very well, however I would like to know how I could add the element "Chance or Probability" that a data stored within the array or in the Database can be chosen

I will try to give an example of what I would like to try to do:

1 - Example that has equal chances:

<?php
//Variável que armazena os dados do array
$escolher = array("Arroz", "Feijão", "Macarrão", "Pizza", "Hamburguer");

//Variável que irá armazenar o elemento escolhido aleatóriamente
$resultado = array_rand($escolher);

//Imprimindo o Resultado na tela
echo 'O Alimento escolhido foi: ' . $resultado; //(Arroz)
?>

2 - Example that adds amount of odds or probabilities of an element to be chosen:

<?php
/*
Variável que armazena os dados do array,
repetindo os dados de acordo com o numero de chances que cada um tem de ser escolhido sendo,
Arroz = 2, Feijão = 1, Macarrão = 4, Pizza = 3, Hamburguer = 4
*/
$escolher = array(
"Arroz", "Arroz",
"Feijão",
"Macarrão", "Macarrão", "Macarrão", "Macarrão",
"Pizza", "Pizza", "Pizza",
"Hamburguer", "Hamburguer", "Hamburguer", "Hamburguer"
);

//Variável que irá armazenar o elemento escolhido aleatóriamente
$resultado = array_rand($escolher);

//Imprimindo o Resultado na tela
echo 'O Alimento escolhido foi: ' . $resultado; //(Macarrão)
?>

Well, the two examples work by returning a random result, but in the case I don’t know if the repetition that occurs in example 2 is reliable, and I would like to make the second example in a way where I don’t need to keep repeating the same information several times within the array to increase or decrease the chances of it being chosen, I would like to do something where I could-inform the probabilities through numbers, and inform what is the chance that each element has, and thus be able to manipulate who has the highest priority to be chosen and who has the lowest priority.

I was taking a look at these articles here from Sopt, but I was more lost than blind in gunfire, perhaps due to my level of knowledge that is not very high, so I would like your help, I thank you now.

These are the links to the articles I quoted:

/questions/206164/sistema-de-sorteio

Drawing strings from a weight array

  • 2

    The problem is confusing because he talks about weights, but there’s nothing there that should have weights, these are isolated items. If the problem is not well defined the solution will never be right, first set it correctly.

  • The array with the same key? This will never work

  • Weight I say is like odds, or chances. In case one item has more chances than another item to be chosen.

  • 1

    I’m going to repeat what I said, nothing in your code indicates that you have what you’re saying, so it’s hard to give a proper solution, for example, if you had weights one being chosen over another the answer already given would be wrong, and it probably is and it didn’t help at all, so we should only answer when the question is clear.

  • Cool, I understand what you mean. I’ll try to rephrase the question.

2 answers

1

Good morning, I hope to help.

your example:

$tarefas = array(
    3 => 'Comer Pizza';
    1 => 'Comer Hamburguer'; 
    5 => 'Comer Arroz com Feijao';
    3 => 'Comer Macarrao';
    1 => 'Comer Pao com Mortadela';
);

$min = 1;  //Valor Minimo
$max = 13; //Máximo com base na soma das Chaves do array

$x = mt_rand($min, $max);
echo $tarefas[$x];

$x = mt_rand(1, 13); //Saída Ex: 5
echo $tarefas[5]; // Comer Arroz com Feijao

Make the changes below to help you, explained in the code:

<?php
    $tarefas = array(
        3 => 'Comer Pizza',
        1 => 'Comer Hamburguer', 
        5 => 'Comer Arroz com Feijao',
        3 => 'Comer Macarrao',
        1 => 'Comer Pao com Mortadela'
    );

    //1 - Organizar as chaves, com isto, não havendo mais repetidos e sim distintos.
    $tarefasN = array_values($tarefas);

    //2 - array_rand, escolhe já de forma aleatoria um ou mais indice no array
    $aleatorio = array_rand($tarefasN, 1); //aonde está 1 vc pode usar para ter retorno, exemplo, se quer 2 retornos, ou 3, 4 e assim por diante

    echo $aleatorio . ' - '; //gera índice aleatório

    echo $tarefasN[$aleatorio]; // retorno já com o array organizado
  • Opa Leandro, so I did some tests, and what happens, when I use the array_rand it makes a random choice inside the array, this by itself serves as a draw, but I need the Chances variant to have weight at the time of choice. Following the model you showed me the draw is choosing more times "Eat Pao with Mortadela" that has 1 weight (chance) while the "Eat Pizza" that has 3 weight (chance) is not being drawn. I don’t know if you understand what’s going on, and thank you for trying to help me.

1


I believe that a better approach would be to turn these weights into indexes so perform a Random to check the range drawn.

    <?php

        $weights = ['arroz' => 2,  "feijao" => 1, "macarrao" => 4, "pizza" => 3, "hamburguer" => 4];
        $max = array_sum($weights);
        $sortIndex = rand(1, $max);
        $sort = null;
        $offset = 0;

        foreach ($weights as $key => $value) {
            $offset += $value;
            if ($sortIndex <= $offset) {
                $sort = $key;
                break;
            }
        }

        echo $sort;
  • I had not stopped to think of using the name as key, so it worked, I will stop and and study what happens in each line, to understand the whole concept behind. Thank you very much, I learned one more.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.