Форум OlegON > Компьютеры и Программное обеспечение > Операционные системы и программное обеспечение > Программирование

Построение алгоритма жеребьевки, нужна помощь... : Программирование

29.03.2024 8:34


28.09.2015 23:23
MWWRuza
 
Я правильно понял принцип разведения первых трех колонок?

Цитата:

01 - 08 - 16
02 - 09 - 17
03 - 10 - 18
04 - 11 - 19
05 - 12 - 20
06 - 13 - 21
07 - 14 - 22
08 - 15 - 23
09 - 16 - 24
10 - 17 - 25
11 - 18 - 01
12 - 19 - 02
13 - 20 - 03
14 - 21 - 04
15 - 22 - 05
16 - 23 - 06
17 - 24 - 07
18 - 25 - 08
19 - 01 - 09
20 - 02 - 10
21 - 03 - 11
22 - 04 - 12
23 - 05 - 13
24 - 06 - 14
25 - 07 - 15
За "шаг" взял 8 - больше, чем куоличество боев в самом больщом туре(4-том = 7), и меньше чем треть боев всего - 25/4 ~= 8...
Теперь, надо попробовать четвертую колонку заполнить, пока вручную, чтобы понять принцип...
ЗЫ Вот только потом, даже если сейчас расставим "циферки" красиво, без повторов, все рухнет, когда начнешь пересечения команд разводить
28.09.2015 23:46
MWWRuza
 
Да собственно, и с четвертой колонкой проблем нет, вот, со сдвигом на 1 относительно первой:
Цитата:

01 - 08 - 16 - 02
02 - 09 - 17 - 03
03 - 10 - 18 - 04
04 - 11 - 19 - 05
05 - 12 - 20 - 06
06 - 13 - 21 - 07
07 - 14 - 22 - 08
08 - 15 - 23 - 09
09 - 16 - 24 - 10
10 - 17 - 25 - 11
11 - 18 - 01 - 12
12 - 19 - 02 - 13
13 - 20 - 03 - 14
14 - 21 - 04 - 15
15 - 22 - 05 - 16
16 - 23 - 06 - 17
17 - 24 - 07 - 18
18 - 25 - 08 - 19
19 - 01 - 09 - 20
20 - 02 - 10 - 21
21 - 03 - 11 - 22
22 - 04 - 12 - 23
23 - 05 - 13 - 24
24 - 06 - 14 - 25
25 - 07 - 15 - 01
А вот дальше... Дальше очень муторно вручную разводить, тут уже "циферками" не обойдешься, вмешивается самый "неудобный" критерий - команды... Надо в программе алгоритм написать, чтобы НачТЗ развелась по этому принципу, а дальше уже старой моей процедурой развести команды попробовать(при этом - сохранять "неповторяемость"), и посмотреть, что получится...
29.09.2015 09:19
Shift
 
Если команд не больше чем количество боев в одном туре, то и так пересечения не будет. А если больше тогда тут надо выбирать, что важнее, что-бы меньше встречаться с коллегами по команде или дважды встречаться с представителем другой команды.
Но в любом случае чем меньше команд и чем больше сами команды, тем меньше данный алгоритм подходит. В этом случае только перебор всех вариантов (ну естественно с оптимизациями, что бы лишнее не просматривать).
И да,
Цитата:
За "шаг" взял 8 - больше, чем куоличество боев в самом больщом туре(4-том = 7), и меньше чем треть боев всего - 25/4 ~= 8...
Теперь, надо попробовать четвертую колонку заполнить, пока вручную, чтобы понять принцип...
ЗЫ Вот только потом, даже если сейчас расставим "циферки" красиво, без повторов, все рухнет, когда начнешь пересечения команд разводить
Последняя колонка перебором всех возможных вариантов.
Берёшь первую позицию и пытаешься туда кого-нибудь вставить, если вставил, то следующая позиция, если нет следующий пилот, если пилоты кончились, откат, ну и по кругу. Результат - либо расставятся не пересекаясь более одного раза, либо нет. А с командами если народу в ней не на много больше чем количество боев в одном туре и так должно хорошо получиться.
Например для 25 (с 1 по 7 в одной команде) если сдвинуть на 7 и (7+8) соответственно, то получается, что
есть одно персечение в первом туре (1 и 7) и возможны при худшем раскладе ещё 4 пересечения (2 в третьем и 2 в четвертом турах). Таким образом 5 командных пересечений из трех допустимых.
Но тут опять же что важнее? Непересечение внутри команды или непересечение дважды двух пилотов.
29.09.2015 09:55
MWWRuza
 
