Переключение на Главную Страницу Страницы: 1 [2] 3  ОтправитьПечать
Очень популярная тема (более 25 ответов) Разминка для головы. Оптимальный алгоритм. (число прочтений - 7996 )
JohnyDeath
1c++ power user
1c++ donor
Отсутствует



Сообщений: 3050
Местоположение: Волгоград
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Разминка для головы. Оптимальный алгоритм.
Ответ #15 - 21. Мая 2010 :: 14:29
Печать  
Anatol писал(а) 21. Мая 2010 :: 14:21:
ид пары это 2 в степени ид игрока

1 = 2
2 = 4
3 = 8
4 = 16
5 = 32
6 = 64

складываем пары между собой получем = ид пары
ид пары не должен быть равен ид игрока (что бы игрок не играл сам с собой  Улыбка )

Я ж говорю, заполнить эту таблицу - не есть проблема. Эту таблицу я придумал, чтоб легче выдирать пары, которые не играли для любого выбранного игрока.
  
Наверх
 
IP записан
 
berezdetsky
1c++ power user
Отсутствует


barba non facit sisadminum

Сообщений: 1986
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Разминка для головы. Оптимальный алгоритм.
Ответ #16 - 21. Мая 2010 :: 14:39
Печать  
JohnyDeath писал(а) 21. Мая 2010 :: 14:20:
Таблица "Пары" заполняется сразу как только заполнена табличка "Игроки" и кол-во записей в ней будет = n!, где n - количество записей в таблице "Игроки".

Занятная комбинаторика.  Смех

Может того.. утро вечера мудренее?
  

пароль как коньяк, чем больше звездочек, тем лучше
Наверх
IP записан
 
JohnyDeath
1c++ power user
1c++ donor
Отсутствует



Сообщений: 3050
Местоположение: Волгоград
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Разминка для головы. Оптимальный алгоритм.
Ответ #17 - 21. Мая 2010 :: 14:50
Печать  
Иван, а разве не так? Насколько я помню, факториал числа  n - это количество перестановок n элементов.
Если ты про то, что пара 1-2 эквивалентна паре 2-1 - да, так и есть, но я намеренно заполнял таблицу "Пары" всеми возможными комбинациями чтобы в запросах писать условие:
Код
Выбрать все
WHERE Пары.Игрок1 = "Игрок_1" 


иначе пришлось бы писать так:
Код
Выбрать все
WHERE Пары.Игрок1 = "Игрок_1" OR Пары.Игрок2 = "Игрок_1" 


со всеми вытекающими...

berezdetsky писал(а) 21. Мая 2010 :: 14:39:
Может того.. утро вечера мудренее?  

Ну да, наверное. Если будут какие-нибудь идеи - напиши обязательно. Я чё-т уже и сплю плохо  Улыбка
Сейчас меня тянет в сторону алгоритмов с "деревьями", хотя я с ними вообще никогда не работал  Нерешительный
  
Наверх
 
IP записан
 
berezdetsky
1c++ power user
Отсутствует


barba non facit sisadminum

Сообщений: 1986
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Разминка для головы. Оптимальный алгоритм.
Ответ #18 - 21. Мая 2010 :: 16:02
Печать  
JohnyDeath писал(а) 21. Мая 2010 :: 14:50:
Иван, а разве не так? Насколько я помню, факториал числа  n - это количество перестановок n элементов.

Это для множеств с повторениями. Без повторений количество перестановок равно n! / (k! * (n - k)!). Для пар (k = 2) это будет n * (n - 1) / 2.


JohnyDeath писал(а) 21. Мая 2010 :: 14:50:
иначе пришлось бы писать так:

Ну.. Мне же в #6 не пришлось..  Улыбка
  

пароль как коньяк, чем больше звездочек, тем лучше
Наверх
IP записан
 
Anatol
Senior Member
****
Отсутствует


тыц, пыц, тыц!!!

Сообщений: 412
Зарегистрирован: 24. Апреля 2009
Re: Разминка для головы. Оптимальный алгоритм.
Ответ #19 - 21. Мая 2010 :: 16:50
Печать  
Помоему задача поставлена не совсем корректно.
по Швейцарской системе распределение пар еще зависит от результат предыдущего тура, выигравшие играют с выигрывавшими, а проигравшие с проигравшими.

#13 на верно следует перечитать правила, а то ерунда получается
  
Наверх
wwwICQ  
IP записан
 
JohnyDeath
1c++ power user
1c++ donor
Отсутствует



Сообщений: 3050
Местоположение: Волгоград
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Разминка для головы. Оптимальный алгоритм.
Ответ #20 - 22. Мая 2010 :: 07:18
Печать  
berezdetsky писал(а) 21. Мая 2010 :: 16:02:
JohnyDeath писал(а) 21. Мая 2010 :: 14:50:
Иван, а разве не так? Насколько я помню, факториал числа  n - это количество перестановок n элементов.

