Мне нужно эмулировать стратегию размещения окон оконного менеджера Fluxbox.
Приблизительно представьте, что окна произвольного размера заполняют экран одно за другим, при этом приблизительный размер каждого из них дает в среднем 80 окон на экране, при этом ни одно окно не перекрывается другим.
Если в вашей системе установлены Fluxbox и Xterm, вы можете попробовать xwinmidiarptoy BASH-скрипт, чтобы увидеть грубый прототип того, что я хочу. См. примечания xwinmidiarptoy.txt, которые я сделал написано об этом, объясняя, что он делает и как его следует использовать.
Важно отметить, что окна закроются, а пространство, которое ранее занимало закрытые окна, снова станет доступным для размещения новых окон.
Алгоритм должен быть Онлайн-алгоритм, обрабатывающий данные "по частям". -кусок в последовательном порядке, т. е. в том порядке, в котором ввод подается в алгоритм, без того, чтобы весь ввод был доступен с самого начала».
Стратегия размещения окна Fluxbox имеет три бинарных варианта, которым я хочу подражать:
Windows строит горизонтальные строки или вертикальные столбцы (потенциально)
Окна располагаются слева направо или справа налево
Окна располагаются сверху вниз или снизу вверх
Различия между целевым алгоритмом и алгоритмом размещения окна
Единицы координат не являются пикселями. Сетка, в которой будут размещаться блоки, будет иметь размер 128 x 128 единиц. Кроме того, область размещения может быть дополнительно уменьшена за счет граничной области, помещенной в сетку.
Почему алгоритм является проблемой?
Он должен работать в соответствии со сроками потока реального времени в аудиоприложении.
В данный момент меня интересует только получение быстрого алгоритма, не беспокойтесь о последствиях потоков в реальном времени и всех препятствиях в программировании, которые это приносит.
И хотя алгоритм никогда не поместит окно, которое перекрывает другое, пользователь сможет размещать и перемещать определенные типы блоков, перекрывающиеся окна будут существовать. Структура данных, используемая для хранения окон и/или свободного пространства, должна справляться с этим перекрытием.
Пока у меня есть два варианта, для которых я создал свободные прототипы:
1) Порт алгоритма размещения Fluxbox в моем коде.
Проблема в том, что клиент (моя программа) вылетает из аудиосервера (JACK), когда я пытаюсь разместить наихудший сценарий из 256 блоков с использованием алгоритма. Этот алгоритм выполняет более 14000 полных (линейных) сканирований списка уже размещенных блоков при размещении 256-го окна.
Для демонстрации этого я создал программу под названием text_boxer-0.0.2.tar.bz2, который принимает текстовый файл в качестве входных данных и упорядочивает его в полях ASCII. Выпустите make
, чтобы построить его. Немного недружелюбно, используйте --help
(или любой другой недопустимый параметр) для списка параметров командной строки. Вы должны указать текстовый файл с помощью параметра.
2) Мой альтернативный подход.
Реализованный лишь частично, этот подход использует структуру данных для каждой области прямоугольного свободного неиспользуемого пространства (список окон может быть полностью отдельным и не требуется для тестирования этого алгоритма). Структура данных действует как узел в двусвязном списке (с отсортированной вставкой), а также содержит координаты левого верхнего угла, ширину и высоту.
Кроме того, структура данных каждого блока также содержит четыре ссылки, которые соединяются с каждым непосредственно соседним (соприкасающимся) блоком на каждой из четырех сторон.
ВАЖНОЕ ПРАВИЛО: каждый блок может соприкасаться только с одним блоком с каждой стороны. Это правило специфично для алгоритма хранения свободного неиспользуемого пространства и не влияет на то, сколько фактических окон могут соприкасаться друг с другом.
Проблема с этим подходом в том, что он очень сложен. Я реализовал простые случаи, когда 1) пространство удалено из одного угла блока, 2) разделение соседних блоков, чтобы соблюдалось ВАЖНОЕ ПРАВИЛО.
Менее простой случай, когда пространство, которое нужно удалить, можно найти только в столбце или строке блоков, реализуется лишь частично — если один из удаляемых блоков точно соответствует ширине (т. е. столбцу) или высоте (т. е. ряд), то возникают проблемы. И даже не упоминайте тот факт, что при этом проверяются только столбцы шириной в один квадрат и строки высотой в один квадрат.
Я реализовал этот алгоритм на C - языке, который я использую для этого проекта (я не использовал C++ в течение нескольких лет, и мне неудобно его использовать после того, как я сосредоточил все свое внимание на разработке C, это хобби). Реализация состоит из 700+ строк кода (включая множество пустых строк, фигурных скобок, комментариев и т. д.). Реализация работает только для стратегии размещения горизонтальные ряды + лево-право + верх-низ.
Так что я должен либо добавить какой-то способ заставить эти +700 строк кода работать для других 7 вариантов стратегии размещения, либо мне придется продублировать эти +700 строк кода для других семи вариантов. Ни один из них не привлекателен, первый из-за того, что существующий код достаточно сложен, второй из-за наворотов.
Алгоритм даже не находится на той стадии, когда я могу использовать его в наихудшем сценарии реального времени из-за отсутствия функциональности, поэтому я до сих пор не знаю, действительно ли он работает лучше или хуже, чем первый подход.
Текущее состояние реализации этого алгоритма на C: freespace.c а>. Я использую gcc -O0 -ggdb freespace.c
для сборки и запускаю его в xterm размером не менее 124 x 60 символов.
Что еще?
Я пролистал и сделал скидку:
Алгоритмы Bin Packing: упор на оптимальное соответствие не соответствует требованиям этого алгоритма.
Алгоритмы Recursive Bisection Placement: звучит многообещающе, но они предназначены для проектирования схем. Их упор делается на оптимальную длину провода.
Оба из них, особенно последний, все элементы, которые должны быть размещены/упакованы, известны до начала алгоритма.
Что вы думаете об этом? Как бы вы подошли к этому? На какие еще алгоритмы следует обратить внимание? Или даже какие концепции мне следует исследовать, поскольку я не изучал информатику/программную инженерию?
Пожалуйста, задавайте вопросы в комментариях, если нужна дополнительная информация.
После того, как вы задали этот вопрос, возникли дополнительные идеи
- Некоторая комбинация моего «альтернативного алгоритма» с пространственной хэш-картой для определения того, будет ли размещаемое большое окно покрывать несколько блоков свободного пространства.