1

I have a group of individuals that I am distributing items to in an effort to move toward even distribution of total items across individuals.

Each individual can receive only certain item types.

The starting distribution of items is not equal.

The number of available items of each type is known, and must fully be exhausted.

df contains an example format for the person data. Note that Chuck has 14 items total, not 14 bats and 14 gloves.

df<-data.frame(person=c("Chuck","Walter","Mickey","Vince","Walter","Mickey","Vince","Chuck"),alloweditem=c("bat","bat","bat","bat","ball","ball","glove","glove"),startingtotalitemspossessed=c(14,9,7,12,9,7,12,14))

otherdf contains and example format for the items and number needing assignment

otherdf<-data.frame(item=c("bat","ball","glove"),numberneedingassignment=c(3,4,7))

Is there a best method for coding this form of item distribution? I imagine the steps to be:

  1. Check which person that can receive a given item has the lowest total items assigned. Break a tie at random.

  2. Assign 1 of the given item to this person.

  3. Update the startingtotalitemspossessed for the person receiving the item.

  4. Update the remaining number of the item left to assign.

  5. Stop this loop for a given item if the total remaining is 0, and move to the next item.

Below is a partial representation of something like how i'd imagine this working as a view inside the loop, left to right.

enter image description here

Note: The number of items and people is very large. If possible, a method that would scale to any given number of people or items would be ideal!

Thank you in advance for your help!

Pake
  • 968
  • 9
  • 24
  • https://stackoverflow.com/questions/11254452/distributing-an-amount-as-evenly-as-possible Seems to be similar (?), but I'm not clear on to adjust to suit this problem. – Pake Aug 17 '18 at 18:19

1 Answers1

1

I'm sure there are better ways, but here is an example:

df<-data.frame(person=c("Chuck","Walter","Mickey","Vince","Walter","Mickey","Vince","Chuck"),
    alloweditem=c("bat","bat","bat","bat","ball","ball","glove","glove"),
    total=c(14,9,7,12,9,7,12,14))
print(df)
##   person alloweditem total
## 1  Chuck         bat    14
## 2 Walter         bat     9
## 3 Mickey         bat     7
## 4  Vince         bat    12
## 5 Walter        ball     9
## 6 Mickey        ball     7
## 7  Vince       glove    12
## 8  Chuck       glove    14

otherdf<-data.frame(item=c("bat","ball","glove"),
    numberneedingassignment=c(3,4,7))

# Items in queue
queue <- rep(otherdf$item, otherdf$numberneedingassignment)

for (i in 1:length(queue)) {
  # Find person with the lowest starting total
    personToBeAssigned <- df[df$alloweditem == queue[i] & 
    df$total == min(df[df$alloweditem == queue[i], 3]), 1][1]
    df[df$person == personToBeAssigned & df$alloweditem == queue[i], 3] <- 
      df[df$person == personToBeAssigned & df$alloweditem == queue[i], 3] + 1
}

print(df)
##   person alloweditem total
## 1  Chuck         bat    14
## 2 Walter         bat    10
## 3 Mickey         bat     9
## 4  Vince         bat    12
## 5 Walter        ball    10
## 6 Mickey        ball    10
## 7  Vince       glove    17
## 8  Chuck       glove    16
howard.h
  • 808
  • 1
  • 8
  • 14