I have N pessoas
to form as many meetings as possible. These N pessoas
can not speak to anyone who has already spoken at other meetings. Each meeting has at most N pessoas
.
Based on this information I can set up an example:
$pessoasIds = array(1,2,3,4,5,6,7,8,9...120); // Até 120 pessoas
$maxPessoas = 13; // 13 pessoas por reunião
There are a few key points that should be considered:
- I can not allow
Pessoa 1
to talk toPessoa 2
if they have already talked at any other meeting. I'll give an example using6 pessoas
with max3 por reunião
An example would be this:
$reunioes = array( 0 => array(1, 2, 3), 1 => array(1, 4, 5), 2 => array(1, 6), 3 => array(2, 4, 6), // a pessoa número 2 ja conversou com a pessoa número 3 e 1 e a pessoa número 4 com a 5 4 => array(2, 5) );
- I need to keep the maximum number of people per meeting and can not exceed this amount.
- I need to keep at least one meeting per person. But I must also make each person have a similar number of meetings, so as not to get too uneven. Of course there will be people with fewer meetings than the others, but as long as this difference is small, that's fine.
- In addition to keeping the maximum number of people in each meeting, I also need to try to maintain a default number of people. For example, I need at least that most people can make a meeting and that is with 13 people each. If the other meetings are 8, 7, 5 or 2 people, it does not matter, but at least a good part of the meetings have the same number of participants, again not to be unfair.
- I also need to keep a certain order of combination. When I bring everyone in the database, I need to sort them in the order of priority. The highest priority comes first, with more chance of having scheduled meetings.
Now, I tried some different logic but none worked:
First attempt
Take Pessoa 1
and combine it with all the others, to form 13 meetings per person. The problem is that Pessoa 1
will always have more meetings than the others, because as it is the first, there is no meeting yet, no one has spoken to anyone yet.
Second attempt
I tried to combine only uma
meeting of each person and return to the first. For example: I am combining the Pessoa 1
meeting. I pass to the second person, third and so on until the last person. When you get to the last one, go back to the first person and see if you can still generate another meeting. It did not work as well because the number of people at each meeting was very uneven. Example: In a list of 120 people with 13 people in each meeting, there were already only two people per meeting by the 11th meeting.
Third Try
This attempt was based on combining one by one. I pick up the first person and add another, thus forming a meeting of two people. I do the same with the second person, third person, and so on until there are a maximum of people per meeting in each one. The problem of this attempt I show below, which I will put as an example in PHP:
$reunioes = array(
1 => array(1,2), // reunião da pessoa número 1
2 => array(2,3), // reunião da pessoa número 2 e etc...
3 => array(3,1)
4 => array(4,1),
5 => array(5,1)
// ...
);
When I try to generate the next set of meetings for Pessoa 1
again, it will not have any more meetings to be generated, because everyone has already spoken with Pessoa 1
.
Objective
The ultimate goal is to form meetings with the average number of people in each group, respecting all the 'rules' I've written in the question
It may happen that you have meetings for two people, but the preference is that you always try to reach the maximum number of people in a meeting, which in the example I gave is 13. If the given limit is 5 people per meeting, the ideal would be that all meetings were with 5 people, but that depends on how many people you have and so on, so it is normal for some to have less than the other and acceptable!
Further details
Note also that I will use ID's instead of sequence numbers. Instead of using 1,2,3,4
, I'll be using 46,12,13,10,1,9
that would be the id's of each person.