Ну, по пересечению команд, в принципе так - в этом конкретном примере:
Одна команда, "Алиса", состоит из 7-ми пилотов. Количество боев в турах - 6, 6, 6, 7. Соответственно, в трех боях трех туров будут по одному пересечению команд, этой самой Алисы... В данном случае, должно быть так, и никак больше. Надо тольео проконтолировать, что-бы в этих пересечениях разные пилоты участвовали, и дважды одн и тот же пилот в этой "коллизии" не учавствовал. В других командах, пересечений не должно быть в принципе! так, как следущая по размеру команда, из 4-х человек, а самый маленький тур - 6 боев. А повторы всех остальных, уже как получится, но, естественно, надо минимизировать...
29.09.2015 10:16
MWWRuza
 
Вобщем, идея понятна... Сегодня вечером, попробую реализовать... Изначально буду заполнять НачТЗ как мес. #33, а потом, производить передвижки в 4-той колонке для разведения команд, контролируя попутно повторы. Три колонки при таком заполнении изначально получатся без повторов и пересечений благодаря шагу сдвига...
29.09.2015 10:17
MWWRuza
 
Цитата:
MWWRuza как мес. #33
Ошибся, как в мес. #32.
29.09.2015 12:46
MWWRuza
 
Не утерпел, сделал, тем более, что в работе окошко было...

Но, что-то не айс... Или я чего-то не допонял, или где-то ошибся...
Первая колонка заполняется "как есть", по списку из документа "Этап", вторая колонка со сдвигом в 8 позиций, третья тоже со сдвигом относительно второй в 8 позиций, четвертая - в принципе, пока на нее не обращаем внимания, со сдвигом 1 относительно первой... Куча повторов и пересечений команд, в первых трех колонках... Я в чем-то ошибся, недопоняв алгоритм, или оно не работает? Сообразить не могу, уже голова квадратная... Вроде как, вчера когда с "циферками" игрался, казалось, что все нормально разводится...
Вот, во вложении экселевские таблички: Жеребьевка, ТаблицаПовторов.
29.09.2015 12:48
MWWRuza
 
Вот, код из 1С:
Код:
Функция ПолучитьШагСдвига(НачСЗ)
	ТзКолБоев 			= ПолКолБоевВТурах();
	ТзКолБоев.Сортировать("КолБоев-");
	МаксКолБоевВТуре 	= ТзКолБоев.ПолучитьЗначение(1,"КолБоев");
	ТретьОтКолБоевВсего	= Цел(НачСЗ.РазмерСписка() / 3);  
	Возврат Макс(МаксКолБоевВТуре,ТретьОтКолБоевВсего);
КонецФункции	

