当前位置:网站首页>Simulation lottery and probability statistics experiment of the top 16 Champions League

Simulation lottery and probability statistics experiment of the top 16 Champions League

2022-06-24 20:26:00 coder_ szc

background

It's new year's day , Send a commemorative article :《 Champions League top 16 simulation lottery and probability statistics experiment 》, It is used to calculate the encounter probability between each team and all possible opponents in the last 16 of the Champions League , And the probability of each match .

Rule description

Before introducing this experiment , First, clarify the draw rules for the last 16 of the Champions League with non fans or friends who do not understand the draw rules for the last 16 of the Champions League :
1、 The top 16 of the Champions League were selected from the top two of the eight groups , And according to the avoidance rules, draw lots for each team to select the top 16 ( The eighth finals ) The opponent ;
2、 Avoidance rules 1: Group avoidance , That is, if the team A and B From the same group ( That is to say, they are the top two of the group ), Then avoid , If we don't meet in the last 16 ;
3、 Avoidance rules 2: Avoid with the Football Association , Every country or region has a football association , Such as Scottish Football Association 、 The English Football Association 、 German Football Association, etc , If the team A and B From the same Football Association , Then avoid ;
4、 Avoidance rules 3: Avoid ranking in the same group , That is, if the team A and B Rank the same in their respective groups , For example, they are the first or the second in the group , Then avoid .
The top 16 teams in this experiment are from 21-22 The last 16 of the Champions League this season .

Experimental design

I'm not writing papers here , So the design is simpler . This experiment was conducted according to the avoidance rule 3000 The second independent top 16 draw lots , And count the encounters of each team , And what happens to each match chart , Finally, the encounter probability of each opponent of each team is not output in ascending order 、 Encounter frequency and probability and frequency of occurrence of each match chart .
There are four classes in this experiment :Team、Matcher、AgainstPlan and UEFAChampionLeagueDraw.

Team class

Team Class is the encapsulation of team information and processing , Team information includes basic information ( Team name 、 Your group 、 Ranking of the football association and the group )、 The information of this lottery ( Whether to complete the match and the opponent selected in this lottery ) And Global lottery information ( The number of encounters between all possible opponents and all opponents ).
Team information processing in addition to the basic information and whether to complete the match get/set outside , It also includes additions and deletions to all possible competitors 、 Add and output the number of encounters of all opponents

AgainstPlan class

AgainstPlan Class is a graph class , It is used to save and process the match map generated by each round of drawing , The singleton pattern is used . The field is just one : The number of occurrences of all matchups , This class is responsible for adding and outputting the number of occurrences of all match graphs . Because the data of a single graph is long , And there are many kinds of match charts , So the default output is only before the occurrence times 20 The match chart of .

Matcher class

This class has no fields , Responsible for three things :1、 A single draw for the last 16 of the Champions League , And to Team The number of encounters of all opponents in the class and AgainstPlan Class to submit the result of this lottery ;2、 Reset the draw for the last 16 of the Champions League ;3、 Judge whether the two teams can complete the match

UEFAChampionLeagueDraw class

This class is an entry class , Responsible for initializing the basic information of the last 16 Champions League players 、 start-up 3000 Sub independent Matcher draw 、 Output statistics .

Code implementation

Team class

First define all the fields , And realize the basic get/set Method :

    private String name; //  Team name 
    private String country; //  The country of the team 
    private String group; //  Team group 
    private int rankInGroup; //  The team's ranking in the group 
    private boolean matched = false; //  Whether the team matches 
    private HashMap<String, Integer> oppositeCount = new HashMap<>(); //  Record opponents and encounters 
    private String oppositeCache = null; //  Opponent cache 
    private List<Team> allPossibleOpposites = new ArrayList<>(); //  All possible rivals 

    public String getName() {
    
        return name;
    }

    public Team setName(String name) {
    
        this.name = name;
        return this;
    }

    public String getCountry() {
    
        return country;
    }

    public Team setCountry(String country) {
    
        this.country = country;
        return this;
    }

    public String getGroup() {
    
        return group;
    }

    public Team setGroup(String group) {
    
        this.group = group;
        return this;
    }

    public int getRankInGroup() {
    
        return rankInGroup;
    }

    public Team setRankInGroup(int rankInGroup) {
    
        this.rankInGroup = rankInGroup;
        return this;
    }

    public boolean isMatched() {
    
        return matched;
    }

    public Team setMatched(boolean matched) {
    
        this.matched = matched;
        return this;
    }

Then add all possible opponents for the current team :

    /** *  From all teams @allOpposites Select all possible opponents  * @param allOpposites  All teams  * @return this */
    public Team addAllPossibleOpposite(Team[] allOpposites) {
    
        for (Team opposite : allOpposites) {
    
            if (opposite.getCountry().equals(country) //  The same country avoids 
                    || opposite.getGroup().equals(group) //  Group avoidance 
                    || opposite.getRankInGroup() == rankInGroup /*  Avoid the same rank  */ ) {
    
                continue;
            }
            addPossibleOpposite(opposite);
        }
        return this;
    }

    /** *  From all teams @allOpposites Select all possible opponents  * @param allOpposites  All teams  * @return this */
    public Team addAllPossibleOpposite(List<Team> allOpposites) {
    
        for (Team opposite : allOpposites) {
    
            if (opposite.getCountry().equals(country) //  The same country avoids 
                    || opposite.getGroup().equals(group) //  Group avoidance 
                    || opposite.getRankInGroup() == rankInGroup /*  Avoid the same rank  */ ) {
    
                continue;
            }
            addPossibleOpposite(opposite);
        }
        return this;
    }

    /** *  Add your opponent to all your opponents  * @param opposite  Current competitor  */
    private void addPossibleOpposite(Team opposite) {
    
        if (!allPossibleOpposites.contains(opposite)) {
    
            allPossibleOpposites.add(opposite);
        }
    }

When some other team completes the match , We want to remove this team from the current team's possible opponents :

    /** *  Remove the opponent from all possible opponents of the team , At this time, the opponent may have finished pairing  * @param opposite  Current competitor  * @return this */
    public Team removePossibleOpposite(Team opposite) {
    
        allPossibleOpposites.remove(opposite);
        return this;
    }

We need to judge whether the current team has any possible opponents , And whether a certain team is the only possible opponent of the current team , These two points are very important to judge whether the other two teams can match , Now we will talk about this :

	/** *  Judge @opposite Is it the only possible opponent of the team  * @param opposite  Current competitor  * @return true The current opponent is the only possible opponent of the team ,false It means not  */
    public boolean isOnlyPossibleOpposite(Team opposite) {
    
        return allPossibleOpposites.size() == 1 && allPossibleOpposites.contains(opposite);
    }
    /* * *  Is there any other possible opponent for our team  * @return true It means that there are still possible competitors ,false Does not exist  */
    public boolean hasPossibleOpposites() {
    
        return !allPossibleOpposites.isEmpty();
    }

When pairing the current team , We need to read, write, and judge the opponent cache for this round of lottery :

    /** *  Set opponent cache  * @param opposite  Current competitor  * @return this */
    public Team setOppositeCache(Team opposite) {
    
        String oppositeName = opposite.getName();
        if (!oppositeName.equals(oppositeCache)) {
    
            oppositeCache = oppositeName;
        }
        return this;
    }

    public String getOppositeCache() {
    
        return oppositeCache;
    }

    /** *  Reset opponent cache , There are two situations :1、 initialization , Start a new draw ;2、 A lottery attempt failed , It is necessary to restart this lottery  * @return this */
    public Team unsetOppositeCache() {
    
        oppositeCache = null;
        return this;
    }

After the draw , We need not to output the encounter of each opponent of the current team in ascending order :

    /** *  Output all opponents of the team and their corresponding encounter frequency and frequency , Sort in ascending order according to the encounter frequency  * @return String  String to be displayed  */
    public String printOppositePossibilities() {
    
        StringBuilder builder = new StringBuilder();

        //  Will all the opponents appear , Sort by the number of encounters in descending order 
        Integer[] matchCountSorted = new Integer[oppositeCount.size()];
        int i = 0;
        int totalCount = 0;
        for (String opposite : oppositeCount.keySet()) {
    
            matchCountSorted[i] = oppositeCount.get(opposite);
            totalCount += matchCountSorted[i];
            i++;
        }

        Arrays.sort(matchCountSorted, Collections.reverseOrder());

        //  Whether a certain encounter frequency completes the output index list ,1 Indicates that all teams corresponding to this frequency have been output ,0 It indicates whether there is any team output for this frequency 
        List<Integer> appended = new ArrayList<Integer>();
        for (int j = 0; j < oppositeCount.size(); j++) {
    
            appended.add(0);
        }

        builder.append("{ \n");
        for (Integer value : matchCountSorted) {
    
            int index = 0;
            for (Map.Entry<String, Integer> entry : oppositeCount.entrySet()) {
    
                if (!oppositeCount.get(entry.getKey()).equals(value) || appended.get(index) == 1) {
    
                    index++;
                    continue;
                }
                builder.append("\t").append(entry.getKey()).append(": ")
                        .append(" Number of encounters :").append(oppositeCount.get(entry.getKey())).append("\t")
                        .append(" Encounter frequency :").append(String.format("%.2f", 100 * entry.getValue() / (float) totalCount))
                        .append("%,\n");
                appended.set(index, 1);
                index++;
            }
        }

        int lastSplitterIndex = builder.lastIndexOf(",\n");
        if (lastSplitterIndex != -1) {
    
            builder.delete(lastSplitterIndex, lastSplitterIndex + ",\n".length() - 1);
        }
        builder.append("}");

        return builder.toString();
    }

After the experiment , We can clear the team data :

    /** *  Clear all cached data of the team  */
    public void clearAll() {
    
        oppositeCache = null;
        oppositeCount.clear();
        allPossibleOpposites.clear();
    }

The full code of the team class is shown below :

package com.szc.UEFAChampionLeague;

import java.util.*;

public class Team {
    
    private String name; //  Team name 
    private String country; //  The country of the team 
    private String group; //  Team group 
    private int rankInGroup; //  The team's ranking in the group 
    private boolean matched = false; //  Whether the team matches 
    private HashMap<String, Integer> oppositeCount = new HashMap<>(); //  Record opponents and encounters 
    private String oppositeCache = null; //  Opponent cache 
    private List<Team> allPossibleOpposites = new ArrayList<>(); //  All possible rivals 

    public String getName() {
    
        return name;
    }

