游戏中的数学:ELO Rating应用

来源:互联网 发布:襄阳云计算idc机房 编辑:程序博客网 时间:2024/05/06 03:20

在之前的博文中简单介绍了ELO Rating系统,依照其思想,博主写了一个对NBA球队的评分系统,代码如下

import java.io.BufferedReader;import java.io.BufferedWriter;import java.io.File;import java.io.FileNotFoundException;import java.io.FileReader;import java.io.FileWriter;import java.io.IOException;import java.util.ArrayList;import java.util.Collections;import java.util.Comparator;import java.util.Iterator;import javax.sound.sampled.Line;public class NBAEloRating {    //根据结果更新A和B的分数    public static void updateRatingScore(Team teamA, Team teamB, Boolean result){        final double DEFAULT_ELO_K_FACTOR = 24.0;        double exceptionA = 1 / (1 + Math.pow(10, (teamB.getRatingScore() - teamA.getRatingScore())/400));        double exceptionB = 1 - exceptionA;        double scoreA = -1;        double scoreB = -1;        if (result){            scoreA = 1;            scoreB = 0;        }else {            scoreA = 0;            scoreB = 1;        }        double newArating = teamA.getRatingScore() + DEFAULT_ELO_K_FACTOR * (scoreA - exceptionA);        double newBrating = teamB.getRatingScore() + DEFAULT_ELO_K_FACTOR * (scoreB - exceptionB);        teamA.setRatingScore(newArating);        teamB.setRatingScore(newBrating);    }    //输出每个球队的评分    public static void printRating(ArrayList<Team> teams){        for (int i = 0; i < teams.size(); i++){            System.out.print(teams.get(i).getTeamName() + ":");            System.out.print(teams.get(i).getRatingScore());            System.out.println();        }    }    public static void main(String[] args) throws IOException{        ArrayList<Team> teams = computeRatingScore();        String predictionFilePath = "res\\prediction";        prediction(teams, predictionFilePath);    }    //根据已有的评分,预测比赛结果    private static void prediction(ArrayList<Team> teams,            String predictionFilePath) throws IOException {        String outputPath = "output\\prediction";        BufferedReader in = new BufferedReader(new FileReader(predictionFilePath));        String game = in.readLine();        String output = "";        while(game != null){            String temp[] = game.split(" ");            int teamA = findTeamNo(teams, temp[0]);            int teamB = findTeamNo(teams, temp[1]);            double teamAWinPro = computeProbability(teams.get(teamA), teams.get(teamB));            output += game + " " + teamAWinPro + " " + (1 - teamAWinPro) + "\r\n";            game = in.readLine();        }        File f = new File(outputPath);        if(!f.exists()){            f.createNewFile();        }        FileWriter fw = new FileWriter(f.getAbsoluteFile());        BufferedWriter bw = new BufferedWriter(fw);        bw.write(output);        bw.close();    }    private static double computeProbability(Team teamA, Team teamB) {        return 1 / (1 + Math.pow(10, (teamB.getRatingScore() - teamA.getRatingScore())/400));    }    public static ArrayList<Team> computeRatingScore() throws IOException{        ArrayList<Team> teams = initailize();        String dataFilePath = "res\\scoredata";        BufferedReader in = new BufferedReader(new FileReader(dataFilePath));        String result = in.readLine();        while(result != null){            String temp[] = result.split(" ");            int teamA = findTeamNo(teams, temp[0]);            int teamB = findTeamNo(teams, temp[1]);            boolean rslt = getResult(temp[2]);            updateRatingScore(teams.get(teamA), teams.get(teamB), rslt);            result = in.readLine();        }        sortByRatingScore(teams);        printRating(teams);        return teams;    }    private static void sortByRatingScore(ArrayList<Team> teams) {        Collections.sort(teams, new Comparator<Team>(){            @Override            public int compare(Team arg0, Team arg1) {                double scoreA = arg0.getRatingScore();                double scoreB = arg1.getRatingScore();                if (scoreA < scoreB)                    return 1;                else {                    return -1;                }            }        });    }    private static boolean getResult(String string) {        String tmp[] = string.split(":");        int teamA = Integer.parseInt(tmp[0]);        int teamB = Integer.parseInt(tmp[1]);        if (teamA > teamB)            return true;        else {            return false;        }    }    private static int findTeamNo(ArrayList<Team> teams, String teamName) {        int teamNo = 0;        while(!teamName.equals(teams.get(teamNo).getTeamName())){            teamNo++;        }        return teamNo;    }    //初始化所有球队的评分    private static ArrayList<Team> initailize() throws IOException {        ArrayList<Team> teams = new ArrayList<>();        String teamListFilePath = "res\\teamlist";        BufferedReader in = new BufferedReader(new FileReader(teamListFilePath));        String teamName = in.readLine();        while (teamName != null){            Team team = new Team(teamName, 1500);            teams.add(team);            teamName = in.readLine();        }        return teams;    }}
public class Team {    private String teamName;    private double ratingScore;    public Team(String teamName, double ratingScore) {        super();        this.teamName = teamName;        this.ratingScore = ratingScore;    }    public String getTeamName() {        return teamName;    }    public void setTeamName(String teamName) {        this.teamName = teamName;    }    public double getRatingScore() {        return ratingScore;    }    public void setRatingScore(double ratingScore) {        this.ratingScore = ratingScore;    }}

球队的历史交锋数据保存在scoredata文件中,这个是用爬虫程序抓取出来的,如果想要实现如上的预测系统可以自己写一个爬虫程序,抓取出数据的格式为:

球队A 球队B 比分
譬如:
小牛 马刺 80:99

0 0
原创粉丝点击