Процедура ЖеребьевкаПоШифт() 
	НачТЗ = СоздатьОбъект("ТаблицаЗначений"); 
	НачТЗ.НоваяКолонка("КрПилот");
	НачТЗ.НоваяКолонка("ЖтПилот");
	НачТЗ.НоваяКолонка("ЗлПилот");
	НачТЗ.НоваяКолонка("СнПилот");
	НачТЗ.НоваяКолонка("Тур","Число");
	НачТЗ.НоваяКолонка("Стык","Число"); // В этой колонке будем отражать количество "пристыкованных" из предыдущего тура колонок, СтыкНаНачало    
	НачСЗ	= СоздатьОбъект("СписокЗначений"); 
	ВыгрузитьТабличнуюЧасть(НачСЗ,"Пилот");
	Шаг 	= ПолучитьШагСдвига(НачСЗ);
	Для Сч = 1 По 4 Цикл
		Если Сч = 1 Тогда 
			СзРаб1 = СоздатьОбъект("СписокЗначений");
			НачСЗ.Выгрузить(СзРаб1);
			Для СчКрКол = 1 По СзРаб1.РазмерСписка() Цикл
				НачТЗ.НоваяСтрока();
				НачТЗ.КрПилот = СзРаб1.ПолучитьЗначение(СчКрКол);
			КонецЦикла;	
		ИначеЕсли Сч = 2 Тогда
			СзРаб2 = СоздатьОбъект("СписокЗначений");
			НачСЗ.Выгрузить(СзРаб2);
			Для СчСдвига = 1 По Шаг Цикл
				СзРаб2.СдвинутьЗначение(СзРаб2.РазмерСписка(),1);	
			КонецЦикла;
			Для СчЖтКол = 1 По СзРаб2.РазмерСписка() Цикл
				НачТЗ.УстановитьЗначение(СчЖтКол,"ЖтПилот",СзРаб2.ПолучитьЗначение(СчЖтКол));
			КонецЦикла;			
		ИначеЕсли Сч = 3 Тогда  
			СзРаб3 = СоздатьОбъект("СписокЗначений");
			СзРаб2.Выгрузить(СзРаб3);
			Для СчСдвига = 1 По Шаг Цикл
				СзРаб3.СдвинутьЗначение(СзРаб3.РазмерСписка(),1);	
			КонецЦикла;
			Для СчЗлКол = 1 По СзРаб3.РазмерСписка() Цикл
				НачТЗ.УстановитьЗначение(СчЗлКол,"ЗлПилот",СзРаб3.ПолучитьЗначение(СчЗлКол));
			КонецЦикла;			
		Иначе
			СзРаб4 = СоздатьОбъект("СписокЗначений");
			НачСЗ.Выгрузить(СзРаб4); 
			Для СчСдвига = 1 По 1 Цикл
				СзРаб4.СдвинутьЗначение(СзРаб4.РазмерСписка(),1);	
			КонецЦикла;
			Для СчСнКол = 1 По СзРаб4.РазмерСписка() Цикл
				НачТЗ.УстановитьЗначение(СчСнКол,"СнПилот",СзРаб4.ПолучитьЗначение(СчСнКол));
			КонецЦикла;			
		КонецЕсли;	
	КонецЦикла;	
	НачТЗ = ЗаполнитьКолонкиТурСтык(НачТЗ);
	ТзПовт = ПолучитьТЗПовторов();
	
	НапечататьТзПовторов(ТзПовт);
	ПечатьДляНаглядности(НачТЗ);
КонецПроцедуры
29.09.2015 13:37
MWWRuza
 
Вобщем, если отсортировать предварительно исходный список по командам, то команды в первых трех колонках разводятся. Но, повторы в тех-же трех колонках все равно остаются...
Вот: Жеребьевка, Таблица повторов.
29.09.2015 16:20
MWWRuza
 
Сделал вывод в печатную форму номеров позиций пилотов в исходном списке, и сразу увидел, где у меня неточность - при шаге = 7, третью колонку надо с 16 начинать, а не с 15... (Хотя, пока не понял - почему?)
Вот так:
01 - 08 - 16 - 02
тогда разводится без повторов по всем 4 колонкам, и без пересечения команд в первых трех...
Буду изучать полученную табличку дальше...
Часовой пояс GMT +3, время: 08:34.

Форум на базе vBulletin®
Copyright © Jelsoft Enterprises Ltd.
В случае заимствования информации гипертекстовая индексируемая ссылка на Форум обязательна.