    public Team setName(String name) {
    
        this.name = name;
        return this;
    }

    public String getCountry() {
    
        return country;
    }

    public Team setCountry(String country) {
    
        this.country = country;
        return this;
    }

    public String getGroup() {
    
        return group;
    }

    public Team setGroup(String group) {
    
        this.group = group;
        return this;
    }

    public int getRankInGroup() {
    
        return rankInGroup;
    }

    public Team setRankInGroup(int rankInGroup) {
    
        this.rankInGroup = rankInGroup;
        return this;
    }

    public boolean isMatched() {
    
        return matched;
    }

    public Team setMatched(boolean matched) {
    
        this.matched = matched;
        return this;
    }

    /** *  From all teams @allOpposites Select all possible opponents  * @param allOpposites  All teams  * @return this */
    public Team addAllPossibleOpposite(Team[] allOpposites) {
    
        for (Team opposite : allOpposites) {
    
            if (opposite.getCountry().equals(country) //  The same country avoids 
                    || opposite.getGroup().equals(group) //  Group avoidance 
                    || opposite.getRankInGroup() == rankInGroup /*  Avoid the same rank  */ ) {
    
                continue;
            }
            addPossibleOpposite(opposite);
        }
        return this;
    }

    /** *  From all teams @allOpposites Select all possible opponents  * @param allOpposites  All teams  * @return this */
    public Team addAllPossibleOpposite(List<Team> allOpposites) {
    
        for (Team opposite : allOpposites) {
    
            if (opposite.getCountry().equals(country) //  The same country avoids 
                    || opposite.getGroup().equals(group) //  Group avoidance 
                    || opposite.getRankInGroup() == rankInGroup /*  Avoid the same rank  */ ) {
    
                continue;
            }
            addPossibleOpposite(opposite);
        }
        return this;
    }

    /** *  Add your opponent to all your opponents  * @param opposite  Current competitor  */
    private void addPossibleOpposite(Team opposite) {
    
        if (!allPossibleOpposites.contains(opposite)) {
    
            allPossibleOpposites.add(opposite);
        }
    }

    /** *  Remove the opponent from all possible opponents of the team , At this time, the opponent may have finished pairing  * @param opposite  Current competitor  * @return this */
    public Team removePossibleOpposite(Team opposite) {
    
        allPossibleOpposites.remove(opposite);
        return this;
    }

    /** *  Judge @opposite Is it the only possible opponent of the team  * @param opposite  Current competitor  * @return true The current opponent is the only possible opponent of the team ,false It means not  */
    public boolean isOnlyPossibleOpposite(Team opposite) {
    
        return allPossibleOpposites.size() == 1 && allPossibleOpposites.contains(opposite);
    }

    /** *  Is there any other possible opponent for our team  * @return true It means that there are still possible competitors ,false Does not exist  */
    public boolean hasPossibleOpposites() {
    
        return !allPossibleOpposites.isEmpty();
    }

    /** *  This drawing of lots is completed , Our team cached their opponents @oppositeCache Add to map oppositeCount in , At the same time, the occurrence frequency of the opponent +1 */
    public void confirmOppositesCache() {
    
        if (!oppositeCount.containsKey(oppositeCache)) {
    
            oppositeCount.put(oppositeCache, 1);
        } else {
    
            oppositeCount.put(oppositeCache, oppositeCount.get(oppositeCache) + 1);
        }
    }

    /** *  Set opponent cache  * @param opposite  Current competitor  * @return this */
    public Team setOppositeCache(Team opposite) {
    
        String oppositeName = opposite.getName();
        if (!oppositeName.equals(oppositeCache)) {
    
            oppositeCache = oppositeName;
        }
        return this;
    }

    public String getOppositeCache() {
    
        return oppositeCache;
    }

    /** *  Reset opponent cache , There are two situations :1、 initialization , Start a new draw ;2、 A lottery attempt failed , It is necessary to restart this lottery  * @return this */
    public Team unsetOppositeCache() {
    
        oppositeCache = null;
        return this;
    }

    /** *  Clear all cached data of the team  */
    public void clearAll() {
    
        oppositeCache = null;
        oppositeCount.clear();
        allPossibleOpposites.clear();
    }

    /** *  Output all opponents of the team and their corresponding encounter frequency and frequency , Sort in ascending order according to the encounter frequency  * @return String  String to be displayed  */
    public String printOppositePossibilities() {
    
        StringBuilder builder = new StringBuilder();

        //  Will all the opponents appear , Sort by the number of encounters in descending order 
        Integer[] matchCountSorted = new Integer[oppositeCount.size()];
        int i = 0;
        int totalCount = 0;
        for (String opposite : oppositeCount.keySet()) {
    
            matchCountSorted[i] = oppositeCount.get(opposite);
            totalCount += matchCountSorted[i];
            i++;
        }

        Arrays.sort(matchCountSorted, Collections.reverseOrder());

        //  Whether a certain encounter frequency completes the output index list ,1 Indicates that all teams corresponding to this frequency have been output ,0 It indicates whether there is any team output for this frequency 
        List<Integer> appended = new ArrayList<Integer>();
        for (int j = 0; j < oppositeCount.size(); j++) {
    
            appended.add(0);
        }

        builder.append("{ \n");
        for (Integer value : matchCountSorted) {
    
            int index = 0;
            for (Map.Entry<String, Integer> entry : oppositeCount.entrySet()) {
    
                if (!oppositeCount.get(entry.getKey()).equals(value) || appended.get(index) == 1) {
    
                    index++;
                    continue;
                }
                builder.append("\t").append(entry.getKey()).append(": ")
                        .append(" Number of encounters :").append(oppositeCount.get(entry.getKey())).append("\t")
                        .append(" Encounter frequency :").append(String.format("%.2f", 100 * entry.getValue() / (float) totalCount))
                        .append("%,\n");
                appended.set(index, 1);
                index++;
            }
        }

        int lastSplitterIndex = builder.lastIndexOf(",\n");
        if (lastSplitterIndex != -1) {
    
            builder.delete(lastSplitterIndex, lastSplitterIndex + ",\n".length() - 1);
        }
        builder.append("}");

        return builder.toString();
    }

    @Override
    public boolean equals(Object o) {
    
        if (this == o) return true;
        if (!(o instanceof Team)) return false;
        Team team = (Team) o;
        return getRankInGroup() == team.getRankInGroup()
                && Objects.equals(getName(), team.getName())
                && Objects.equals(getCountry(), team.getCountry())
                && Objects.equals(getGroup(), team.getGroup());
    }

    @Override
    public int hashCode() {
    
        return Objects.hash(getName(), getCountry(), getGroup(), getRankInGroup());
    }

    @Override
    public String toString() {
    
        return "Team{" +
                "name='" + name + '\'' +
                ", country='" + country + '\'' +
                ", group='" + group + '\'' +
                ", rankInGroup=" + rankInGroup +
                '}';
    }
}

AgainstPlan class

First define the fields of the graph class , And implement the singleton :

    private HashMap<String, Integer> againstPlan = new HashMap<>(); //  Mapping against graphs and occurrences 
    private static volatile AgainstPlan sInstance;

    private AgainstPlan() {
    }

    public static AgainstPlan getsInstance() {
    
        if (sInstance == null) {
    
            synchronized (AgainstPlan.class) {
    
                if (sInstance == null) {
    
                    sInstance = new AgainstPlan();
                }
            }
        }
        return sInstance;
    }

then , After each round of drawing , We need to update the mapping according to the draw results of each team :

    /** *  Submit the results of a single draw for all teams , Form a match chart , Save to global cache mapping  * @param teams  The last 16 of the Champions League  */
    public void confirmDrawResult(Team[] teams) {
    
        if (teams == null || teams.length == 0) {
    
            return;
        }

        StringBuilder builder = new StringBuilder();

        for (Team team : teams) {
    
            if (team.getRankInGroup() != 2) {
    
                //  The second group is the host before the guest , So only for the second statistical match chart of the group , It also avoids repeated statistics 
                continue;
            }
            //  Match chart format :A vs B
            builder.append("\t\t").append(team.getName())
                    .append(" vs ")
                    .append(team.getOppositeCache())
                    .append("\n");
        }
        builder.deleteCharAt(builder.lastIndexOf("\n"));

        String currentAgainstPlan = builder.toString();

        //  Update the map with this map 
        if (!againstPlan.containsKey(currentAgainstPlan)) {
    
            againstPlan.put(currentAgainstPlan, 1);
        } else {
    
            againstPlan.put(currentAgainstPlan, againstPlan.get(currentAgainstPlan) + 1);
        }
    }

When all the draw is over , We also need to output the match chart , This is just an interception here :

    /** *  Before the number of output occurrences 20 The match situation , If the graph cache amount  <= 20, Then all match conditions are output  * @return  String of all match cases  */
    public String printAllAgainstPlan() {
    
        return printAllAgainstPlan(20);
    }

    /** *  Before the number of output occurrences topN The match situation , If the graph cache amount  <= topN, Then all match conditions are output  * @param topN  Before intercepting the number of occurrences topN name  * @return  String of all match cases  */
    public String printAllAgainstPlan(int topN) {
    
        StringBuilder builder = new StringBuilder();

        Integer[] matchCountSorted = new Integer[againstPlan.size()];
        int i = 0;
        int totalCount = 0;
        for (String opposite : againstPlan.keySet()) {
    
            matchCountSorted[i] = againstPlan.get(opposite);
            totalCount += matchCountSorted[i];
            i++;
        }

        Arrays.sort(matchCountSorted, Collections.reverseOrder());

        //  Of the match topN Intercept 
        Integer[] matchCountFiltered;
        if (matchCountSorted.length > topN) {
    
            matchCountFiltered = Arrays.copyOfRange(matchCountSorted, 0, topN);
        } else {
    
            matchCountFiltered = Arrays.copyOf(matchCountSorted, matchCountSorted.length);
        }

        List<Integer> appended = new ArrayList<Integer>();
        for (int j = 0; j < againstPlan.size(); j++) {
    
            appended.add(0);
        }

        builder.append("{ \n");
        for (Integer value : matchCountFiltered) {
    
            int index = 0;
            for (Map.Entry<String, Integer> entry : againstPlan.entrySet()) {
    
                if (!againstPlan.get(entry.getKey()).equals(value) || appended.get(index) == 1) {
    
                    index++;
                    continue;
                }
                builder.append("\t").append(" Match situation : {\n")
                        .append(entry.getKey())
                        .append("\n\n\t\t Number of occurrences :").append(entry.getValue())
                        .append("\n\t\t Probability of occurrence :").append(String.format("%.2f", 100 * entry.getValue() / (float) totalCount))
                        .append("%\n\t},\n");
                appended.set(index, 1);
                index++;
            }
        }

        int lastSplitterIndex = builder.lastIndexOf(",\n");
        if (lastSplitterIndex != -1) {
    
            builder.delete(lastSplitterIndex, lastSplitterIndex + ",\n".length() - 1);
        }
        builder.append("}");

        return builder.toString();
    }

