2009-08-18 39 views
6

Tôi đang gặp một số rắc rối để đạt được dự án round robin nhỏ này. Những gì tôi cố gắng làm là tạo lịch xem trước của trò chơiThuật toán Giải đấu Vòng tròn Robin tại C#

thì tôi muốn xuất;

ngày 1: Đội 1 vs Đội 2; Đội 3 vs Đội 4; Đội 5vs Đội 6;

ngày 2 Đội 1 vs Đội 4; Đội 6 vs Đội 3; Đội 2 vs Đội 5;

cho đến khi kết thúc chức vô địch;

Đây là mã tôi đã có cho đến nay nhưng tôi đang gặp rắc rối để cho đội bóng đầu tiên cố định trong khi phần còn lại của mảng xoay ...:

static void Main(string[] args) 
    { 
     string[] ListTeam = new string[] {"Equipe1", "Equipe2", "Equipe3", "Equipe4", "Equipe5", "Equipe6"}; 
     IList<Match> ListMatch = new List<Match>(); 
     it NumberOfDays = (ListTeam.Count()-1); 
     int y = 2; 

     for (int i = 1; i <= NumberOfDays; i++) 
     { 
      Console.WriteLine("\nDay {0} : \n",i); 
      Console.WriteLine(ListTeam[0].ToString() + " VS " + ListTeam[i].ToString()); 

      for (y =ListTeam.Count(); y>0 ; y--) 
      { 
       Console.WriteLine(ListTeam[y].ToString() + " VS " + ListTeam[y+1].ToString()); 
       y++; 
      } 

     } 
    } 

EDIT: Tôi tìm thấy một code sample in java but tôi không thể dịch được ...

+0

Tôi không thể tìm cách để encre đội đầu tiên và vẫn làm ouput các trận đấu khác – Polo

+0

@ John Nolan: xin lỗi vì lỗi chính tả và đánh vần ... – Polo

+0

Việc triển khai Java mà bạn đã liên kết đến rất tối nghĩa. Ngoài ra, thực tế là các văn bản và các biến được bằng tiếng Pháp không giúp đỡ (tôi, ít nhất). – paracycle

Trả lời

11

này nên được dễ dàng, đủ để làm sử dụng số học modula:

UPDATE 2: (Như đã hứa thuật toán đúng)

public void ListMatches(List<string> ListTeam) 
{ 
    if (ListTeam.Count % 2 != 0) 
    { 
     ListTeam.Add("Bye"); 
    } 

    int numDays = (numTeams - 1); 
    int halfSize = numTeams/2; 

    List<string> teams = new List<string>(); 

    teams.AddRange(ListTeam.Skip(halfSize).Take(halfSize)); 
    teams.AddRange(ListTeam.Skip(1).Take(halfSize -1).ToArray().Reverse()); 

    int teamsSize = teams.Count; 

    for (int day = 0; day < numDays; day++) 
    { 
     Console.WriteLine("Day {0}", (day + 1)); 

     int teamIdx = day % teamsSize; 

     Console.WriteLine("{0} vs {1}", teams[teamIdx], ListTeam[0]); 

     for (int idx = 1; idx < halfSize; idx++) 
     {    
      int firstTeam = (day + idx) % teamsSize; 
      int secondTeam = (day + teamsSize - idx) % teamsSize; 
      Console.WriteLine("{0} vs {1}", teams[firstTeam], teams[secondTeam]); 
     } 
    } 
} 

đó sẽ in các trận đấu đội mỗi ngày.

Hãy để tôi nhanh chóng cố gắng giải thích như thế nào thuật toán hoạt động:

tôi nhận thấy rằng vì chúng ta đang quay tất cả các đội bóng ngoại trừ thứ nhất, nếu chúng ta đặt tất cả các đội bóng trong một mảng ngoại trừ cái đầu tiên, sau đó chúng tôi nên chỉ cần đọc ra khỏi nhóm đầu tiên từ mảng đó bằng cách sử dụng chỉ số bù đắp dựa trên ngày và làm số học mô-đun để quấn quanh một cách chính xác. Trong thực tế, chúng tôi sẽ coi mảng đó là lặp lại vô hạn theo cả hai hướng và chúng tôi sẽ trượt chế độ xem của chúng tôi theo chiều tăng dần sang phải (hoặc sang trái).

Tuy nhiên, có một sự cố và thực tế là chúng tôi phải đặt hàng các nhóm theo cách rất cụ thể để hoạt động chính xác. Nếu không, chúng tôi sẽ không quay đúng. Bởi vì điều này chúng ta cần phải đọc của đội thứ hai phù hợp theo một cách rất đặc biệt là tốt.

