//General Mix of Elo and Teamstrength (K, K mod, D mod, extra coms) package zkforumparser; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.stream.Collectors; import java.util.stream.Stream; public class GeneralEloTeamstrength extends ELO { private boolean withKMod; private boolean withDMod; private boolean withExtraComs; //Map ratings = new HashMap(); public TeamstrengthComs(){ withKMod=false; withDMod=false; withExtraComs=true; } public TeamstrengthComs(double k, boolean withKMod, boolean withDMod, boolean withExtraComs){ this.K = k; this.withKMod = withKMod; this.withDMod = withDMod; this.withExtraComs = withExtraComs; } @Override public List predictResult(List> teams) { return teams.stream().map(team -> predictResult(teams, team)).collect(Collectors.toList()); } //------------ //another implementation of predictResult to return single doubles: //@Override public double predictResult(List> teams, Collection team) { double dMod = 1.0; if(withDMod){ dMod = Math.sqrt(teams.stream().mapToDouble(team -> team.size()).reduce(0.0, Double::sum) / teams.size()); } if(withExtraComs){ return (Math.pow(10, dMod*(team.stream().mapToDouble(player -> ratings.get(player)).average().getAsDouble())/400) / teams.stream().map(t -> Math.pow(10, dMod*(t.stream().mapToDouble(player -> ratings.get(player)).average().getAsDouble())/400)).reduce(0.0, Double::sum)); } else return (team.size() * Math.pow(10, dMod*(team.stream().mapToDouble(player -> ratings.get(player)).average().getAsDouble())/400) / teams.stream().map(t -> t.size() * Math.pow(10, dMod*(t.stream().mapToDouble(player -> ratings.get(player)).average().getAsDouble())/400)).reduce(0.0, Double::sum)); } } //------------ @Override public void evaluateResult(Collection> winnerTeams, Collection> loserTeams) { //winnerTeams and loserTeams are combined to use it in predictResult, but I'm not sure if this works with stream.concat (Collection.addAll does not necessarily work because it's an optional operation): Map ratingsc = new HashMap(); List> AllTeams = new List<>(); AllTeams = Stream.concat(winnerTeams.stream(), loserTeams.stream()).collect(Collectors.toList()); double kMod = 1.0; if(withKMod){ kMod = Math.sqrt(AllTeams.stream().mapToDouble(team -> team.size()).reduce(0.0, Double::sum) / AllTeams.size()); } winnerTeams.stream().forEach(t -> t.stream().forEach(x -> ratingsc.put(x, ratings.get(x) + K * kMod * (1 - predictResult(AllTeams , t)) / t.size()))); loserTeams.stream().forEach(t -> t.stream().forEach(x -> ratingsc.put(x, ratings.get(x) - K * kMod * predictResult(AllTeams, t) / t.size()))); ratingsc.forEach((x, y) -> ratings.put(x, y)); } //------------ public boolean getWithKMod(){ return withKMod; } //------------ public boolean getWithDMod(){ return withDMod; } //------------ public boolean getWithExtraComs(){ return withExtraComs; } }