The entire code for the graph class is as follows :

package com.szc.UEFAChampionLeague;

import java.util.*;

public class AgainstPlan {
    
    private HashMap<String, Integer> againstPlan = new HashMap<>(); //  Mapping against graphs and occurrences 
    private static volatile AgainstPlan sInstance;

    private AgainstPlan() {
    }

    public static AgainstPlan getsInstance() {
    
        if (sInstance == null) {
    
            synchronized (AgainstPlan.class) {
    
                if (sInstance == null) {
    
                    sInstance = new AgainstPlan();
                }
            }
        }
        return sInstance;
    }

    /** *  Submit the results of a single draw for all teams , Form a match chart , Save to global cache mapping  * @param teams  The last 16 of the Champions League  */
    public void confirmDrawResult(Team[] teams) {
    
        if (teams == null || teams.length == 0) {
    
            return;
        }

        StringBuilder builder = new StringBuilder();

        for (Team team : teams) {
    
            if (team.getRankInGroup() != 2) {
    
                //  The second group is the host before the guest , So only for the second statistical match chart of the group , It also avoids repeated statistics 
                continue;
            }
            //  Match chart format :A vs B
            builder.append("\t\t").append(team.getName())
                    .append(" vs ")
                    .append(team.getOppositeCache())
                    .append("\n");
        }
        builder.deleteCharAt(builder.lastIndexOf("\n"));

        String currentAgainstPlan = builder.toString();

        //  Update the map with this map 
        if (!againstPlan.containsKey(currentAgainstPlan)) {
    
            againstPlan.put(currentAgainstPlan, 1);
        } else {
    
            againstPlan.put(currentAgainstPlan, againstPlan.get(currentAgainstPlan) + 1);
        }
    }

    /** *  Before the number of output occurrences 20 The match situation , If the graph cache amount  <= 20, Then all match conditions are output  * @return  String of all match cases  */
    public String printAllAgainstPlan() {
    
        return printAllAgainstPlan(20);
    }

    /** *  Before the number of output occurrences topN The match situation , If the graph cache amount  <= topN, Then all match conditions are output  * @param topN  Before intercepting the number of occurrences topN name  * @return  String of all match cases  */
    public String printAllAgainstPlan(int topN) {
    
        StringBuilder builder = new StringBuilder();

        Integer[] matchCountSorted = new Integer[againstPlan.size()];
        int i = 0;
        int totalCount = 0;
        for (String opposite : againstPlan.keySet()) {
    
            matchCountSorted[i] = againstPlan.get(opposite);
            totalCount += matchCountSorted[i];
            i++;
        }

        Arrays.sort(matchCountSorted, Collections.reverseOrder());

        //  Of the match topN Intercept 
        Integer[] matchCountFiltered;
        if (matchCountSorted.length > topN) {
    
            matchCountFiltered = Arrays.copyOfRange(matchCountSorted, 0, topN);
        } else {
    
            matchCountFiltered = Arrays.copyOf(matchCountSorted, matchCountSorted.length);
        }

        List<Integer> appended = new ArrayList<Integer>();
        for (int j = 0; j < againstPlan.size(); j++) {
    
            appended.add(0);
        }

        builder.append("{ \n");
        for (Integer value : matchCountFiltered) {
    
            int index = 0;
            for (Map.Entry<String, Integer> entry : againstPlan.entrySet()) {
    
                if (!againstPlan.get(entry.getKey()).equals(value) || appended.get(index) == 1) {
    
                    index++;
                    continue;
                }
                builder.append("\t").append(" Match situation : {\n")
                        .append(entry.getKey())
                        .append("\n\n\t\t Number of occurrences :").append(entry.getValue())
                        .append("\n\t\t Probability of occurrence :").append(String.format("%.2f", 100 * entry.getValue() / (float) totalCount))
                        .append("%\n\t},\n");
                appended.set(index, 1);
                index++;
            }
        }

        int lastSplitterIndex = builder.lastIndexOf(",\n");
        if (lastSplitterIndex != -1) {
    
            builder.delete(lastSplitterIndex, lastSplitterIndex + ",\n".length() - 1);
        }
        builder.append("}");

        return builder.toString();
    }
}

Matcher class

First , We will draw a lot for the last 16 of the Champions League :

    /** *  Draw simulated lots for all top 16 teams  * @param teams  All the top 16 teams  */
    public static void match(Team[] teams) {
    
        Random random = new Random();
        List<Team> unmatchedTeams = new ArrayList<>();
        unmatchedTeams.addAll(Arrays.asList(teams));

        for (Team unmatchedTeam : unmatchedTeams) {
    
            if (!unmatchedTeam.hasPossibleOpposites()) {
    
                return;
            }
        }

        while (!unmatchedTeams.isEmpty()) {
    
            int firstIndex = random.nextInt(unmatchedTeams.size());
            //  Draw the first team 
            Team firstRank = unmatchedTeams.get(firstIndex);

            int secondIndex = random.nextInt(unmatchedTeams.size());
            //  Draw the second team 
            Team secondRank = unmatchedTeams.get(secondIndex);

            if (canMatch(firstRank, secondRank, unmatchedTeams)) {
    
                //  If the two teams can complete the match , And the rest of the teams can be paired , Then complete the pairing 
                unmatchedTeams.remove(firstRank);
                unmatchedTeams.remove(secondRank);

                firstRank.setOppositeCache(secondRank).setMatched(true);
                secondRank.setOppositeCache(firstRank).setMatched(true);

                for (Team team : unmatchedTeams) {
    
                    team.removePossibleOpposite(firstRank).removePossibleOpposite(secondRank);
                }
            } else {
    
                //  Whether the remaining unmatched teams have potential opponents 
                boolean restNotMatch = false;
                for (Team unmatchedTeam : unmatchedTeams) {
    
                    if (!unmatchedTeam.hasPossibleOpposites()) {
    
                        restNotMatch = true;
                    }
                }

                if (restNotMatch ||
                        (unmatchedTeams.isEmpty() && !canSimpleMatch(firstRank, secondRank))) {
    
                    //  The remaining unmatched teams cannot complete the pairing , Or the two remaining teams , Can't pair .
                    //  In this case , Start the drawing again 
                    unmatchedTeams.clear();
                    unmatchedTeams.addAll(Arrays.asList(teams));
                    resetMatchFlag(unmatchedTeams);
                }
            }
        }

        for (Team team : teams) {
    
            //  This drawing of lots is completed , All teams will submit the results of the draw to 
            team.confirmOppositesCache();
        }

        //  Submit the drawing of this draw 
        AgainstPlan.getsInstance().confirmDrawResult(teams);
    }

First , Add all sixteen teams to the unmatched team list unmatchedTeams in , After a simple opponent non empty check for each team , We started this round of simulated lottery .
In each iteration of the current draw , Do a few things :
1、 Two teams randomly selected from the unmatched teams ( It may be the same ), Judge whether the two teams can complete the match , And whether other teams can match after matching ( That is, there are potential rivals );
2、 If it matches , Delete the two teams from the unmatched team 、 Set their opponents in the first round of knockout as opponents 、 Set the status of the two teams to matched 、 Remove both teams from the list of possible opponents of other unmatched teams ;
3、 If it doesn't match , There are two situations :1)、 The two teams drawn are not suitable , But there are other possibilities ;2)、 Of all unmatched teams , There are teams without potential rivals , Or maybe these are the only two teams left . If it's the case 1, Then we'll do it again 1-2 Just draw lots ; If it's the case 2, It is considered that this round of lottery has failed , Go ahead 4 Step .
4、 Restart this round of drawing , That is, reset the unmatched team list with 16 teams , And reset the matching status of all teams .
repeat 1-4 Iteration of steps , Until the unmatched team list is empty , Then this round of drawing of lots is over . After this round of drawing of lots , Submit the draw results to each team , And submit the drawing of the draw .
In the first step of the above iteration “ Judge whether the two teams can complete the match , And whether other teams can match after matching ”, The corresponding method is canMatch(), As shown below

    /** *  Whether the two teams can match up , And whether the remaining teams can complete the pairing  * @param firstTeam  The first team  * @param secondTeam  The second team  * @param allTeams  All teams  * @return true Can be paired ,false Indicates that pairing is not possible  */
    public static boolean canMatch(Team firstTeam, Team secondTeam, List<Team> allTeams) {
    
        if (!canSimpleMatch(firstTeam, secondTeam)) {
    
            //  The two teams can't match , Go straight back to false
            return false;
        }

        allTeams.remove(firstTeam);
        allTeams.remove(secondTeam);

        if (allTeams.isEmpty()) {
    
            //  There are no teams left , And the two teams can match , Description match complete 
            return true;
        }

        //  Of the remaining unmatched teams , If a team has no possible opponents , Then the matching fails 
        boolean hasNoPossibilities = false;
        for (Team otherTeam : allTeams) {
    
           if (!otherTeam.isMatched() && !otherTeam.hasPossibleOpposites()
                   && !otherTeam.isOnlyPossibleOpposite(firstTeam)
                   && !otherTeam.isOnlyPossibleOpposite(secondTeam)) {
    
               hasNoPossibilities = true;
               break;
           }
        }

        return !hasNoPossibilities;
    }

canMatch() Judge the current status , The conditions under which two teams can match are :
1、 No other team , And the two teams can match each other ;
2、 There are other teams , And the two teams can match each other , At the same time, other teams have potential opponents besides the current two teams to be matched
The method responsible for judging whether the two teams can match individually is canSimpleMatch():

    /** *  Can the two teams complete the match  * @param firstTeam  The first team  * @param secondTeam  The second team  * @return true It means that two teams can match ,false It means that the two teams cannot match  */
    public static boolean canSimpleMatch(Team firstTeam, Team secondTeam) {
    
        if (firstTeam == secondTeam) {
    
            //  The same team , Avoid directly 
            return false;
        }

        if (firstTeam.isMatched() || secondTeam.isMatched()) {
    
            //  A team has been paired , Avoid immediately 
            return false;
        }

        if (firstTeam.getRankInGroup() == secondTeam.getRankInGroup()) {
    
            //  Only seeded and unseeded teams can be paired 
            return false;
        }

        if (firstTeam.getGroup().equals(secondTeam.getGroup())) {
    
            //  Group avoidance 
            return false;
        }

        //  The same country avoids 
        return !firstTeam.getCountry().equals(secondTeam.getCountry());
    }

