Ejemplo n.º 1
0
func vote(client types.RepPoolClient, instance instance.Instance, representatives []string) (string, float64, error) {
	results := client.Vote(representatives, instance)

	winningScore := 1e9
	winners := []string{}

	for _, result := range results {
		if result.Error != "" {
			continue
		}

		if result.Score < winningScore {
			winningScore = result.Score
			winners = []string{result.Rep}
		} else if result.Score == winningScore { // can be less strict here
			winners = append(winners, result.Rep)
		}
	}

	if len(winners) == 0 {
		return "", 0, AllBiddersFull
	}

	winner := winners[util.R.Intn(len(winners))]

	return winner, winningScore, nil
}
Ejemplo n.º 2
0
func Auction(client types.RepPoolClient, auctionRequest types.AuctionRequest) types.AuctionResult {
	var auctionWinner string

	var representatives []string

	if !auctionRequest.Rules.RepickEveryRound {
		representatives = randomSubset(auctionRequest.RepGuids, auctionRequest.Rules.MaxBiddingPool)
	}

	numRounds, numVotes := 0, 0
	t := time.Now()
	for round := 1; round <= auctionRequest.Rules.MaxRounds; round++ {
		if auctionRequest.Rules.RepickEveryRound {
			representatives = randomSubset(auctionRequest.RepGuids, auctionRequest.Rules.MaxBiddingPool)
		}
		numRounds++
		winner, _, err := vote(client, auctionRequest.Instance, representatives)
		numVotes += len(representatives)
		if err != nil {
			continue
		}

		c := make(chan types.VoteResult)
		go func() {
			winnerScore, err := client.ReserveAndRecastVote(winner, auctionRequest.Instance)
			result := types.VoteResult{
				Rep: winner,
			}
			if err != nil {
				result.Error = err.Error()
				c <- result
				return
			}
			result.Score = winnerScore
			c <- result
		}()

		secondRoundVoters := []string{}

		for _, rep := range representatives {
			if rep != winner {
				secondRoundVoters = append(secondRoundVoters, rep)
			}
		}

		_, secondPlaceScore, err := vote(client, auctionRequest.Instance, secondRoundVoters)

		winnerRecast := <-c
		numVotes += len(representatives)

		if winnerRecast.Error != "" {
			//winner ran out of space on the recast, retry
			continue
		}

		if err == nil && secondPlaceScore < winnerRecast.Score && round < auctionRequest.Rules.MaxRounds {
			client.Release(winner, auctionRequest.Instance)
			continue
		}

		client.Claim(winner, auctionRequest.Instance)
		auctionWinner = winner
		break
	}

	return types.AuctionResult{
		Winner:    auctionWinner,
		Instance:  auctionRequest.Instance,
		NumRounds: numRounds,
		NumVotes:  numVotes,
		Duration:  time.Since(t),
	}
}