Алгоритмы жеребьевки

Discussion in 'Машинное отделение' started by Tristan, 4 Feb 2007.

  1. TopicStarter Overlay

    Tristan Учаcтник

    • Участник
    Member Since:
    26.09.2006
    Message Count:
    110
    Likes Received:
    0
    Репутация:
    0
    Оффлайн
    Всем привет!

    Подскажите ресурсы на алгоритмы жеребьевок круговиков и швейцарки.
  2. Guest

    Member Since:
    Message Count:
    0
    Likes Received:
    0
    Репутация:
    0
    Оффлайн
    Не совсем понятно, что Вы хотите. Саму жеребьевку или кто с кем играет в результате жеребьевки. Для круговиков все относительно просто. Проводите жеребьевку (расставлять людей по рейтингу - это самое худшее). После того, как игроки получили стартовые номера - используете стандартные таблицы. Их можно найти например на сайте канадской шахматной федерации - http://chess.ca/pdf/PairRRs.pdf
    Там таблицы до 16-ти игроков, но если вы приглядитесь внимательно, то увидите как их создать для любого числа игроков. Еще одна тонкость, если для второго круга использовать ту же таблицу, то один из участников сыграет 3 партии подряд белым цветом, а другой три партии подряд черным. Чтобы этого избежать порядок туров второго круга немного модифицируется. Если играется только один круг, то таких проблем нет.
    С швейцарками сложнее, есть несколько вариантов правил - http://www.fide.com/official/handbook.asp?level=C04, и в рамках правил может существовать несколько (>=0) вариантов жеребьевок. Если Вам нужно турнир проводить, то лучше воспользоваться готовыми програмами. Есть и бесплатные, есть и shareware. Можно и купить если сильно надо.
  3. TopicStarter Overlay

    Tristan Учаcтник

    • Участник
    Member Since:
    26.09.2006
    Message Count:
    110
    Likes Received:
    0
    Репутация:
    0
    Оффлайн
    Большое спасибо. Это почти то, что нужно. Нет ли точного алгоритма круговой жеребьевки? А то щас сиди, отгадывай последовательность.
  4. Guest

    Member Since:
    Message Count:
    0
    Likes Received:
    0
    Репутация:
    0
    Оффлайн
    Навсидку, в таблице на 2n участников в туре номер k играют пары с номерами i и j так что:
    i+j = 2n+k или
    i+j = k+1
    Если k+1 - четное, то участник с номером (k+1)/2 играет против последнего участника (2n).
    Если 2n+k - четное, то соперником последнего будет участник с номером (2n+k)/2.
    С цветами сами разберитесь.
  5. WinPooh В.М.

    • Команда форума
    Member Since:
    13.02.2006
    Message Count:
    9.492
    Likes Received:
    3.122
    Репутация:
    95
    Location:
    Москва
    Оффлайн
    Думаю, что Гугл хороший помощник в таком поиске :)

    А на бумаге, помнится, в книжках Гика по занимательной математике и шахматам (издавались в 80-е годы в "Библиотечке КВАНТ") довольно много было про круговую жеребьёвку. Я в школе даже программу соответствующую на ФОРТРАНе написал, для получения зачёта по информатике :)
  6. WinPooh В.М.

    • Команда форума
    Member Since:
    13.02.2006
    Message Count:
    9.492
    Likes Received:
    3.122
    Репутация:
    95
    Location:
    Москва
    Оффлайн
  7. TopicStarter Overlay

    Tristan Учаcтник

    • Участник
    Member Since:
    26.09.2006
    Message Count:
    110
    Likes Received:
    0
    Репутация:
    0
    Оффлайн
    Большое спасибо, комрады!
  8. Guest

    Member Since:
    Message Count:
    0
    Likes Received:
    0
    Репутация:
    0
    Оффлайн
    На досуге программку на C накрапал, откомпилируйте ее и обращайтесь как-нибудь так:
    ./a.out -n 16


    #include <stdlib.h>
    #include <getopt.h>

    char optstring[]="n:";
    extern char *optarg;
    extern int optind, opterr;

    int main(int argc, unsigned char **argv)
    {
    int i, j, n=6, N, k, c;

    while ( (c = getopt(argc, argv, optstring)) != -1)
    {
    switch(c)
    {
    case 'n':
    sscanf(optarg, "%d", &n);
    if (n <= 0) n = 6;
    break;
    default:
    break;
    }
    }

    printf ("%d-player Round Robin\n", n);

    N = n + (n&1);

    for (k=1; k<=N-1; k++)
    {
    printf("Round %d: ", k);
    if ((k&1)==1)
    {
    j = (k+1)/2;
    if (n<N)
    printf("%d-Bye ", j);
    else
    printf("%d-%d ", j, N);

    for (i=(k+2)/2-1; i>=1; i--)
    printf("%d-%d ", k+1-i, i);

    for (i=k+1; i<(N+k+1)/2; i++)
    printf("%d-%d ", i, N+k-i);

    }
    else
    {
    j = (k+N)/2;
    if (n<N)
    printf("%d-Bye ", j);
    else
    printf("%d-%d ", N, j);

    for (i=(N+k+1)/2-1; i>=k+1; i--)
    printf("%d-%d ", N+k-i, i);

    for (i=1; i<(k+2)/2; i++)
    printf("%d-%d ", i, k+1-i);
    }
    printf("\n");
    }
    }

Share This Page