If this round of drawing fails , Or you need to start the next independent lottery , You need to reset the draw status of the top 16 and the current opponent :

    /** *  Reset the match of all teams  * @param teams  All teams  */
    public static void resetMatchFlag(Team[] teams) {
    
        for (Team team : teams) {
    
            team.setMatched(false).addAllPossibleOpposite(teams).unsetOppositeCache();
        }
    }

    /** *  Reset the match of all teams  * @param teams  All teams  */
    public static void resetMatchFlag(List<Team> teams) {
    
        for (Team team : teams) {
    
            team.setMatched(false).addAllPossibleOpposite(teams).unsetOppositeCache();
        }
    }

The full code of the lottery class is as follows :

package com.szc.UEFAChampionLeague;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Random;

public class Matcher {
    
    /** *  Draw simulated lots for all top 16 teams  * @param teams  All the top 16 teams  */
    public static void match(Team[] teams) {
    
        Random random = new Random();
        List<Team> unmatchedTeams = new ArrayList<>();
        unmatchedTeams.addAll(Arrays.asList(teams));

        for (Team unmatchedTeam : unmatchedTeams) {
    
            if (!unmatchedTeam.hasPossibleOpposites()) {
    
                return;
            }
        }

        while (!unmatchedTeams.isEmpty()) {
    
            int firstIndex = random.nextInt(unmatchedTeams.size());
            //  Draw the first team 
            Team firstRank = unmatchedTeams.get(firstIndex);

            int secondIndex = random.nextInt(unmatchedTeams.size());
            //  Draw the second team 
            Team secondRank = unmatchedTeams.get(secondIndex);

            if (canMatch(firstRank, secondRank, unmatchedTeams)) {
    
                //  If the two teams can complete the match , And the rest of the teams can be paired , Then complete the pairing 
                unmatchedTeams.remove(firstRank);
                unmatchedTeams.remove(secondRank);

                firstRank.setOppositeCache(secondRank).setMatched(true);
                secondRank.setOppositeCache(firstRank).setMatched(true);

                for (Team team : unmatchedTeams) {
    
                    team.removePossibleOpposite(firstRank).removePossibleOpposite(secondRank);
                }
            } else {
    
                //  Whether the remaining unmatched teams have potential opponents 
                boolean restNotMatch = false;
                for (Team unmatchedTeam : unmatchedTeams) {
    
                    if (!unmatchedTeam.hasPossibleOpposites()) {
    
                        restNotMatch = true;
                    }
                }

                if (restNotMatch ||
                        (unmatchedTeams.isEmpty() && !canSimpleMatch(firstRank, secondRank))) {
    
                    //  The remaining unmatched teams cannot complete the pairing , Or the two remaining teams , Can't pair .
                    //  In this case , Start the drawing again 
                    unmatchedTeams.clear();
                    unmatchedTeams.addAll(Arrays.asList(teams));
                    resetMatchFlag(unmatchedTeams);
                }
            }
        }

        for (Team team : teams) {
    
            //  This drawing of lots is completed , All teams will submit the results of the draw to 
            team.confirmOppositesCache();
        }

        //  Submit the drawing of this draw 
        AgainstPlan.getsInstance().confirmDrawResult(teams);
    }

    /** *  Reset the match of all teams  * @param teams  All teams  */
    public static void resetMatchFlag(Team[] teams) {
    
        for (Team team : teams) {
    
            team.setMatched(false).addAllPossibleOpposite(teams).unsetOppositeCache();
        }
    }

    /** *  Reset the match of all teams  * @param teams  All teams  */
    public static void resetMatchFlag(List<Team> teams) {
    
        for (Team team : teams) {
    
            team.setMatched(false).addAllPossibleOpposite(teams).unsetOppositeCache();
        }
    }

    /** *  Can the two teams complete the match  * @param firstTeam  The first team  * @param secondTeam  The second team  * @return true It means that two teams can match ,false It means that the two teams cannot match  */
    public static boolean canSimpleMatch(Team firstTeam, Team secondTeam) {
    
        if (firstTeam == secondTeam) {
    
            //  The same team , Avoid directly 
            return false;
        }

        if (firstTeam.isMatched() || secondTeam.isMatched()) {
    
            //  A team has been paired , Avoid immediately 
            return false;
        }

        if (firstTeam.getRankInGroup() == secondTeam.getRankInGroup()) {
    
            //  Only seeded and unseeded teams can be paired 
            return false;
        }

        if (firstTeam.getGroup().equals(secondTeam.getGroup())) {
    
            //  Group avoidance 
            return false;
        }

        //  The same country avoids 
        return !firstTeam.getCountry().equals(secondTeam.getCountry());
    }

    /** *  Whether the two teams can match up , And whether the remaining teams can complete the pairing  * @param firstTeam  The first team  * @param secondTeam  The second team  * @param allTeams  All teams  * @return true Can be paired ,false Indicates that pairing is not possible  */
    public static boolean canMatch(Team firstTeam, Team secondTeam, List<Team> allTeams) {
    
        if (!canSimpleMatch(firstTeam, secondTeam)) {
    
            //  The two teams can't match , Go straight back to false
            return false;
        }

        allTeams.remove(firstTeam);
        allTeams.remove(secondTeam);

        if (allTeams.isEmpty()) {
    
            //  There are no teams left , And the two teams can match , Description match complete 
            return true;
        }

        //  Of the remaining unmatched teams , If a team has no possible opponents , Then the matching fails 
        boolean hasNoPossibilities = false;
        for (Team otherTeam : allTeams) {
    
           if (!otherTeam.isMatched() && !otherTeam.hasPossibleOpposites()
                   && !otherTeam.isOnlyPossibleOpposite(firstTeam)
                   && !otherTeam.isOnlyPossibleOpposite(secondTeam)) {
    
               hasNoPossibilities = true;
               break;
           }
        }

        return !hasNoPossibilities;
    }
}

UEFAChampionLeagueDraw class

This class is the entry class , Responsible for three things :
1、 Initialize the top 16 data ;
2、 start-up 3000 An independent draw ;
3、 Output statistics .
Initialize the top 16 data , Is to input the name and other basic information for the top 16 :

        Team[] teams = new Team[16];

        teams[0] = setTeam(" Manchester city ", "England", "A", 1);
        teams[1] = setTeam(" Paris Saint Germain ", "France", "A", 2);
        teams[2] = setTeam(" Liverpool ", "England", "B", 1);
        teams[3] = setTeam(" Atletico Madrid ", "Spain", "B", 2);
        teams[4] = setTeam(" Ajax ", "Netherlands", "C", 1);
        teams[5] = setTeam(" Portuguese Sports ", "Portugal", "C", 2);
        teams[6] = setTeam(" Real Madrid ", "Spain", "D", 1);
        teams[7] = setTeam(" International Milan ", "Italy", "D", 2);
        teams[8] = setTeam(" Bayern Munich ", "Germany", "E", 1);
        teams[9] = setTeam(" Benfica ", "Portugal", "E", 2);
        teams[10] = setTeam(" Manchester united ", "England", "F", 1);
        teams[11] = setTeam(" Villarreal ", "Spain", "F", 2);
        teams[12] = setTeam(" Lille ", "France", "G", 1);
        teams[13] = setTeam(" Salzburg Red Bull ", "Austria", "G", 2);
        teams[14] = setTeam(" Juventus ", "Italy", "H", 1);
        teams[15] = setTeam(" Chelsea ", "England", "H", 2);

setTeam() It is a layer of encapsulation for team information initialization :

    /** *  Initialize a team's information , And return the team to  * @param name  Team name  * @param country  The country of the team  * @param group  Team group  * @param rankInGroup  Rank within the team group  * @return  Team object  */
    public static Team setTeam(String name, String country, String group, int rankInGroup) {
    
        Team team = new Team();
        team.setName(name)
                .setCountry(country)
                .setGroup(group)
                .setRankInGroup(rankInGroup);
        return team;
    }

then , Conduct a lottery experiment , And output the result :

    /** *  Draw lots for the top 16 of the Champions League  * @param teams  The last 16 of the Champions League  */
    private static void drawMatches(Team[] teams) {
    
        Matcher.resetMatchFlag(teams);
        for (int i = 0; i < 3000; i++) {
    
            //  Start 3000 An independent draw 
            Matcher.match(teams);
            Matcher.resetMatchFlag(teams);
        }

        for (Team team : teams) {
    
            System.out.println(team.getName() + ": " + team.printOppositePossibilities());
            team.clearAll();
        }

        System.out.println(AgainstPlan.getsInstance().printAllAgainstPlan());
    }

UEFAChampionLeagueDraw The full code of the class is as follows :

package com.szc.UEFAChampionLeague;

public class UEFAChampionLeagueDraw {
    
    public static void main(String[] args) {
    
        Team[] teams = new Team[16];

        teams[0] = setTeam(" Manchester city ", "England", "A", 1);
        teams[1] = setTeam(" Paris Saint Germain ", "France", "A", 2);
        teams[2] = setTeam(" Liverpool ", "England", "B", 1);
        teams[3] = setTeam(" Atletico Madrid ", "Spain", "B", 2);
        teams[4] = setTeam(" Ajax ", "Netherlands", "C", 1);
        teams[5] = setTeam(" Portuguese Sports ", "Portugal", "C", 2);
        teams[6] = setTeam(" Real Madrid ", "Spain", "D", 1);
        teams[7] = setTeam(" International Milan ", "Italy", "D", 2);
        teams[8] = setTeam(" Bayern Munich ", "Germany", "E", 1);
        teams[9] = setTeam(" Benfica ", "Portugal", "E", 2);
        teams[10] = setTeam(" Manchester united ", "England", "F", 1);
        teams[11] = setTeam(" Villarreal ", "Spain", "F", 2);
        teams[12] = setTeam(" Lille ", "France", "G", 1);
        teams[13] = setTeam(" Salzburg Red Bull ", "Austria", "G", 2);
        teams[14] = setTeam(" Juventus ", "Italy", "H", 1);
        teams[15] = setTeam(" Chelsea ", "England", "H", 2);

        drawMatches(teams);
    }