Các cách chính xác để chuẩn bị danh sách của bạn như sau:

  • Không bao giờ đưa đội bóng đầu tiên (Team # 1) trong danh sách.
  • Lấy nửa cuối của danh sách nhóm và đặt chúng ở phía trước danh sách.
  • Lấy nửa đầu của danh sách, đảo ngược và đặt chúng vào danh sách (nhưng không phải Nhóm # 1).

Bây giờ, cách chính xác để đọc ra khỏi danh sách như sau:

  • Đối với mỗi ngày, tăng chỉ số đầu tiên mà bạn đang xem xét bởi 1.
  • Đối với nhóm đầu tiên mà bạn nhìn thấy tại vị trí đó, hãy kết hợp đội đó với Đội # 1.
  • Đối với đội tiếp theo trong danh sách ((day + idx) % numDays), chúng tôi thường khớp với đội được bù lại bằng một nửa số đội trừ 1 (trừ 1 vì chúng tôi đã tự mình đối đầu với trận đầu tiên). Tuy nhiên, vì nửa sau của danh sách của chúng tôi đã được chuẩn bị bằng cách hoàn nguyên, chúng tôi cần phải khớp với phần bù đó trong nửa sau của danh sách. Một cách đơn giản hơn để làm là quan sát rằng trong điều này là tương đương với kết hợp cùng một chỉ mục nhưng từ cuối danh sách. Với số tiền hiện tại là day, đó là (day + (numDays - idx)) % numDays.

UPDATE 3: tôi đã không hài lòng rằng giải pháp của tôi liên quan đến lựa chọn phức tạp như vậy, khớp, đảo ngược của các phần tử mảng. Sau khi tôi đã suy nghĩ về những gì giải pháp của tôi liên quan đến tôi nhận ra rằng tôi đã quá treo lên về giữ trật tự của các đội như được đưa ra. Tuy nhiên, đó không phải là một yêu cầu và người ta có thể có được một lịch trình khác nhau nhưng không kém phần hợp lý bằng cách không quan tâm đến thứ tự ban đầu. Tất cả những gì quan trọng là thuật toán lựa chọn tôi mô tả trong phần thứ hai của lời giải thích của tôi.

Vì vậy bạn có thể đơn giản hóa các dòng sau:

teams.AddRange(ListTeam.Skip(halfSize).Take(halfSize)); 
teams.AddRange(ListTeam.Skip(1).Take(halfSize -1).ToArray().Reverse()); 

tới:

teams.AddRange(ListTeam); // Copy all the elements. 
teams.RemoveAt(0); // To exclude the first team. 
+0

Cho đến nay rất tốt nhưng nếu bạn cố gắng để ouput đội 1 vs đội 2 bạn sẽ nhận được một exeption – Polo

+0

tôi thấy nhưng không thể nó được thực hiện với hai vòng để có được A vs B, C vs D .... – Polo

+0

Có bạn đi . Tôi đã cập nhật nó. – paracycle

6

Có vẻ như bạn muốn lập lịch biểu round-robin tournament. Bài viết wp chứa thuật toán.

Tôi không thấy nơi bạn đang cố gắng xoay mảng. Các hoán vị sẽ trông giống như sau: 1 -> 2 -> 3 -> 4 ... -> n/2 - 1 -> n - 1 -> n - 2 -> n - 3 -> ... -> n/2 -> 1 (và 0 vẫn cố định). Bạn có thể làm điều đó trong 2 vòng (hàng trên cùng và hàng dưới cùng).

+0

Cảm ơn bạn đã trả lời nhưng có cách tạo ngẫu nhiên không? – Polo

+0

ở đâu? tôi chỉ có thể tìm thấy methode – Polo

+0

? phương pháp nên dẫn trực tiếp đến một thuật toán thích hợp. Việc thêm nhãn ngẫu nhiên của các đội là một bổ sung nhỏ nhặt và đáp ứng các yêu cầu của bạn. Có thể lưu ý rằng 'xoay theo chiều kim đồng hồ' trang wp nói là một vòng, vì vậy, 1 2 3 4, xoay vòng theo chiều kim đồng hồ là 4 1 2 3. – nlucaroni

0

Làm thế nào về tính toán kết hợp có thể cho mỗi ngày mà bạn muốn sau đó

  1. loại chúng trong mỗi cặp ví dụ: đội số thấp nhất luôn là đầu tiên trong bất kỳ cặp.
  2. sắp xếp các cặp được liệt kê cho từng ngày theo cặp đầu tiên trong mỗi cặp .
+0

(NumberOfTeams/2) và sau ??? Tôi đã không nhận được quan điểm của bạn, nhưng như tôi cần phải encre đội đầu tiên và xoay mảng cho đến khi nó quay trở lại nút đầu tiên nhưng tôi không thể tìm thấy một cách – Polo

+0

Tôi đang ngây thơ để encre đội đầu tiên và sau đó xoay các mảng (phần tôi bỏ lỡ) cho đến khi nó quay trở lại điểm gốc – Polo

+0

Tôi nghĩ rằng tôi đang cố gắng để nói, thay vì cố gắng để làm luân phiên * và * giữ team1 đầu tiên bằng cách sử dụng một thuật toán vượt qua làm điều đó trong một hai vượt qua thay vào đó. – RobS

1

Nó có thể là một phương pháp phức tạp, nhưng điều này có thể được giảm đến một vấn đề lý thuyết đồ thị. Tạo một đỉnh đồ thị cho mỗi đội, và tạo ra một cạnh giữa mỗi đỉnh (vì vậy nó là một đồ thị hoàn chỉnh). Sau đó cho các thuật toán:

Đối với mỗi ngày i = 1 .. n:

  • Chọn bất kỳ hai đỉnh đánh dấu được kết nối trực tiếp và gắn nhãn mép giữa họ với tôi. Đánh dấu cả hai đỉnh.
  • Lặp lại cho đến khi tất cả các đỉnh được đánh dấu.
  • Xuất các cạnh được gắn nhãn (tức là team1 vs team2, team3 vs team4 etc)
  • Xóa các cạnh được gắn nhãn khỏi biểu đồ và đặt lại tất cả các đỉnh thành không được đánh dấu.
+0

thats một chút để tought, tôi đang bắt đầu – Polo

+0

Công bằng đủ. Đó là một chút của một lý thuyết hơn là một giải pháp thực tế. – tw39124

2

tôi đã thực hiện một số cải tiến trong khối mã đã trả lời rằng tính toán đúp lịch round-robin

GameEntities db = new GameEntities(); 


private void btnTeamFixtures_Click(object sender, RoutedEventArgs e) 
    { 
     txtResults.Text = null; 

     var allTeams = db.Team.Select(t => t.TeamName); 

     int numDays = allTeams.Count() - 1; 
     int halfsize = allTeams.Count()/2; 

     List<string> temp = new List<string>(); 
     List<string> teams = new List<string>(); 

     teams.AddRange(allTeams); 
     temp.AddRange(allTeams); 
     teams.RemoveAt(0); 

     int teamSize = teams.Count; 

     for (int day = 0; day < numDays * 2; day++) 
     { 
      //Calculate1stRound(day); 
      if (day % 2 == 0) 
      { 
       txtResults.Text += String.Format("\n\nDay {0}\n", (day + 1)); 

       int teamIdx = day % teamSize; 

       txtResults.Text += String.Format("{0} vs {1}\n", teams[teamIdx], temp[0]); 

       for (int idx = 0; idx < halfsize; idx++) 
       { 
        int firstTeam = (day + idx) % teamSize; 
        int secondTeam = ((day + teamSize) - idx) % teamSize; 

        if (firstTeam != secondTeam) 
        { 
         txtResults.Text += String.Format("{0} vs {1}\n", teams[firstTeam], teams[secondTeam]); 
        } 
       } 
      } 

      //Calculate2ndRound(day); 
      if (day % 2 != 0) 
      { 
       int teamIdx = day % teamSize; 

       txtResults.Text += String.Format("\n\nDay {0}\n", (day + 1)); 

       txtResults.Text += String.Format("{0} vs {1}\n", temp[0], teams[teamIdx]); 

       for (int idx = 0; idx < halfsize; idx++) 
       { 
        int firstTeam = (day + idx) % teamSize; 
        int secondTeam = ((day + teamSize) - idx) % teamSize; 

        if (firstTeam != secondTeam) 
        { 
         txtResults.Text += String.Format("{0} vs {1}\n", teams[secondTeam], teams[firstTeam]); 
        } 
       } 
      } 
     } 
    } 

Nếu u muốn u có thể tạo ra 2 phương pháp và vượt qua và số nguyên (ngày) như tôi đã làm trong 2 dòng nhận xét, để tách mã.

Nếu bạn có bất kỳ câu hỏi hoặc đề xuất nào, vui lòng trả lời.

Các vấn đề liên quan