Ремонт принтеров, сканнеров, факсов и остальной офисной техники


назад Оглавление вперед




[264]

35.5 Исполнение алгоритма Any-Segment-Intersect. Положения движущейся прямой в критических точках показаны пунктиром; рядом выписаны пересекаемые отрезки (в порядке сверху - вниз) в момент сразу после прохода критической точки, Пересечение отрезков dub обнаруживается после удаления отрезка с.

через его правый конец.

Состояние дел у прямой можно хранить как упорядоченное множество отрезков, с которым выполняются следующие операции:

Insert (Г, s) : добавить отрезок s в Г;

Delete (Г, s) : удалить отрезок s из Г;

Above (Г, s) : указать отрезок, располагающийся непосредственно выше s в множестве Г;

Below (Г, s) : возвращает отрезок, располагающийся непосредственно ниже s в множестве Т.

(Говоря об отношении порядка в Г, мы описываем слова «выше» и «ниже» в соответствии с геометрическим смыслом этого отношения.)

Мы можем хранить (линейно) упорядоченное множество из п отрезков и выполнять любую из указанных операций за время О (lg п), используя красно-чёрное дерево, Заметим, что операции сравнения (какой из отрезков выше в данный момент) можно выполнить за время 0(1), используя векторные произведения (см. упр. 35.2-2).

Проверка пересечений

Построим алгоритм, который по заданному множеству S, состоящему из п отрезков, проверяет, есть ли среди них хотя бы два пересекающихся. Этот алгоритм использует красно-чёрное дерево для хранения текущего состояния дел у движущейся прямой.

Any-Segment-Intersect(S)

1Т \gets \emptyset

2сортируем концы отрезков в порядке возрастания абсцисс (точки

с равными абсциссами идут в порядке возрастания ординат); проверяем, нет ли совпадающих точек среди концов (если есть -возвращаем true)

3\emph{for} (для) каждой точки $р$ из полученного списка

4\emph{do} if $р$ --- левый конец некоторого отрезка $s$

5\emph{then} Insert (Т, s )

6\emph{if} (Above (T, s) существует и пересекает s)

(Below (T, s) существует и пересекает s)

7\emph{then return} true

8\emph{if} $p$ правый конец некоторого отрезка $s$

9\emph{then if} определены Above (T, s) и Below

и (Above (T, s) пересекает

10\emph{then return} true

11Deleted, s)


12 \emph{return} false