    /** *  Draw lots for the top 16 of the Champions League  * @param teams  The last 16 of the Champions League  */
    private static void drawMatches(Team[] teams) {
    
        Matcher.resetMatchFlag(teams);
        for (int i = 0; i < 3000; i++) {
    
            //  Start 3000 An independent draw 
            Matcher.match(teams);
            Matcher.resetMatchFlag(teams);
        }

        for (Team team : teams) {
    
            System.out.println(team.getName() + ": " + team.printOppositePossibilities());
            team.clearAll();
        }

        System.out.println(AgainstPlan.getsInstance().printAllAgainstPlan());
    }

    /** *  Initialize a team's information , And return the team to  * @param name  Team name  * @param country  The country of the team  * @param group  Team group  * @param rankInGroup  Rank within the team group  * @return  Team object  */
    public static Team setTeam(String name, String country, String group, int rankInGroup) {
    
        Team team = new Team();
        team.setName(name)
                .setCountry(country)
                .setGroup(group)
                .setRankInGroup(rankInGroup);
        return team;
    }
}

Running results

The output results of a certain operation are as follows :

 Manchester city : {
     
	 International Milan :  Number of encounters :575	 Encounter frequency :19.17%,
	 Atletico Madrid :  Number of encounters :550	 Encounter frequency :18.33%,
	 Villarreal :  Number of encounters :548	 Encounter frequency :18.27%,
	 Salzburg Red Bull :  Number of encounters :449	 Encounter frequency :14.97%,
	 Portuguese Sports :  Number of encounters :440	 Encounter frequency :14.67%,
	 Benfica :  Number of encounters :438	 Encounter frequency :14.60%
}
 Paris Saint Germain : {
     
	 Real Madrid :  Number of encounters :570	 Encounter frequency :19.00%,
	 Liverpool :  Number of encounters :541	 Encounter frequency :18.03%,
	 Juventus :  Number of encounters :534	 Encounter frequency :17.80%,
	 Manchester united :  Number of encounters :525	 Encounter frequency :17.50%,
	 Ajax :  Number of encounters :433	 Encounter frequency :14.43%,
	 Bayern Munich :  Number of encounters :397	 Encounter frequency :13.23%
}
 Liverpool : {
     
	 Villarreal :  Number of encounters :593	 Encounter frequency :19.77%,
	 Paris Saint Germain :  Number of encounters :541	 Encounter frequency :18.03%,
	 International Milan :  Number of encounters :531	 Encounter frequency :17.70%,
	 Benfica :  Number of encounters :448	 Encounter frequency :14.93%,
	 Salzburg Red Bull :  Number of encounters :447	 Encounter frequency :14.90%,
	 Portuguese Sports :  Number of encounters :440	 Encounter frequency :14.67%
}
 Atletico Madrid : {
     
	 Manchester city :  Number of encounters :550	 Encounter frequency :18.33%,
	 Manchester united :  Number of encounters :549	 Encounter frequency :18.30%,
	 Lille :  Number of encounters :527	 Encounter frequency :17.57%,
	 Juventus :  Number of encounters :526	 Encounter frequency :17.53%,
	 Ajax :  Number of encounters :445	 Encounter frequency :14.83%,
	 Bayern Munich :  Number of encounters :403	 Encounter frequency :13.43%
}
 Ajax : {
     
	 Chelsea :  Number of encounters :655	 Encounter frequency :21.83%,
	 Atletico Madrid :  Number of encounters :445	 Encounter frequency :14.83%,
	 Paris Saint Germain :  Number of encounters :433	 Encounter frequency :14.43%,
	 International Milan :  Number of encounters :393	 Encounter frequency :13.10%,
	 Villarreal :  Number of encounters :378	 Encounter frequency :12.60%,
	 Benfica :  Number of encounters :357	 Encounter frequency :11.90%,
	 Salzburg Red Bull :  Number of encounters :339	 Encounter frequency :11.30%
}
 Portuguese Sports : {
     
	 Juventus :  Number of encounters :462	 Encounter frequency :15.40%,
	 Manchester united :  Number of encounters :456	 Encounter frequency :15.20%,
	 Real Madrid :  Number of encounters :456	 Encounter frequency :15.20%,
	 Liverpool :  Number of encounters :440	 Encounter frequency :14.67%,
	 Manchester city :  Number of encounters :440	 Encounter frequency :14.67%,
	 Lille :  Number of encounters :389	 Encounter frequency :12.97%,
	 Bayern Munich :  Number of encounters :357	 Encounter frequency :11.90%
}
 Real Madrid : {
     
	 Chelsea :  Number of encounters :1023	 Encounter frequency :34.10%,
	 Paris Saint Germain :  Number of encounters :570	 Encounter frequency :19.00%,
	 Salzburg Red Bull :  Number of encounters :489	 Encounter frequency :16.30%,
	 Benfica :  Number of encounters :462	 Encounter frequency :15.40%,
	 Portuguese Sports :  Number of encounters :456	 Encounter frequency :15.20%
}
 International Milan : {
     
	 Manchester united :  Number of encounters :576	 Encounter frequency :19.20%,
	 Manchester city :  Number of encounters :575	 Encounter frequency :19.17%,
	 Liverpool :  Number of encounters :531	 Encounter frequency :17.70%,
	 Lille :  Number of encounters :472	 Encounter frequency :15.73%,
	 Bayern Munich :  Number of encounters :453	 Encounter frequency :15.10%,
	 Ajax :  Number of encounters :393	 Encounter frequency :13.10%
}
 Bayern Munich : {
     
	 Chelsea :  Number of encounters :606	 Encounter frequency :20.20%,
	 International Milan :  Number of encounters :453	 Encounter frequency :15.10%,
	 Villarreal :  Number of encounters :414	 Encounter frequency :13.80%,
	 Atletico Madrid :  Number of encounters :403	 Encounter frequency :13.43%,
	 Paris Saint Germain :  Number of encounters :397	 Encounter frequency :13.23%,
	 Salzburg Red Bull :  Number of encounters :370	 Encounter frequency :12.33%,
	 Portuguese Sports :  Number of encounters :357	 Encounter frequency :11.90%
}
 Benfica : {
     
	 Real Madrid :  Number of encounters :462	 Encounter frequency :15.40%,
	 Manchester united :  Number of encounters :449	 Encounter frequency :14.97%,
	 Liverpool :  Number of encounters :448	 Encounter frequency :14.93%,
	 Juventus :  Number of encounters :443	 Encounter frequency :14.77%,
	 Manchester city :  Number of encounters :438	 Encounter frequency :14.60%,
	 Lille :  Number of encounters :403	 Encounter frequency :13.43%,
	 Ajax :  Number of encounters :357	 Encounter frequency :11.90%
}
 Manchester united : {
     
	 International Milan :  Number of encounters :576	 Encounter frequency :19.20%,
	 Atletico Madrid :  Number of encounters :549	 Encounter frequency :18.30%,
	 Paris Saint Germain :  Number of encounters :525	 Encounter frequency :17.50%,
	 Portuguese Sports :  Number of encounters :456	 Encounter frequency :15.20%,
	 Benfica :  Number of encounters :449	 Encounter frequency :14.97%,
	 Salzburg Red Bull :  Number of encounters :445	 Encounter frequency :14.83%
}
 Villarreal : {
     
	 Liverpool :  Number of encounters :593	 Encounter frequency :19.77%,
	 Juventus :  Number of encounters :574	 Encounter frequency :19.13%,
	 Manchester city :  Number of encounters :548	 Encounter frequency :18.27%,
	 Lille :  Number of encounters :493	 Encounter frequency :16.43%,
	 Bayern Munich :  Number of encounters :414	 Encounter frequency :13.80%,
	 Ajax :  Number of encounters :378	 Encounter frequency :12.60%
}
 Lille : {
     
	 Chelsea :  Number of encounters :716	 Encounter frequency :23.87%,
	 Atletico Madrid :  Number of encounters :527	 Encounter frequency :17.57%,
	 Villarreal :  Number of encounters :493	 Encounter frequency :16.43%,
	 International Milan :  Number of encounters :472	 Encounter frequency :15.73%,
	 Benfica :  Number of encounters :403	 Encounter frequency :13.43%,
	 Portuguese Sports :  Number of encounters :389	 Encounter frequency :12.97%
}
 Salzburg Red Bull : {
     
	 Real Madrid :  Number of encounters :489	 Encounter frequency :16.30%,
	 Juventus :  Number of encounters :461	 Encounter frequency :15.37%,
	 Manchester city :  Number of encounters :449	 Encounter frequency :14.97%,
	 Liverpool :  Number of encounters :447	 Encounter frequency :14.90%,
	 Manchester united :  Number of encounters :445	 Encounter frequency :14.83%,
	 Bayern Munich :  Number of encounters :370	 Encounter frequency :12.33%,
	 Ajax :  Number of encounters :339	 Encounter frequency :11.30%
}
 Juventus : {
     
	 Villarreal :  Number of encounters :574	 Encounter frequency :19.13%,
	 Paris Saint Germain :  Number of encounters :534	 Encounter frequency :17.80%,
	 Atletico Madrid :  Number of encounters :526	 Encounter frequency :17.53%,
	 Portuguese Sports :  Number of encounters :462	 Encounter frequency :15.40%,
	 Salzburg Red Bull :  Number of encounters :461	 Encounter frequency :15.37%,
	 Benfica :  Number of encounters :443	 Encounter frequency :14.77%
}
 Chelsea : {
     
	 Real Madrid :  Number of encounters :1023	 Encounter frequency :34.10%,
	 Lille :  Number of encounters :716	 Encounter frequency :23.87%,
	 Ajax :  Number of encounters :655	 Encounter frequency :21.83%,
	 Bayern Munich :  Number of encounters :606	 Encounter frequency :20.20%
}
{
     
	 Match situation : {
    
		 Paris Saint Germain  vs  Bayern Munich 
		 Atletico Madrid  vs  Lille 
		 Portuguese Sports  vs  Manchester united 
		 International Milan  vs  Ajax 
		 Benfica  vs  Manchester city 
		 Villarreal  vs  Liverpool 
		 Salzburg Red Bull  vs  Juventus 
		 Chelsea  vs  Real Madrid 

		 Number of occurrences :5
		 Probability of occurrence :0.17%
	},
	 Match situation : {
    
		 Paris Saint Germain  vs  Bayern Munich 
		 Atletico Madrid  vs  Ajax 
		 Portuguese Sports  vs  Juventus 
		 International Milan  vs  Lille 
		 Benfica  vs  Manchester united 
		 Villarreal  vs  Liverpool 
		 Salzburg Red Bull  vs  Manchester city 
		 Chelsea  vs  Real Madrid 

		 Number of occurrences :5
		 Probability of occurrence :0.17%
	},
	 Match situation : {
    
		 Paris Saint Germain  vs  Juventus 
		 Atletico Madrid  vs  Manchester united 
		 Portuguese Sports  vs  Manchester city 
		 International Milan  vs  Liverpool 
		 Benfica  vs  Lille 
		 Villarreal  vs  Ajax 
		 Salzburg Red Bull  vs  Bayern Munich 
		 Chelsea  vs  Real Madrid 

		 Number of occurrences :5
		 Probability of occurrence :0.17%
	},
	 Match situation : {
    
		 Paris Saint Germain  vs  Juventus 
		 Atletico Madrid  vs  Bayern Munich 
		 Portuguese Sports  vs  Manchester united 
		 International Milan  vs  Ajax 
		 Benfica  vs  Liverpool 
		 Villarreal  vs  Manchester city 
		 Salzburg Red Bull  vs  Real Madrid 
		 Chelsea  vs  Lille 

		 Number of occurrences :4
		 Probability of occurrence :0.13%
	},
	 Match situation : {
    
		 Paris Saint Germain  vs  Juventus 
		 Atletico Madrid  vs  Bayern Munich 
		 Portuguese Sports  vs  Liverpool 
		 International Milan  vs  Manchester city 
		 Benfica  vs  Real Madrid 
		 Villarreal  vs  Ajax 
		 Salzburg Red Bull  vs  Manchester united 
		 Chelsea  vs  Lille 

		 Number of occurrences :4
		 Probability of occurrence :0.13%
	},
	 Match situation : {
    
		 Paris Saint Germain  vs  Real Madrid 
		 Atletico Madrid  vs  Bayern Munich 
		 Portuguese Sports  vs  Liverpool 
		 International Milan  vs  Ajax 
		 Benfica  vs  Manchester city 
		 Villarreal  vs  Juventus 
		 Salzburg Red Bull  vs  Manchester united 
		 Chelsea  vs  Lille 

		 Number of occurrences :4
		 Probability of occurrence :0.13%
	},
	 Match situation : {
    
		 Paris Saint Germain  vs  Juventus 
		 Atletico Madrid  vs  Lille 
		 Portuguese Sports  vs  Liverpool 
		 International Milan  vs  Bayern Munich 
		 Benfica  vs  Real Madrid 
		 Villarreal  vs  Manchester city 
		 Salzburg Red Bull  vs  Manchester united 
		 Chelsea  vs  Ajax 

		 Number of occurrences :4
		 Probability of occurrence :0.13%
	},
	 Match situation : {
    
		 Paris Saint Germain  vs  Manchester united 
		 Atletico Madrid  vs  Juventus 
		 Portuguese Sports  vs  Liverpool 
		 International Milan  vs  Ajax 
		 Benfica  vs  Manchester city 
		 Villarreal  vs  Lille 
		 Salzburg Red Bull  vs  Bayern Munich 
		 Chelsea  vs  Real Madrid 

		 Number of occurrences :4
		 Probability of occurrence :0.13%
	},
	 Match situation : {
    
		 Paris Saint Germain  vs  Juventus 
		 Atletico Madrid  vs  Manchester united 
		 Portuguese Sports  vs  Manchester city 
		 International Milan  vs  Ajax 
		 Benfica  vs  Lille 
		 Villarreal  vs  Liverpool 
		 Salzburg Red Bull  vs  Bayern Munich 
		 Chelsea  vs  Real Madrid 

		 Number of occurrences :4
		 Probability of occurrence :0.13%
	},
	 Match situation : {
    
		 Paris Saint Germain  vs  Manchester united 
		 Atletico Madrid  vs  Ajax 
		 Portuguese Sports  vs  Liverpool 
		 International Milan  vs  Lille 
		 Benfica  vs  Juventus 
		 Villarreal  vs  Manchester city 
		 Salzburg Red Bull  vs  Real Madrid 
		 Chelsea  vs  Bayern Munich 

		 Number of occurrences :4
		 Probability of occurrence :0.13%
	},
	 Match situation : {
    
		 Paris Saint Germain  vs  Real Madrid 
		 Atletico Madrid  vs  Manchester city 
		 Portuguese Sports  vs  Juventus 
		 International Milan  vs  Manchester united 
		 Benfica  vs  Lille 
		 Villarreal  vs  Liverpool 
		 Salzburg Red Bull  vs  Ajax 
		 Chelsea  vs  Bayern Munich 

		 Number of occurrences :4
		 Probability of occurrence :0.13%
	},
	 Match situation : {
    
		 Paris Saint Germain  vs  Real Madrid 
		 Atletico Madrid  vs  Bayern Munich 
		 Portuguese Sports  vs  Lille 
		 International Milan  vs  Manchester united 
		 Benfica  vs  Manchester city 
		 Villarreal  vs  Juventus 
		 Salzburg Red Bull  vs  Liverpool 
		 Chelsea  vs  Ajax 

		 Number of occurrences :4
		 Probability of occurrence :0.13%
	},
	 Match situation : {
    
		 Paris Saint Germain  vs  Liverpool 
		 Atletico Madrid  vs  Ajax 
		 Portuguese Sports  vs  Lille 
		 International Milan  vs  Bayern Munich 
		 Benfica  vs  Manchester city 
		 Villarreal  vs  Juventus 
		 Salzburg Red Bull  vs  Manchester united 
		 Chelsea  vs  Real Madrid 

		 Number of occurrences :4
		 Probability of occurrence :0.13%
	},
	 Match situation : {
    
		 Paris Saint Germain  vs  Liverpool 
		 Atletico Madrid  vs  Lille 
		 Portuguese Sports  vs  Juventus 
		 International Milan  vs  Bayern Munich 
		 Benfica  vs  Real Madrid 
		 Villarreal  vs  Manchester city 
		 Salzburg Red Bull  vs  Manchester united 
		 Chelsea  vs  Ajax 

		 Number of occurrences :4
		 Probability of occurrence :0.13%
	},
	 Match situation : {
    
		 Paris Saint Germain  vs  Liverpool 
		 Atletico Madrid  vs  Juventus 
		 Portuguese Sports  vs  Real Madrid 
		 International Milan  vs  Manchester city 
		 Benfica  vs  Manchester united 
		 Villarreal  vs  Bayern Munich 
		 Salzburg Red Bull  vs  Ajax 
		 Chelsea  vs  Lille 

		 Number of occurrences :4
		 Probability of occurrence :0.13%
	},
	 Match situation : {
    
		 Paris Saint Germain  vs  Real Madrid 
		 Atletico Madrid  vs  Bayern Munich 
		 Portuguese Sports  vs  Manchester united 
		 International Milan  vs  Liverpool 
		 Benfica  vs  Ajax 
		 Villarreal  vs  Manchester city 
		 Salzburg Red Bull  vs  Juventus 
		 Chelsea  vs  Lille 

		 Number of occurrences :4
		 Probability of occurrence :0.13%
	},
	 Match situation : {
    
		 Paris Saint Germain  vs  Liverpool 
		 Atletico Madrid  vs  Bayern Munich 
		 Portuguese Sports  vs  Real Madrid 
		 International Milan  vs  Manchester united 
		 Benfica  vs  Lille 
		 Villarreal  vs  Manchester city 
		 Salzburg Red Bull  vs  Juventus 
		 Chelsea  vs  Ajax 

		 Number of occurrences :4
		 Probability of occurrence :0.13%
	},
	 Match situation : {
    
		 Paris Saint Germain  vs  Bayern Munich 
		 Atletico Madrid  vs  Manchester united 
		 Portuguese Sports  vs  Liverpool 
		 International Milan  vs  Lille 
		 Benfica  vs  Juventus 
		 Villarreal  vs  Ajax 
		 Salzburg Red Bull  vs  Manchester city 
		 Chelsea  vs  Real Madrid 

		 Number of occurrences :4
		 Probability of occurrence :0.13%
	},
	 Match situation : {
    
		 Paris Saint Germain  vs  Liverpool 
		 Atletico Madrid  vs  Juventus 
		 Portuguese Sports  vs  Bayern Munich 
		 International Milan  vs  Manchester united 
		 Benfica  vs  Real Madrid 
		 Villarreal  vs  Lille 
		 Salzburg Red Bull  vs  Manchester city 
		 Chelsea  vs  Ajax 

		 Number of occurrences :4
		 Probability of occurrence :0.13%
	},
	 Match situation : {
    
		 Paris Saint Germain  vs  Juventus 
		 Atletico Madrid  vs  Ajax 
		 Portuguese Sports  vs  Manchester city 
		 International Milan  vs  Manchester united 
		 Benfica  vs  Liverpool 
		 Villarreal  vs  Lille 
		 Salzburg Red Bull  vs  Bayern Munich 
		 Chelsea  vs  Real Madrid 

		 Number of occurrences :4
		 Probability of occurrence :0.13%
	},
	 Match situation : {
    
		 Paris Saint Germain  vs  Manchester united 
		 Atletico Madrid  vs  Ajax 
		 Portuguese Sports  vs  Lille 
		 International Milan  vs  Manchester city 
		 Benfica  vs  Liverpool 
		 Villarreal  vs  Juventus 
		 Salzburg Red Bull  vs  Real Madrid 
		 Chelsea  vs  Bayern Munich 

		 Number of occurrences :4
		 Probability of occurrence :0.13%
	}
}