Это для множеств с повторениями. Без повторений количество перестановок равно n! / (k! * (n - k)!). Для пар (k = 2) это будет n * (n - 1) / 2.

Это я понимаю. Но мне кажется, что в данном случае избыточность этой таблицы полезна.
При виде всех этих восклицательных знаков вспомнились фразы типа: "цэ из эн по ка"; и школьный сборник задач по математике "Сканави". Институт, почему-то, вообще не вспомнился...

berezdetsky писал(а) 21. Мая 2010 :: 16:02:
JohnyDeath писал(а) 21. Мая 2010 :: 14:50:
иначе пришлось бы писать так:

Ну.. Мне же в #6 не пришлось..  Улыбка

Да я и не спорю, что можно найти тысячу и один способ построения запроса и этой таблицы. Но вопрос-то сейчас в другом:
Как из пар, которые могут играть в этом туре с заданным набором участников, выбрать ту комбинацию, которая бы покрывала всех заданных участников. Получить сам список доступных пар для данных участников мы уже поняли и написали несколько запросов.
  
Наверх
 
IP записан
 
JohnyDeath
1c++ power user
1c++ donor
Отсутствует



Сообщений: 3050
Местоположение: Волгоград
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Разминка для головы. Оптимальный алгоритм.
Ответ #21 - 22. Мая 2010 :: 07:45
Печать  
Anatol писал(а) 21. Мая 2010 :: 16:50:
Помоему задача поставлена не совсем корректно.
по Швейцарской системе распределение пар еще зависит от результат предыдущего тура, выигравшие играют с выигрывавшими, а проигравшие с проигравшими.

#13 на верно следует перечитать правила, а то ерунда получается

Давай на примере покажу.
Всего в чемпионате участвуют 6 человек: 1,2,3,4,5,6. В первом туре они разбиваются на пары согласно жребию (т.к. кол-во очков у всех = 0 и рейтинга ни у кого никакого нет) на вот такие пары:
Игрок1 Игрок2 Победитель
1 2 1
3 4 3
5 6 5

Во втором туре, согласно правилам, игроки разбиваются на подгруппы по количеству набранных очков. Мы имеем две подгруппы: 1,3,5 (Победители) и 2,4,6 (Проигравшие). Т.к. первая подгруппа имеет нечетное кол-во участников, то последнего выкидываем в ближайшую очковую группу. Тогда имеем такие подгруппы: {1,3} и {5,2,4,6}. Играем:
Игрок1 Игрок2 Победитель
1 3 3
5 2 2
4 6 4

Теперь перед 3-м туром имеем:
1. Игрок 3 имеет 2 очка
2. Игроки 1,2,4,5 имеют по одному очку
3. Игрок 6 имеет 0 очков
Разбиваемся на подгруппы (согласно очкам и правилу "четности"): {3,1,2,4}, {5,6}
Т.о. в 3-м туре имеем первую подгруппу, где некоторые игрокуи уже играли между собой. А именно:
Пара: 3 - 4
и Пара: 1 - 2


Как раз и надо составить тур для первой подгруппы, где на входе имеем доступные пары:
2-3
1-4
2-4
и список игроков: {1,2,3,4}
« Последняя редакция: 22. Мая 2010 :: 16:09 - JohnyDeath »  
Наверх
 
IP записан
 
berezdetsky
1c++ power user
Отсутствует


barba non facit sisadminum

Сообщений: 1986
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Разминка для головы. Оптимальный алгоритм.
Ответ #22 - 22. Мая 2010 :: 12:18
Печать  
На сколько я понял, жеребьёвка используется только в первом туре. В последующих - по рейтинговому принципу. Следствие: Цитата:
Если строго придерживаться всех правил распределения по парам, то практически все пары складываются однозначно, то есть почти не бывает свободы выбора.

На твоём примере, с учётом коэффициента Бухгольца, последовательность в группе = {4, 2, 1, 3}, а значит пары - 4-1 и 2-3.

Можно, конечно, решить и простым перебором из двух вложенных циклов..
  

пароль как коньяк, чем больше звездочек, тем лучше
Наверх
IP записан
 
JohnyDeath
1c++ power user
1c++ donor
Отсутствует



Сообщений: 3050
Местоположение: Волгоград
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Разминка для головы. Оптимальный алгоритм.
Ответ #23 - 22. Мая 2010 :: 15:21
Печать  
Иван, а вот ты бы поверил без оглядки высказыванию о том, что "практически все пары складываются однозначно"? Я не поверил, что всё может обойтись, а смоделировать все возможные комбинации, которые могут произойти в игре с 500 участниками я не в силах, поэтому и стал искать запасное решение.
Коэф-т Бухгольца конечно же учитывается при формировании групп. Этот пример я дал только для того, чтобы показать, что некоторые игроки могут попадать в одну группу несколько раз. Привести пример, где правило формирование групп и пар не сработало, не могу, ибо очень трудно придумать такую ситуацию. Но, как обычно и бывает, уже в боевых условиях такая ситуация запрсто может вылезти при первом же применении, а там уже ручками сами пользователи этой программы вряд ли смогут что-то сделать (читай "пестец турниру")