На рис. 35.5 показано выполнение алгоритма. Изначально множество Г пусто (строка 1). В строке 2 строится расписание ожидаемых событий, соответствующих концам отрезков (вообще-то критическими точками являются также моменты пересечения отрезков, но после обнаружения такого пересечения алгоритм заканчивает работу сразу же, так что эти моменты мы смело можем игнорировать.

Каждая итерация цикла for в строках 3-11 обрабатывает одну критическую точку. Если она соответствуют левому концу некоторого отрезка s, то в строке 5 этот отрезок добавляется в упорядоченное множество, а в строках 6-7 проверяется, не пересекается ли он часом с одним из соседних отрезков (если да, то алгоритм кончает работу и даёт ответ true). (Возможно, что критическая точка соответствует концам нескольких отрезков - в этом случае они добавляются один за другим.)

Если обрабатываемая критическая точка является правым концом некоторого отрезка s, то этот отрезок удаляется из Г (строка 11); предварительно проверяется, не пересекаются ли отрезки, которые разделял удаляемый отрезок и которые теперь становятся соседними (строки 9-10)

Так делается для всех концов всех отрезков; если при этом пересечение так и обнаруживается, то алгоритм возвращает false (строка 12).

Правильность алгоритма

Теорема 35.1

Процедура Any-Segment-Intersect(S) возвращает true в том и только том случае, когда среди отрезков множества S есть пересекающиеся.

Доказательство.

Заметим, что значение true возвращается лишь после того, как обнаружены два пересекающихся отрезка. Поэтому надо лишь проверить, что если в S есть пара пересекающихся отрезков, то она будет обнаружена.

Предположим теперь, что алгоритм не возвращает значения true, а просматривает по очереди все концы отрезков, не находит пересечения и возвращает значение false. Покажем, что в таком случае отрезки не пересекаются.

Рассмотрим сначала случай, когда концы всех отрезков имеют различные абсциссы. Тогда на каждой итерации цикла рассматривается новое значение абсциссы. Докажем, что при этом остаются верными такие свойства:

(a)множество Г соответствует положению прямой непосредственно справа от последней обработанной абсциссы;

(b)соседние в множестве Г отрезки не пересекаются.


Вначале эти свойства выполнены (Г пусто, движущаяся прямая не пересекает ни одного из отрезков, находясь слева от всех них). Проверим, что они остаются выполненными после прохода через один из концов (другими словами, после очередной итерации цикла).

Если очередная точка есть левый конец отрезка, то появляется новая точка пересечения с движущейся прямой. Начинающийся в ней отрезок не пересекается с соседними (в смысле текущего состояния множества Г) отрезками, иначе это было бы обнаружено. Остальные пары соседних отрезков были соседними раньше, так что мы уже знаем, что они не пересекаются.

Раз соседние отрезки не пересекаются, то на участке до следующего значения абсциссы в списке относительный порядок сохраняется (точка пересечения может быть только у несоседних отрезков и только после конца того отрезка, который их разделял).

Пусть теперь очередная точка есть правый конец отрезка. Тогда из множества Г удаляется элемент (как и полагается, если мы хотим, чтобы Г соответствовало положению прямой справа от очередной точки). Появляется новая пара соседних отрезков - про которую алгоритм проверяет, что они не пересекаются. По тем же причинам, что и раньше, можно утверждать, что до следующего значения абсциссы относительный порядок сохраняется.

Итак, свойства (а) и (Ь) проверены, и заодно доказано, что никакие два отрезка не пересекаются. В самом деле, раз между рассматриваемыми абсциссами порядок сохраняется, между ними пересечение невозможно; а при прохождении движущейся прямой через конец отрезка пересечение также невозможно, так как некоторые пересекающиеся отрезки были бы соседними слева или справа от прямой.

Осталось разобраться, почему наше рассуждение применимо к случаю, когда несколько концов отрезков лежат на одной вертикали (но не совпадают - это проверяется при сортировке концов отрезков). Это можно объяснить так: представим себе, что движущаяся прямая чуть-чуть наклонена влево (против часовой стрелки). Тогда она будет пересекать концы отрезков в разные (хотя, возможно, очень близкие) моменты времени, и просматриваться они будут как раз в нужном порядке (точки с одинаковой абсциссой - в порядке возрастания ординат). Тем самым можно свести дело к уже разобранному случаю (проверяться на пересечение будут те же пары отрезков, что и с воображаемой наклонённой прямой).

Время работы.

Если множество S состоит из га отрезков, то время работы алгоритма Any-Segment-Intersect есть O(ralgra). В самом деле, сортировку можно выполнить за такое время (сортировку слиянием или с помощью двоичной кучи), затем мы обрабатываем 2га концов отрезков, тратя на каждый время О (lgra) (таково время любой ис-



[стр.Начало] [стр.1] [стр.2] [стр.3] [стр.4] [стр.5] [стр.6] [стр.7] [стр.8] [стр.9] [стр.10] [стр.11] [стр.12] [стр.13] [стр.14] [стр.15] [стр.16] [стр.17] [стр.18] [стр.19] [стр.20] [стр.21] [стр.22] [стр.23] [стр.24] [стр.25] [стр.26] [стр.27] [стр.28] [стр.29] [стр.30] [стр.31] [стр.32] [стр.33] [стр.34] [стр.35] [стр.36] [стр.37] [стр.38] [стр.39] [стр.40] [стр.41] [стр.42] [стр.43] [стр.44] [стр.45] [стр.46] [стр.47] [стр.48] [стр.49] [стр.50] [стр.51] [стр.52] [стр.53] [стр.54] [стр.55] [стр.56] [стр.57] [стр.58] [стр.59] [стр.60] [стр.61] [стр.62] [стр.63] [стр.64] [стр.65] [стр.66] [стр.67] [стр.68] [стр.69] [стр.70] [стр.71] [стр.72] [стр.73] [стр.74] [стр.75] [стр.76] [стр.77] [стр.78] [стр.79] [стр.80] [стр.81] [стр.82] [стр.83] [стр.84] [стр.85] [стр.86] [стр.87] [стр.88] [стр.89] [стр.90] [стр.91] [стр.92] [стр.93] [стр.94] [стр.95] [стр.96] [стр.97] [стр.98] [стр.99] [стр.100] [стр.101] [стр.102] [стр.103] [стр.104] [стр.105] [стр.106] [стр.107] [стр.108] [стр.109] [стр.110] [стр.111] [стр.112] [стр.113] [стр.114] [стр.115] [стр.116] [стр.117] [стр.118] [стр.119] [стр.120] [стр.121] [стр.122] [стр.123] [стр.124] [стр.125] [стр.126] [стр.127] [стр.128] [стр.129] [стр.130] [стр.131] [стр.132] [стр.133] [стр.134] [стр.135] [стр.136] [стр.137] [стр.138] [стр.139] [стр.140] [стр.141] [стр.142] [стр.143] [стр.144] [стр.145] [стр.146] [стр.147] [стр.148] [стр.149] [стр.150] [стр.151] [стр.152] [стр.153] [стр.154] [стр.155] [стр.156] [стр.157] [стр.158] [стр.159] [стр.160] [стр.161] [стр.162] [стр.163] [стр.164] [стр.165] [стр.166] [стр.167] [стр.168] [стр.169] [стр.170] [стр.171] [стр.172] [стр.173] [стр.174] [стр.175] [стр.176] [стр.177] [стр.178] [стр.179] [стр.180] [стр.181] [стр.182] [стр.183] [стр.184] [стр.185] [стр.186] [стр.187] [стр.188] [стр.189] [стр.190] [стр.191] [стр.192] [стр.193] [стр.194] [стр.195] [стр.196] [стр.197] [стр.198] [стр.199] [стр.200] [стр.201] [стр.202] [стр.203] [стр.204] [стр.205] [стр.206] [стр.207] [стр.208] [стр.209] [стр.210] [стр.211] [стр.212] [стр.213] [стр.214] [стр.215] [стр.216] [стр.217] [стр.218] [стр.219] [стр.220] [стр.221] [стр.222] [стр.223] [стр.224] [стр.225] [стр.226] [стр.227] [стр.228] [стр.229] [стр.230] [стр.231] [стр.232] [стр.233] [стр.234] [стр.235] [стр.236] [стр.237] [стр.238] [стр.239] [стр.240] [стр.241] [стр.242] [стр.243] [стр.244] [стр.245] [стр.246] [стр.247] [стр.248] [стр.249] [стр.250] [стр.251] [стр.252] [стр.253] [стр.254] [стр.255] [стр.256] [стр.257] [стр.258] [стр.259] [стр.260] [стр.261] [стр.262] [стр.263] [стр.264] [стр.265] [стр.266] [стр.267] [стр.268] [стр.269] [стр.270] [стр.271] [стр.272] [стр.273] [стр.274] [стр.275] [стр.276] [стр.277] [стр.278] [стр.279] [стр.280] [стр.281] [стр.282] [стр.283] [стр.284] [стр.285] [стр.286] [стр.287] [стр.288] [стр.289] [стр.290] [стр.291] [стр.292] [стр.293] [стр.294]