The encounter of all possible opponents of each team is counted as :

 Manchester city : {
     
	 International Milan :  Number of encounters :575	 Encounter frequency :19.17%,
	 Atletico Madrid :  Number of encounters :550	 Encounter frequency :18.33%,
	 Villarreal :  Number of encounters :548	 Encounter frequency :18.27%,
	 Salzburg Red Bull :  Number of encounters :449	 Encounter frequency :14.97%,
	 Portuguese Sports :  Number of encounters :440	 Encounter frequency :14.67%,
	 Benfica :  Number of encounters :438	 Encounter frequency :14.60%
}
 Paris Saint Germain : {
     
	 Real Madrid :  Number of encounters :570	 Encounter frequency :19.00%,
	 Liverpool :  Number of encounters :541	 Encounter frequency :18.03%,
	 Juventus :  Number of encounters :534	 Encounter frequency :17.80%,
	 Manchester united :  Number of encounters :525	 Encounter frequency :17.50%,
	 Ajax :  Number of encounters :433	 Encounter frequency :14.43%,
	 Bayern Munich :  Number of encounters :397	 Encounter frequency :13.23%
}
 Liverpool : {
     
	 Villarreal :  Number of encounters :593	 Encounter frequency :19.77%,
	 Paris Saint Germain :  Number of encounters :541	 Encounter frequency :18.03%,
	 International Milan :  Number of encounters :531	 Encounter frequency :17.70%,
	 Benfica :  Number of encounters :448	 Encounter frequency :14.93%,
	 Salzburg Red Bull :  Number of encounters :447	 Encounter frequency :14.90%,
	 Portuguese Sports :  Number of encounters :440	 Encounter frequency :14.67%
}
 Atletico Madrid : {
     
	 Manchester city :  Number of encounters :550	 Encounter frequency :18.33%,
	 Manchester united :  Number of encounters :549	 Encounter frequency :18.30%,
	 Lille :  Number of encounters :527	 Encounter frequency :17.57%,
	 Juventus :  Number of encounters :526	 Encounter frequency :17.53%,
	 Ajax :  Number of encounters :445	 Encounter frequency :14.83%,
	 Bayern Munich :  Number of encounters :403	 Encounter frequency :13.43%
}
 Ajax : {
     
	 Chelsea :  Number of encounters :655	 Encounter frequency :21.83%,
	 Atletico Madrid :  Number of encounters :445	 Encounter frequency :14.83%,
	 Paris Saint Germain :  Number of encounters :433	 Encounter frequency :14.43%,
	 International Milan :  Number of encounters :393	 Encounter frequency :13.10%,
	 Villarreal :  Number of encounters :378	 Encounter frequency :12.60%,
	 Benfica :  Number of encounters :357	 Encounter frequency :11.90%,
	 Salzburg Red Bull :  Number of encounters :339	 Encounter frequency :11.30%
}
 Portuguese Sports : {
     
	 Juventus :  Number of encounters :462	 Encounter frequency :15.40%,
	 Manchester united :  Number of encounters :456	 Encounter frequency :15.20%,
	 Real Madrid :  Number of encounters :456	 Encounter frequency :15.20%,
	 Liverpool :  Number of encounters :440	 Encounter frequency :14.67%,
	 Manchester city :  Number of encounters :440	 Encounter frequency :14.67%,
	 Lille :  Number of encounters :389	 Encounter frequency :12.97%,
	 Bayern Munich :  Number of encounters :357	 Encounter frequency :11.90%
}
 Real Madrid : {
     
	 Chelsea :  Number of encounters :1023	 Encounter frequency :34.10%,
	 Paris Saint Germain :  Number of encounters :570	 Encounter frequency :19.00%,
	 Salzburg Red Bull :  Number of encounters :489	 Encounter frequency :16.30%,
	 Benfica :  Number of encounters :462	 Encounter frequency :15.40%,
	 Portuguese Sports :  Number of encounters :456	 Encounter frequency :15.20%
}
 International Milan : {
     
	 Manchester united :  Number of encounters :576	 Encounter frequency :19.20%,
	 Manchester city :  Number of encounters :575	 Encounter frequency :19.17%,
	 Liverpool :  Number of encounters :531	 Encounter frequency :17.70%,
	 Lille :  Number of encounters :472	 Encounter frequency :15.73%,
	 Bayern Munich :  Number of encounters :453	 Encounter frequency :15.10%,
	 Ajax :  Number of encounters :393	 Encounter frequency :13.10%
}
 Bayern Munich : {
     
	 Chelsea :  Number of encounters :606	 Encounter frequency :20.20%,
	 International Milan :  Number of encounters :453	 Encounter frequency :15.10%,
	 Villarreal :  Number of encounters :414	 Encounter frequency :13.80%,
	 Atletico Madrid :  Number of encounters :403	 Encounter frequency :13.43%,
	 Paris Saint Germain :  Number of encounters :397	 Encounter frequency :13.23%,
	 Salzburg Red Bull :  Number of encounters :370	 Encounter frequency :12.33%,
	 Portuguese Sports :  Number of encounters :357	 Encounter frequency :11.90%
}
 Benfica : {
     
	 Real Madrid :  Number of encounters :462	 Encounter frequency :15.40%,
	 Manchester united :  Number of encounters :449	 Encounter frequency :14.97%,
	 Liverpool :  Number of encounters :448	 Encounter frequency :14.93%,
	 Juventus :  Number of encounters :443	 Encounter frequency :14.77%,
	 Manchester city :  Number of encounters :438	 Encounter frequency :14.60%,
	 Lille :  Number of encounters :403	 Encounter frequency :13.43%,
	 Ajax :  Number of encounters :357	 Encounter frequency :11.90%
}
 Manchester united : {
     
	 International Milan :  Number of encounters :576	 Encounter frequency :19.20%,
	 Atletico Madrid :  Number of encounters :549	 Encounter frequency :18.30%,
	 Paris Saint Germain :  Number of encounters :525	 Encounter frequency :17.50%,
	 Portuguese Sports :  Number of encounters :456	 Encounter frequency :15.20%,
	 Benfica :  Number of encounters :449	 Encounter frequency :14.97%,
	 Salzburg Red Bull :  Number of encounters :445	 Encounter frequency :14.83%
}
 Villarreal : {
     
	 Liverpool :  Number of encounters :593	 Encounter frequency :19.77%,
	 Juventus :  Number of encounters :574	 Encounter frequency :19.13%,
	 Manchester city :  Number of encounters :548	 Encounter frequency :18.27%,
	 Lille :  Number of encounters :493	 Encounter frequency :16.43%,
	 Bayern Munich :  Number of encounters :414	 Encounter frequency :13.80%,
	 Ajax :  Number of encounters :378	 Encounter frequency :12.60%
}
 Lille : {
     
	 Chelsea :  Number of encounters :716	 Encounter frequency :23.87%,
	 Atletico Madrid :  Number of encounters :527	 Encounter frequency :17.57%,
	 Villarreal :  Number of encounters :493	 Encounter frequency :16.43%,
	 International Milan :  Number of encounters :472	 Encounter frequency :15.73%,
	 Benfica :  Number of encounters :403	 Encounter frequency :13.43%,
	 Portuguese Sports :  Number of encounters :389	 Encounter frequency :12.97%
}
 Salzburg Red Bull : {
     
	 Real Madrid :  Number of encounters :489	 Encounter frequency :16.30%,
	 Juventus :  Number of encounters :461	 Encounter frequency :15.37%,
	 Manchester city :  Number of encounters :449	 Encounter frequency :14.97%,
	 Liverpool :  Number of encounters :447	 Encounter frequency :14.90%,
	 Manchester united :  Number of encounters :445	 Encounter frequency :14.83%,
	 Bayern Munich :  Number of encounters :370	 Encounter frequency :12.33%,
	 Ajax :  Number of encounters :339	 Encounter frequency :11.30%
}
 Juventus : {
     
	 Villarreal :  Number of encounters :574	 Encounter frequency :19.13%,
	 Paris Saint Germain :  Number of encounters :534	 Encounter frequency :17.80%,
	 Atletico Madrid :  Number of encounters :526	 Encounter frequency :17.53%,
	 Portuguese Sports :  Number of encounters :462	 Encounter frequency :15.40%,
	 Salzburg Red Bull :  Number of encounters :461	 Encounter frequency :15.37%,
	 Benfica :  Number of encounters :443	 Encounter frequency :14.77%
}
 Chelsea : {
     
	 Real Madrid :  Number of encounters :1023	 Encounter frequency :34.10%,
	 Lille :  Number of encounters :716	 Encounter frequency :23.87%,
	 Ajax :  Number of encounters :655	 Encounter frequency :21.83%,
	 Bayern Munich :  Number of encounters :606	 Encounter frequency :20.20%
}