Общий алгоритм примерно такой:
1. Играем (вносим данные о сыгранных матчах)
2. Сортируем всех по (КоличествоОчков, Коэф. Бухгольца)
3. Разбиваем на подгруппы в зависимости от кол-ва очков
4. Разбиваемся на пары для игры. А именно:
  а)Пробуем классическим методом (первый из первой половины группы играет с первым из второй половины).
  б)Если он не срабатывает применяем обсуждаемый здесь алгоритм.
  в)Если и он не срабатывает, откатываемся на вариант (а) и забиваем на то, что некоторые играют друг с другом уже не впервый раз. Сыграют и еще разок.

и так для каждого тура.

И да, я тоже остановился на алгоритме с 2-мя вложенными циклами, но почему-то душа у меня к нему не лежит, кажется будто он делает что-то не так (доказать не могу  Нерешительный).
  
Наверх
 
IP записан
 
JohnyDeath
1c++ power user
1c++ donor
Отсутствует



Сообщений: 3050
Местоположение: Волгоград
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Разминка для головы. Оптимальный алгоритм.
Ответ #24 - 22. Мая 2010 :: 15:56
Печать  
berezdetsky писал(а) 22. Мая 2010 :: 12:18:
На твоём примере, с учётом коэффициента Бухгольца, последовательность в группе = {4, 2, 1, 3}, а значит пары - 4-1 и 2-3.

Коэф. Бухгольца для этих игроков:
у 1го - 2 балла
у 2го - 2 балла
у 3го - 1 балл
у 4го - 1 балл
(а как у тебя получилось так однозначно расставить?)

Т.о. можем получить 4 варианта расстановки группы: {1,2,3,4}, {1,2,4,3}, {2,1,3,4}, {2,1,4,3}
Первый вариант не подходит, т.к. 1-й с 3-м уже играли.
  
Наверх
 
IP записан
 
berezdetsky
1c++ power user
Отсутствует


barba non facit sisadminum

Сообщений: 1986
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Разминка для головы. Оптимальный алгоритм.
Ответ #25 - 22. Мая 2010 :: 16:27
Печать  
JohnyDeath писал(а) 22. Мая 2010 :: 15:21:
Иван, а вот ты бы поверил без оглядки высказыванию о том, что "практически все пары складываются однозначно"?

Но ведь так и есть. Хотя я могу представить группу, для которой не будет существовать допустимого набора пар. "Сыграют и еще разок", IMHO, противоречит идее швейцарской системы.

JohnyDeath писал(а) 22. Мая 2010 :: 15:21:
И да, я тоже остановился на алгоритме с 2-мя вложенными циклами, но почему-то душа у меня к нему не лежит, кажется будто он делает что-то не так (доказать не могу  Нерешительный).

Возможно, мы имеем ввиду разные алгоритмы. Я говорю о стандартном алгоритме генерации k-элементных подмножеств из комбинаторики.
  

пароль как коньяк, чем больше звездочек, тем лучше
Наверх
IP записан
 
berezdetsky
1c++ power user
Отсутствует


barba non facit sisadminum

Сообщений: 1986
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Разминка для головы. Оптимальный алгоритм.
Ответ #26 - 22. Мая 2010 :: 16:51
Печать  
JohnyDeath писал(а) 22. Мая 2010 :: 15:56:
berezdetsky писал(а) 22. Мая 2010 :: 12:18:
На твоём примере, с учётом коэффициента Бухгольца, последовательность в группе = {4, 2, 1, 3}, а значит пары - 4-1 и 2-3.

Коэф. Бухгольца для этих игроков:
у 1го - 2 балла
у 2го - 2 балла
у 3го - 1 балл
у 4го - 1 балл
(а как у тебя получилось так однозначно расставить?)

Ээ.. Где-то ошибся.  Смущённый Сейчас пересчитал, получилось
1 - 3 балла, 2 и 4 - по 2 балла, 3 - вне конкуренции, т.к. у него изначально 2 очка против 1 у остальных. Для 2 и 4 применяем усечённый коэффициент Бухгольца, получаем 2 - 1 балл, 4 - 2 балла.
Итого: {2, 4, 1, 3}. Пары - 2-1 и 4-3. Облом.  Ужас

Хотя усечённый коэффициент Бухгольца выглядит несколько сомнительно - я предпочёл бы там не отнимать, а прибавлять..
  

