In this initial model, we have 3 phases
# Phase 01: Idea generation We assign a random number to each agent
target <- 1e9 # we set the target at 1'000'000'000
totAgents <- 1e3 # We use 1'000 agents
clusters <- 10 # We assume 10 domains for ideas
set.seed(1) #Setting a seed to allow comparable results
ideas <- runif(totAgents, min=0, max=target) # Generating random numbers in a uniform distribution
We cluster the results
ideaClusters <- 1+as.integer(ideas/(target/clusters)) #Extracting the cluster by dividing each number to the number of clusters
agentsId <- 1:totAgents # Adding a UID
agentsReward_01 <- rep(0,totAgents) # A variable associated to phase 01
agentsReward_02 <- rep(0,totAgents) # A variable associated to phase 02
agents <- data.frame(agentsId, ideas, ideaClusters,agentsReward_01,agentsReward_02) #Creating a dataframe with ID, value and cluster
# hist(agents$ideas)
# hist(agents$ideaClusters)
We assign prizes
idClusters <- seq(1:clusters)
idWinners <- rep(NA,clusters)
valueWinners <- rep(NA,clusters)
listWinners <- data.frame(idClusters,idWinners, valueWinners) #Creating a dataframe with Cluster ID, Winner ID and value
for(i in 1:totAgents){
j <- agents[i,3] # Check the cluster of the agent
if(is.na(listWinners[j,2])){ # If the cluster of the agent does not have a winner (it's value is NA) ...
listWinners[j,2] <-agents[i,1] # ... use the agent's ID
listWinners[j,3] <-agents[i,2] # ... use the agent's value
agents[i,4] <- 1 # rewarding the selected agent
}
}
listWinners
## idClusters idWinners valueWinners
## 1 1 10 61786270
## 2 2 12 176556753
## 3 3 1 265508663
## 4 4 2 372123900
## 5 5 16 497699242
## 6 6 3 572853363
## 7 7 8 660797792
## 8 8 15 769841420
## 9 9 6 898389685
## 10 10 4 908207790
#Phase 02: Idea pooling We use lpSOlve to define the objective function
library(lpSolve)
objective.in <- listWinners[,3] # Pooling the retained ideas by looking for the best combination
We define the constraints of the function
mat <- matrix(listWinners[,3], nrow=1, byrow=TRUE) # The sum of the pooled ideas ...
dir <- "<=" # ... should be below ...
rhs <- target # ... the target
We solve the Linear programming function and we reward the owners of the pooled ideas
optimum <-lp(direction="max", objective.in, mat, dir, rhs, all.bin = TRUE) # Which is the best combination of pooled ideas?
optimum$solution # The selected ideas
## [1] 1 0 1 0 0 0 1 0 0 0
for(i in 1:clusters){
if(optimum$solution[i] >0){ # if an idea is pooled ...
j <- listWinners[i,2] # ... select the owner of the pooled idea
agents[j,5] <- 1 # ... and reward the agent another time
}
}
Filter the winners
totWinners <- filter(agents, agentsReward_01 >0) # This could reduce computational effort
Gather the two last columns of agents into one
library(tidyverse)
agentsRewards <- agents %>%
gather('agentsReward_01', 'agentsReward_02', key = "Phase", value = "Rewards")
Summarize by agent
summarise(group_by(agentsRewards, agentsId), Rewards = sum(Rewards, na.rm = TRUE))
## # A tibble: 1,000 x 2
## agentsId Rewards
## <int> <dbl>
## 1 1 2
## 2 2 1
## 3 3 1
## 4 4 1
## 5 5 0
## 6 6 1
## 7 7 0
## 8 8 2
## 9 9 0
## 10 10 2
## # ... with 990 more rows
Check the reminder for another idea challenge
remainder <- target - sum(agents$ideas*agents$agentsReward_02) #Comparing the initial target with the sum of the pooled ideas
Setting up a function to generate ideas
phase00 <- function(target, totAgents,totIdeas,clusters){
set.seed(1) #Setting a seed to a fix number to allow comparable results
agentsId <- as.integer(rnorm(totIdeas, totAgents/2, totAgents/10)) # Assigning an owner to each idea (this allows multiple ideas to one owner)
set.seed(1) #Setting a seed again
idea <- as.integer(runif(totIdeas, min = 0, max = target)) # Generating random numbers in a uniform distribution
ideaClusters <- 1+as.integer(idea/(target/clusters)) #Extracting the cluster by dividing each number to the number of clusters
agentsReward_01 <- rep(0,totIdeas) # A variable associated to phase 01
agentsReward_02 <- rep(0,totIdeas) # A variable associated to phase 02
ideas <- data.frame(agentsId, idea, ideaClusters,agentsReward_01,agentsReward_02) #Creating a dataframe with ID, value and cluster
return(ideas)
}
Setting up a function to select ideas
phase01 <- function(clusters, ideas){
#Creating a dataframe with Cluster ID, Winner ID and value
idClusters <- seq(1:clusters)
idWinners <- rep(NA, clusters)
valueWinners <- rep(NA, clusters)
listWinners <- data.frame(idClusters, idWinners, valueWinners)
#Reward the owners of the selected ideas
lenIdeas <- dim(ideas)[1]
for (i in 1:lenIdeas) {
j <- ideas[i, 3] # Check the cluster of the idea
if (is.na(listWinners[j, 2])) {
# If the cluster of the agent does not have a winner (it's value is NA) ...
listWinners[j, 2] <- ideas[i, 1] # ... use the agent's ID
listWinners[j, 3] <- ideas[i, 2] # ... use the idea's value
ideas[i, 4] <- 1 +ideas[i, 4] # rewarding the selected agent by increasing the reward to 1 (taking into account multiple challenges)
}
}
return(ideas)
}
Setting up a function to pool ideas
phase02 <- function (selectedIdeas, target) {
library(lpSolve)
ideas <- selectedIdeas
listWinners <- filter(ideas, agentsReward_01 >0) #Filtering the list of winners before performing a left join with the pooled ideas
#Linear programming
objective.in <- listWinners[, 2] # Trying to pool the retained ideas by looking for the best combination of coefficients
mat <- matrix(listWinners[, 2], nrow = 1, byrow = TRUE) # The sum of the pooled ideas ...
dir <- "<=" # ... should be below ...
rhs <- target # ... the target
optimum <- lp(direction = "max", objective.in, mat, dir, rhs, all.bin = TRUE) # Which is the best combination of pooled ideas?
optimum$solution # The selected ideas
listWinners[,5] <- optimum$solution #Assign prizes
polledIdeas <- ideas %>%
left_join(listWinners, by = c("agentsId","idea","ideaClusters","agentsReward_01")) #Left join
agentsReward_02 <- polledIdeas$agentsReward_02.x+ polledIdeas$agentsReward_02.y # Taking into account previous idea challenges
polledIdeas <- data.frame(polledIdeas,agentsReward_02) #add the new column
polledIdeas[5] <- NULL # Removing the redundant columns
polledIdeas[5] <- NULL # Removing the redundant columns
return(polledIdeas)
}
Setting up a function to summarize the rewards
phase03 <- function(ideas, target){
library(tidyverse)
agentsRewards <- ideas %>%
gather('agentsReward_01', 'agentsReward_02', key = "Phase", value = "Rewards")
winners <- summarise(group_by(agentsRewards, agentsId, idea), Rewards = sum(Rewards, na.rm = TRUE))
winners <- arrange(winners, idea) #Sorting ideas
problemSolved <- sum(filter(winners, Rewards > 1)[, 2])
#Print results for comparison
print("filter(winners, Rewards >0)")
print(filter(winners, Rewards > 0)) # Test: selected ideas
print("Mean(winners$Rewards)")
print(mean(winners$Rewards))
print("Problem Solved")
print(problemSolved)
print("Remainder")
print(target-problemSolved)
return(agentsRewards)
}
Setting up a function to run an idea Challenge
ideaChallenge <- function(target, totAgents, totIdeas, clusters, sortedIdea) {
generatedIdeas <- as.data.frame(seq(1:totIdeas))
generatedIdeas <- phase00(target, totAgents, totIdeas, clusters) # Generating ideas
if(sortedIdea) generatedIdeas <-arrange(generatedIdeas,desc(idea)) # Sorting ideas by experts
selectedIdeas <- phase01(clusters, generatedIdeas) # Selecting ideas
polledIdeas <- phase02(selectedIdeas, target) # Polling ideas
agentsRewards <- phase03(polledIdeas, target)
return(agentsRewards)
}
target <- 1e9 # we set the target at 1'000'000'000
totAgents <- 1e3
totIdeas <- 1e4
clusters <- 1
generatedIdeas0 <- as.data.frame(seq(1:totIdeas))
generatedIdeas0 <- phase00(target, totAgents, totIdeas, clusters) # Generating ideas
generatedIdeas0 <-arrange(generatedIdeas0,desc(idea)) #Sorting ideas by experts
selectedIdeas0 <- phase01(clusters, generatedIdeas0) # Selecting ideas
agentsRewards0 <- selectedIdeas0 %>%
gather('agentsReward_01', 'agentsReward_02', key = "Phase", value = "Rewards")
winners <- dim(filter(agentsRewards0, Rewards>0))[1]
quality <-filter(agentsRewards0, Rewards==1)[,2]
prize <- mean(agentsRewards0$Rewards) * totAgents
challengeID <- "Single Winner"
performance <- data.frame(challengeID, winners, quality, prize)
performance$winners # Winners
## [1] 1
performance$quality # Sum of the pooled ideas
## [1] 999930593
performance$prize # Cost of prizes
## [1] 0.05
MODEL A: Selecting the first idea for each cluster
target <- 1e9 # we set the target at 1'000'000'000
totAgents <- 1e3
totIdeas <- 1e4
clusters <- 10
agentsRewards1_1 <- ideaChallenge(target, totAgents, totIdeas, clusters, FALSE)
## [1] "filter(winners, Rewards >0)"
## # A tibble: 10 x 3
## # Groups: agentsId [10]
## agentsId idea Rewards
## <int> <int> <dbl>
## 1 469 61786270 1
## 2 538 176556752 2
## 3 437 265508663 1
## 4 518 372123899 1
## 5 495 497699242 1
## 6 416 572853363 1
## 7 573 660797792 1
## 8 612 769841419 2
## 9 417 898389684 1
## 10 659 908207789 1
## [1] "Mean(winners$Rewards)"
## [1] 0.0012
## [1] "Problem Solved"
## [1] 946398171
## [1] "Remainder"
## [1] 53601829
Model B: Selecting the idea for each cluster with the highest score
agentsRewards2 <- ideaChallenge(target, totAgents, totIdeas, clusters, TRUE) #using sorted ideas
## [1] "filter(winners, Rewards >0)"
## # A tibble: 10 x 3
## # Groups: agentsId [10]
## agentsId idea Rewards
## <int> <int> <dbl>
## 1 359 99989993 2
## 2 508 199977182 1
## 3 486 299951496 1
## 4 617 399994368 2
## 5 474 499982866 2
## 6 552 599919136 1
## 7 469 699974252 1
## 8 468 799901459 1
## 9 544 899746668 1
## 10 578 999930593 1
## [1] "Mean(winners$Rewards)"
## [1] 0.0013
## [1] "Problem Solved"
## [1] 999967227
## [1] "Remainder"
## [1] 32773
# Setting up the remainder as new target
winners1_1 <- summarise(group_by(agentsRewards1_1, agentsId, idea), Rewards = sum(Rewards, na.rm = TRUE))
problemSolved1_1 <- sum(filter(winners1_1, Rewards > 1)[, 2])
remainder1_1 <- target - problemSolved1_1
agentsRewards1_2 <- ideaChallenge(remainder1_1, totAgents, totIdeas, clusters, FALSE)
## [1] "filter(winners, Rewards >0)"
## # A tibble: 10 x 3
## # Groups: agentsId [10]
## agentsId idea Rewards
## <int> <int> <dbl>
## 1 469 3311857 1
## 2 538 9463764 2
## 3 437 14231749 1
## 4 518 19946521 1
## 5 495 26677589 1
## 6 416 30705988 1
## 7 573 35419970 1
## 8 612 41264908 2
## 9 417 48155330 1
## 10 659 48681598 1
## [1] "Mean(winners$Rewards)"
## [1] 0.0012
## [1] "Problem Solved"
## [1] 50728672
## [1] "Remainder"
## [1] 2873157
# agentsRewards1_3 <- ideaChallenge_Cheatstorming(remainder1_1, totAgents, totIdeas, clusters, agentsRewards1_1) # Using old ideas
target <- remainder1_1 # New target
generatedIdeas<- agentsRewards1_1 %>%
spread(key = Phase, value = Rewards) # Putting the table back in shape
generatedIdeas<-filter(generatedIdeas,idea<target) #Removing the ideas that are above the target
generatedIdeas$ideaClusters <- 1+as.integer(generatedIdeas$idea/(target/clusters))# New clusters
generatedIdeas$agentsReward_01 <- 1/dim(generatedIdeas)[1] +generatedIdeas$agentsReward_01 # Reward all contributions in phase 01
if(is.na(generatedIdeas$agentsReward_02)) {
generatedIdeas$agentsReward_02 <- 0 # Remove NA from column 2
}
selectedIdeas <- generatedIdeas
pooledIdeas <- phase02(selectedIdeas, target) # Pooling ideas
agentsRewards <- phase03(pooledIdeas, target)
## [1] "filter(winners, Rewards >0)"
## # A tibble: 564 x 3
## # Groups: agentsId [301]
## agentsId idea Rewards
## <int> <int> <dbl>
## 1 465 106433 0.00177
## 2 546 120655 0.00177
## 3 342 200380 1.00
## 4 569 570522 0.00177
## 5 405 605266 1.00
## 6 573 656347 0.00177
## 7 510 668174 0.00177
## 8 585 682127 0.00177
## 9 320 918506 1.00
## 10 309 1026818 0.00177
## # ... with 554 more rows
## [1] "Mean(winners$Rewards)"
## [1] 0.0141844
## [1] "Problem Solved"
## [1] 53601829
## [1] "Remainder"
## [1] 0
filter(agentsRewards, Rewards>=1)
## agentsId idea ideaClusters Phase Rewards
## 1 260 6082597 2 agentsReward_02 1
## 2 320 918506 1 agentsReward_02 1
## 3 342 200380 1 agentsReward_02 1
## 4 395 1836858 1 agentsReward_02 1
## 5 405 605266 1 agentsReward_02 1
## 6 545 1363479 1 agentsReward_02 1
## 7 776 42594743 8 agentsReward_02 1
clusters <- 50 # Increased the number of clusters
agentsRewards3 <- ideaChallenge(target, totAgents, totIdeas, clusters, FALSE)
## [1] "filter(winners, Rewards >0)"
## # A tibble: 50 x 3
## # Groups: agentsId [46]
## agentsId idea Rewards
## <int> <int> <dbl>
## 1 484 717746 1
## 2 536 1250595 1
## 3 620 3158990 1
## 4 469 3311857 1
## 5 698 5331568 1
## 6 494 5785975 1
## 7 301 6729982 2
## 8 526 7681376 1
## 9 538 9463764 1
## 10 494 9981604 1
## # ... with 40 more rows
## [1] "Mean(winners$Rewards)"
## [1] 0.0054
## [1] "Problem Solved"
## [1] 53600792
## [1] "Remainder"
## [1] 1037