It seems , From the perspective of individual teams , The computer hopes that Chelsea and Real Madrid will meet again , Last season the blues were eliminated from Real Madrid and reached the final . From Bayern's point of view , Bayern have the highest probability of meeting old rivals Chelsea , But the four clubs at Chelsea are in the opposite hands , The probability of encountering the southern king is the lowest .
Let's take a look at the overall match chart :

{
     
	 Match situation : {
    
		 Paris Saint Germain  vs  Bayern Munich 
		 Atletico Madrid  vs  Lille 
		 Portuguese Sports  vs  Manchester united 
		 International Milan  vs  Ajax 
		 Benfica  vs  Manchester city 
		 Villarreal  vs  Liverpool 
		 Salzburg Red Bull  vs  Juventus 
		 Chelsea  vs  Real Madrid 

		 Number of occurrences :5
		 Probability of occurrence :0.17%
	},
	 Match situation : {
    
		 Paris Saint Germain  vs  Bayern Munich 
		 Atletico Madrid  vs  Ajax 
		 Portuguese Sports  vs  Juventus 
		 International Milan  vs  Lille 
		 Benfica  vs  Manchester united 
		 Villarreal  vs  Liverpool 
		 Salzburg Red Bull  vs  Manchester city 
		 Chelsea  vs  Real Madrid 

		 Number of occurrences :5
		 Probability of occurrence :0.17%
	},
	 Match situation : {
    
		 Paris Saint Germain  vs  Juventus 
		 Atletico Madrid  vs  Manchester united 
		 Portuguese Sports  vs  Manchester city 
		 International Milan  vs  Liverpool 
		 Benfica  vs  Lille 
		 Villarreal  vs  Ajax 
		 Salzburg Red Bull  vs  Bayern Munich 
		 Chelsea  vs  Real Madrid 

		 Number of occurrences :5
		 Probability of occurrence :0.17%
	},
	 Match situation : {
    
		 Paris Saint Germain  vs  Juventus 
		 Atletico Madrid  vs  Bayern Munich 
		 Portuguese Sports  vs  Manchester united 
		 International Milan  vs  Ajax 
		 Benfica  vs  Liverpool 
		 Villarreal  vs  Manchester city 
		 Salzburg Red Bull  vs  Real Madrid 
		 Chelsea  vs  Lille 

		 Number of occurrences :4
		 Probability of occurrence :0.13%
	},
	 Match situation : {
    
		 Paris Saint Germain  vs  Juventus 
		 Atletico Madrid  vs  Bayern Munich 
		 Portuguese Sports  vs  Liverpool 
		 International Milan  vs  Manchester city 
		 Benfica  vs  Real Madrid 
		 Villarreal  vs  Ajax 
		 Salzburg Red Bull  vs  Manchester united 
		 Chelsea  vs  Lille 

		 Number of occurrences :4
		 Probability of occurrence :0.13%
	},
	 Match situation : {
    
		 Paris Saint Germain  vs  Real Madrid 
		 Atletico Madrid  vs  Bayern Munich 
		 Portuguese Sports  vs  Liverpool 
		 International Milan  vs  Ajax 
		 Benfica  vs  Manchester city 
		 Villarreal  vs  Juventus 
		 Salzburg Red Bull  vs  Manchester united 
		 Chelsea  vs  Lille 

		 Number of occurrences :4
		 Probability of occurrence :0.13%
	},
	 Match situation : {
    
		 Paris Saint Germain  vs  Juventus 
		 Atletico Madrid  vs  Lille 
		 Portuguese Sports  vs  Liverpool 
		 International Milan  vs  Bayern Munich 
		 Benfica  vs  Real Madrid 
		 Villarreal  vs  Manchester city 
		 Salzburg Red Bull  vs  Manchester united 
		 Chelsea  vs  Ajax 

		 Number of occurrences :4
		 Probability of occurrence :0.13%
	},
	 Match situation : {
    
		 Paris Saint Germain  vs  Manchester united 
		 Atletico Madrid  vs  Juventus 
		 Portuguese Sports  vs  Liverpool 
		 International Milan  vs  Ajax 
		 Benfica  vs  Manchester city 
		 Villarreal  vs  Lille 
		 Salzburg Red Bull  vs  Bayern Munich 
		 Chelsea  vs  Real Madrid 

		 Number of occurrences :4
		 Probability of occurrence :0.13%
	},
	 Match situation : {
    
		 Paris Saint Germain  vs  Juventus 
		 Atletico Madrid  vs  Manchester united 
		 Portuguese Sports  vs  Manchester city 
		 International Milan  vs  Ajax 
		 Benfica  vs  Lille 
		 Villarreal  vs  Liverpool 
		 Salzburg Red Bull  vs  Bayern Munich 
		 Chelsea  vs  Real Madrid 

		 Number of occurrences :4
		 Probability of occurrence :0.13%
	},
	 Match situation : {
    
		 Paris Saint Germain  vs  Manchester united 
		 Atletico Madrid  vs  Ajax 
		 Portuguese Sports  vs  Liverpool 
		 International Milan  vs  Lille 
		 Benfica  vs  Juventus 
		 Villarreal  vs  Manchester city 
		 Salzburg Red Bull  vs  Real Madrid 
		 Chelsea  vs  Bayern Munich 

		 Number of occurrences :4
		 Probability of occurrence :0.13%
	},
	 Match situation : {
    
		 Paris Saint Germain  vs  Real Madrid 
		 Atletico Madrid  vs  Manchester city 
		 Portuguese Sports  vs  Juventus 
		 International Milan  vs  Manchester united 
		 Benfica  vs  Lille 
		 Villarreal  vs  Liverpool 
		 Salzburg Red Bull  vs  Ajax 
		 Chelsea  vs  Bayern Munich 

		 Number of occurrences :4
		 Probability of occurrence :0.13%
	},
	 Match situation : {
    
		 Paris Saint Germain  vs  Real Madrid 
		 Atletico Madrid  vs  Bayern Munich 
		 Portuguese Sports  vs  Lille 
		 International Milan  vs  Manchester united 
		 Benfica  vs  Manchester city 
		 Villarreal  vs  Juventus 
		 Salzburg Red Bull  vs  Liverpool 
		 Chelsea  vs  Ajax 

		 Number of occurrences :4
		 Probability of occurrence :0.13%
	},
	 Match situation : {
    
		 Paris Saint Germain  vs  Liverpool 
		 Atletico Madrid  vs  Ajax 
		 Portuguese Sports  vs  Lille 
		 International Milan  vs  Bayern Munich 
		 Benfica  vs  Manchester city 
		 Villarreal  vs  Juventus 
		 Salzburg Red Bull  vs  Manchester united 
		 Chelsea  vs  Real Madrid 

		 Number of occurrences :4
		 Probability of occurrence :0.13%
	},
	 Match situation : {
    
		 Paris Saint Germain  vs  Liverpool 
		 Atletico Madrid  vs  Lille 
		 Portuguese Sports  vs  Juventus 
		 International Milan  vs  Bayern Munich 
		 Benfica  vs  Real Madrid 
		 Villarreal  vs  Manchester city 
		 Salzburg Red Bull  vs  Manchester united 
		 Chelsea  vs  Ajax 

		 Number of occurrences :4
		 Probability of occurrence :0.13%
	},
	 Match situation : {
    
		 Paris Saint Germain  vs  Liverpool 
		 Atletico Madrid  vs  Juventus 
		 Portuguese Sports  vs  Real Madrid 
		 International Milan  vs  Manchester city 
		 Benfica  vs  Manchester united 
		 Villarreal  vs  Bayern Munich 
		 Salzburg Red Bull  vs  Ajax 
		 Chelsea  vs  Lille 

		 Number of occurrences :4
		 Probability of occurrence :0.13%
	},
	 Match situation : {
    
		 Paris Saint Germain  vs  Real Madrid 
		 Atletico Madrid  vs  Bayern Munich 
		 Portuguese Sports  vs  Manchester united 
		 International Milan  vs  Liverpool 
		 Benfica  vs  Ajax 
		 Villarreal  vs  Manchester city 
		 Salzburg Red Bull  vs  Juventus 
		 Chelsea  vs  Lille 

		 Number of occurrences :4
		 Probability of occurrence :0.13%
	},
	 Match situation : {
    
		 Paris Saint Germain  vs  Liverpool 
		 Atletico Madrid  vs  Bayern Munich 
		 Portuguese Sports  vs  Real Madrid 
		 International Milan  vs  Manchester united 
		 Benfica  vs  Lille 
		 Villarreal  vs  Manchester city 
		 Salzburg Red Bull  vs  Juventus 
		 Chelsea  vs  Ajax 

		 Number of occurrences :4
		 Probability of occurrence :0.13%
	},
	 Match situation : {
    
		 Paris Saint Germain  vs  Bayern Munich 
		 Atletico Madrid  vs  Manchester united 
		 Portuguese Sports  vs  Liverpool 
		 International Milan  vs  Lille 
		 Benfica  vs  Juventus 
		 Villarreal  vs  Ajax 
		 Salzburg Red Bull  vs  Manchester city 
		 Chelsea  vs  Real Madrid 

		 Number of occurrences :4
		 Probability of occurrence :0.13%
	},
	 Match situation : {
    
		 Paris Saint Germain  vs  Liverpool 
		 Atletico Madrid  vs  Juventus 
		 Portuguese Sports  vs  Bayern Munich 
		 International Milan  vs  Manchester united 
		 Benfica  vs  Real Madrid 
		 Villarreal  vs  Lille 
		 Salzburg Red Bull  vs  Manchester city 
		 Chelsea  vs  Ajax 

		 Number of occurrences :4
		 Probability of occurrence :0.13%
	},
	 Match situation : {
    
		 Paris Saint Germain  vs  Juventus 
		 Atletico Madrid  vs  Ajax 
		 Portuguese Sports  vs  Manchester city 
		 International Milan  vs  Manchester united 
		 Benfica  vs  Liverpool 
		 Villarreal  vs  Lille 
		 Salzburg Red Bull  vs  Bayern Munich 
		 Chelsea  vs  Real Madrid 

		 Number of occurrences :4
		 Probability of occurrence :0.13%
	},
	 Match situation : {
    
		 Paris Saint Germain  vs  Manchester united 
		 Atletico Madrid  vs  Ajax 
		 Portuguese Sports  vs  Lille 
		 International Milan  vs  Manchester city 
		 Benfica  vs  Liverpool 
		 Villarreal  vs  Juventus 
		 Salzburg Red Bull  vs  Real Madrid 
		 Chelsea  vs  Bayern Munich 

		 Number of occurrences :4
		 Probability of occurrence :0.13%
	}
}

