/** * Returns the set of songs which are proposed by the agents. * * @param proposalTimes * @return The songs */ private List<BaseSong<BaseArtist, BaseAlbum>> getProposedSongs(AgentsTiming proposalTimes) { Set<IAgent> agents = agentManager.getAgents(); // Using set here to ensure no duplicate entries Set<BaseSong<BaseArtist, BaseAlbum>> proposedSongs = new HashSet<BaseSong<BaseArtist, BaseAlbum>>(SONG_PROPOSAL_USAGE_COUNT * agents.size()); for (IAgent agent : agents) { throwIfAborted(); StopWatch stopWatch = StopWatch.start(); List<BaseSong<BaseArtist, BaseAlbum>> agentProposals = new ArrayList<BaseSong<BaseArtist, BaseAlbum>>(agent.suggestSongs(SONG_PROPOSAL_COUNT)); // Get #SONG_PROPOSAL_USAGE_COUNT items of them at random while (agentProposals.size() > SONG_PROPOSAL_USAGE_COUNT) { agentProposals.remove(RandomProvider.getRandom().nextInt(agentProposals.size())); } proposedSongs.addAll(agentProposals); proposalTimes.addAgentTiming(agent, stopWatch.stop()); } return new ArrayList<BaseSong<BaseArtist, BaseAlbum>>(proposedSongs); }
/** * Returns the average votes of the agents for the given songs. The votes gets weighted by the * importance of the agents. * * @param proposedSongs The proposed songs * @param agentsVotes (out) The votes for all the songs by agent * @param voteTimes * @return The weighted mean votes for the songs */ private Map<BaseSong<BaseArtist, BaseAlbum>, Double> getVotesForProposed( List<BaseSong<BaseArtist, BaseAlbum>> proposedSongs, Map<IAgent, List<SongVote>> agentsVotes, AgentsTiming voteTimes) { Set<IAgent> agents = agentManager.getAgents(); // Init the ratings list & the weight sum table Map<BaseSong<BaseArtist, BaseAlbum>, Double> votes = new HashMap<BaseSong<BaseArtist, BaseAlbum>, Double>(); Map<BaseSong<BaseArtist, BaseAlbum>, Double> weightSums = new HashMap<BaseSong<BaseArtist, BaseAlbum>, Double>(agents.size()); for (BaseSong<BaseArtist, BaseAlbum> song : proposedSongs) { votes.put(song, 0.0d); weightSums.put(song, 0.0d); } // Calculate the song ratings for (IAgent agent : agents) { throwIfAborted(); // Get the agent vote List<SongVote> agentVotes; StopWatch stopWatch = StopWatch.start(); { agentVotes = agent.vote(Collections.unmodifiableList(proposedSongs)); } voteTimes.addAgentTiming(agent, stopWatch.stop()); // Fill up the list to ensure that a vote for all songs exist List<BaseSong<BaseArtist, BaseAlbum>> noVote = new ArrayList<BaseSong<BaseArtist, BaseAlbum>>(proposedSongs); for (int i = 0; i < agentVotes.size(); ) { final SongVote vote = agentVotes.get(i); int idx = noVote.indexOf(vote.getSong()); if (idx >= 0) { noVote.remove(idx); ++i; } else { // No vote for this song is required agentVotes.remove(i); } } for (BaseSong<BaseArtist, BaseAlbum> song : noVote) { agentVotes.add(new SongVote(song, 0.0f)); } agentsVotes.put(agent, agentVotes); for (SongVote vote : agentVotes) { final BaseSong<BaseArtist, BaseAlbum> song = vote.getSong(); double oldRating = votes.get(song); double agentWeight = getAgentWeights().get(agent); double oldW = weightSums.get(song); double newW = oldW + agentWeight; double newRating = (oldRating * oldW + vote.getVote() * agentWeight) / newW; // Continuous, weighted mean calculation votes.put(song, newRating); weightSums.put(song, newW); } } return votes; }