пароль как коньяк, чем больше звездочек, тем лучше
Наверх
IP записан
 
JohnyDeath
1c++ power user
1c++ donor
Отсутствует



Сообщений: 3050
Местоположение: Волгоград
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Разминка для головы. Оптимальный алгоритм.
Ответ #27 - 22. Мая 2010 :: 17:19
Печать  
berezdetsky писал(а) 22. Мая 2010 :: 16:27:
JohnyDeath писал(а) 22. Мая 2010 :: 15:21:
Иван, а вот ты бы поверил без оглядки высказыванию о том, что "практически все пары складываются однозначно"?

Но ведь так и есть. Хотя я могу представить группу, для которой не будет существовать допустимого набора пар. "Сыграют и еще разок", IMHO, противоречит идее швейцарской системы.

Даже при кол-ве игроков = 4 мы смоделировали ситуацию, где этот алгоритм обламывается. Вариант "Сыграют и еще разок" мне кажется лучше вариантов: "остановить весь турнир" или "присвоит этим игрокам автоматом какое-то кол-во очков"

berezdetsky писал(а) 22. Мая 2010 :: 16:27:
Возможно, мы имеем ввиду разные алгоритмы. Я говорю о стандартном алгоритме генерации k-элементных подмножеств из комбинаторики.


У меня примерно такой:
Код
Выбрать все
Функция ПолучитьПарыДляИгр(спИгроковГруппы//:СписокЗначений
	,спВозможныхПар//:СписокЗначений
	)

	спНераспределенныхИгроков = СоздатьОбъект("СписокЗначений");
	спИгроковГруппы.Выгрузить(спНераспределенныхИгроков);

	Для й=1 По спВозможныхПар.РазмерСписка() Цикл
		Результат  = СоздатьОбъект("СписокЗначений");
		текПара = спВозможныхПар.ПолучитьЗначение(й);
		Результат.ДобавитьЗначение(текПара);
		ПолучитьИгроковПары(текПара, Игрок1, Игрок2);
		УдалитьИзСписка(спНераспределенныхИгроков, Игрок1, Игрок2);
		Если спНераспределенныхИгроков.РазмерСписка()=0 Тогда
			Возврат Результат;
		КонецЕсли;

		Для ж=1 По спВозможныхПар.РазмерСписка() Цикл
			текПара_2 = спВозможныхПар.ПолучитьЗначение(ж);
			Если текПара=текПара_2 Тогда Продолжить;		КонецЕсли;

			Результат.ДобавитьЗначение(текПара_2);
			ПолучитьИгроковПары(текПара_2, Игрок1, Игрок2);
			УдалитьИзСписка(спНераспределенныхИгроков, Игрок1, Игрок2);
			Если спНераспределенныхИгроков.РазмерСписка()=0 Тогда
				Возврат Результат;
			КонецЕсли;

		КонецЦикла;
	КонецЦикла;

	Возврат "Решений нет!";
КонецФункции	// ПолучитьПарыДляИгр 


Это он же?  Улыбка
  
Наверх
 
IP записан
 
berezdetsky
1c++ power user
Отсутствует


barba non facit sisadminum

Сообщений: 1986
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Разминка для головы. Оптимальный алгоритм.
Ответ #28 - 22. Мая 2010 :: 17:43
Печать  
JohnyDeath писал(а) 22. Мая 2010 :: 17:19:
Даже при кол-ве игроков = 4 мы смоделировали ситуацию, где этот алгоритм обламывается.

Нет. Мы получили ситуацию, которая решается перестановками. А вот что делать с ситуациями, которые таким образом не решаются - в википедии не написано. Там понадобится какой-то алгоритм перераспределения групп.

JohnyDeath писал(а) 22. Мая 2010 :: 17:19:
Это он же?  Улыбка

А это вообще работает? Если Результат пересоздаётся в цикле, а спНераспределенныхИгроков - нет?
  

пароль как коньяк, чем больше звездочек, тем лучше
Наверх
IP записан
 
JohnyDeath
1c++ power user
1c++ donor
Отсутствует



Сообщений: 3050
Местоположение: Волгоград
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Разминка для головы. Оптимальный алгоритм.
Ответ #29 - 22. Мая 2010 :: 17:52
Печать  
А, ну да. Строчки
Код
Выбрать все
спНераспределенныхИгроков = СоздатьОбъект("СписокЗначений");
спИгроковГруппы.Выгрузить(спНераспределенныхИгроков); 


надо тоже засунуть в цикл.

Работает или нет - не знаю, пока это всё только в голове и на листочках.
Думаешь, что не прокатит? (хотя я тоже в нем сомневаюсь  Улыбка )
  
Наверх
 
IP записан
 
Переключение на Главную Страницу Страницы: 1 [2] 3 
ОтправитьПечать