The three occurrences are 5 The graph of the highest probability is shown below :

	 Match situation : {
    
		 Paris Saint Germain  vs  Bayern Munich 
		 Atletico Madrid  vs  Lille 
		 Portuguese Sports  vs  Manchester united 
		 International Milan  vs  Ajax 
		 Benfica  vs  Manchester city 
		 Villarreal  vs  Liverpool 
		 Salzburg Red Bull  vs  Juventus 
		 Chelsea  vs  Real Madrid 

		 Number of occurrences :5
		 Probability of occurrence :0.17%
	},
	 Match situation : {
    
		 Paris Saint Germain  vs  Bayern Munich 
		 Atletico Madrid  vs  Ajax 
		 Portuguese Sports  vs  Juventus 
		 International Milan  vs  Lille 
		 Benfica  vs  Manchester united 
		 Villarreal  vs  Liverpool 
		 Salzburg Red Bull  vs  Manchester city 
		 Chelsea  vs  Real Madrid 

		 Number of occurrences :5
		 Probability of occurrence :0.17%
	},
	 Match situation : {
    
		 Paris Saint Germain  vs  Juventus 
		 Atletico Madrid  vs  Manchester united 
		 Portuguese Sports  vs  Manchester city 
		 International Milan  vs  Liverpool 
		 Benfica  vs  Lille 
		 Villarreal  vs  Ajax 
		 Salzburg Red Bull  vs  Bayern Munich 
		 Chelsea  vs  Real Madrid 

		 Number of occurrences :5
		 Probability of occurrence :0.17%
	}

Chelsea's opponents in the three matches are all Real Madrid , And Messi's signing in Paris is also very bad , Bayern twice and Juve once , Although Juve played a mediocre game in the league in the first half of the season .

Conclusion

This project is purely for entertainment , In fact , I'm lucky , We have drawn Salzburg, which is relatively weak , Real Madrid met Messi 、 Ramos' greater Paris , Atletico Madrid met C Ronaldo's Manchester United , The Reds meet Inter , It's also a good story .

原网站

版权声明
本文为[coder_ szc]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/02/202202211327444592.html

随机推荐