gis doc123

137
СОДЕРЖАНИЕ Введение ……………………………………………………………………… 8 1. ТЕХНИКО-ЭКОНОМИЧЕСКОЕ ОБОСНОВАНИЕ ……………………. 10 1.1. Характеристика объекта и существующей системы управления ……. 10 1.2. Цели и основные показатели системы управления ……..……………. 11 1.3. Функции и задачи системы управления ………………………………. 12 1.4. Ожидаемые технико-экономические результаты …………………….. 13 1.5. Выводы и предложения ………………………………………………… 21 2. ТЕОРЕТИЧЕСКИЕ ИССЛЕДОВАНИЯ ………………………………… 22 2.1. Задачи, подлежащие решению ………………………………………… 22 2.2. Формализация задачи и результаты исследований ………………….. 22 3. СИСТЕМОТЕХНИЧЕСКИЕ ПРОЕКТНЫЕ РЕШЕНИЯ ……………… 25 3.1. Обоснование и характеристика проектных решений по функциональному и организационному обеспечению системы ………….. 25 3.2. Обоснование и характеристика проектных решений по информационному обеспечению системы …………………………………. 29 3.3. Обоснование и характеристика проектных решений по техническому обеспечению системы ……………………………………………………….. 40 3.4. Алгоритмы функционирования ………………………………………… 42 3.5. Обоснование и характеристика проектных решений по программному обеспечению системы …………………………………….. 53 4. КОНСТРУКТОРСКО-ТЕХНОЛОГИЧЕСКИЕ ПРОЕКТНЫЕ РЕШЕНИЯ …………………………………………………………………… 55 4.1. Выбор инструментальных средств …………………………………….. 55 4.2. Формы …………………………………………………………………… 58 5. БЕЗОПАСНОСТЬ ЖИЗНЕДЕЯТЕЛЬНОСТИ ………………………….. 62 5.1. Анализ опасных и вредных факторов …………………………………. 62

Upload: independent

Post on 25-Jan-2023

3 views

Category:

Documents


0 download

TRANSCRIPT

СОДЕРЖАНИЕ

Введение ……………………………………………………………………… 81. ТЕХНИКО-ЭКОНОМИЧЕСКОЕ ОБОСНОВАНИЕ ……………………. 101.1. Характеристика объекта и существующей системы управления ……. 101.2. Цели и основные показатели системы управления ……..……………. 111.3. Функции и задачи системы управления ………………………………. 121.4. Ожидаемые технико-экономические результаты …………………….. 131.5. Выводы и предложения ………………………………………………… 212. ТЕОРЕТИЧЕСКИЕ ИССЛЕДОВАНИЯ ………………………………… 222.1. Задачи, подлежащие решению ………………………………………… 222.2. Формализация задачи и результаты исследований ………………….. 223. СИСТЕМОТЕХНИЧЕСКИЕ ПРОЕКТНЫЕ РЕШЕНИЯ ……………… 253.1. Обоснование и характеристика проектных решений по функциональному и организационному обеспечению системы ………….. 253.2. Обоснование и характеристика проектных решений по информационному обеспечению системы …………………………………. 293.3. Обоснование и характеристика проектных решений по техническому обеспечению системы ……………………………………………………….. 403.4. Алгоритмы функционирования ………………………………………… 423.5. Обоснование и характеристика проектных решений по программному обеспечению системы …………………………………….. 534. КОНСТРУКТОРСКО-ТЕХНОЛОГИЧЕСКИЕ ПРОЕКТНЫЕ РЕШЕНИЯ …………………………………………………………………… 554.1. Выбор инструментальных средств …………………………………….. 554.2. Формы …………………………………………………………………… 585. БЕЗОПАСНОСТЬ ЖИЗНЕДЕЯТЕЛЬНОСТИ ………………………….. 625.1. Анализ опасных и вредных факторов …………………………………. 62

5.2. Характеристики лаборатории ………………………………………….. 625.3. Шум и вибрация ………………………………………………………… 625.4. Вентиляция ……………………………………………………………… 625.5. Отопление ……………………………………………………………….. 625.6. Метеорологические условия в лаборатории ………………………….. 625.7. Освещение ………………………………………………………………. 635.8. Средства индивидуальной защиты ……………………………………. 645.9. Электробезопасность …………………………………………………… 645.10. Защита от статического электричества и молниезащита …………… 655.11. Пожарная профилактика ………………………………………………. 655.12. Утилизация отходов и охрана окружающей среды ………………….. 665.13. Охрана труда …………………………………………………………… 66ЗАКЛЮЧЕНИЕ ………………………………………………………………. 67СПИСОК ИСПОЛЬЗОВАННОЙ ЛИТЕРАТУРЫ …………………………. 68ПРИЛОЖЕНИЕ ………………………………………………………………. 69

ВВЕДЕНИЕ

Контроль и качество городских трубопроводов

представляется в виде условной схемы, которую

пользователь АИС имеет возможность проектировать и

сохранять в базе данных с использованием инструментальных

средств АИС. При проектировании пользователь наносит на

схему условные обозначения объектов геосреды и определяет

значения параметров, характеризующих эти объекты.

Объекты геосреды, в соответствии со значениями тех

или иных параметров, могут являться ограничителями

качества трубопроводов , т. е. определенным образом

8

влиять на их состояние , поэтому при расчете оптимального

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

соответствующих параметров объектов-ограничителей.

Записка содержит четыре раздела:

1.Раздел “Технико-экономическое обоснование”, в котором

содержится описание системы управления, раскрываются

цели, функции и задачи системы, рассчитываются технико-

экономические показатели затрат на разработку данной

системы.

2.Раздел “Теоретические исследования”. В него входит

исследование вопросов, связанных с задачей оптимизации

качества городских трубопроводов , а также формализация

этой задачи.

3.Раздел “Системотехнические проектные решения”. Данный

раздел содержит описание функционального состава АИС,

организационного, информационного, и технического

обеспечения АИС, а также алгоритмы функционирования и

технологический процесс обработки информации в системе.

4.Раздел “Конструкторско-технологические проектные

решения” содержит описание выбора инструментальных

средств и его обоснование, выбор форм представления

выходных данных и разработку инструкции пользователя.

5.Раздел “Безопасность жизнедеятельности”.

Завершает пояснительную записку приложение, которое

включает в себя листинги основных программ.

9

1. ТЕХНИКО-ЭКОНОМИЧЕСКОЕ ОБОСНОВАНИЕ

1.1. Характеристика объекта и существующей системы

управления

АИС связана с оптимизацией качества городских

трубопроводов по внешним и гидравлическим параметрам,

поэтому безусловно представляет интерес для достаточно

широкого круга пользователей, можно сказать для всего

города, с точки зрения повышения эффективности работы,

качества предоставляемых услуг, а также экономии средств.

АИС имеет большую практическую значимость, поскольку

позволяет увеличить время эксплуатации городских

трубопроводов путем повышения оперативности принятия

решений при контроле над ними. Кроме того, повышается

надежность принятия правильных решений, достоверность

получаемой информации. АИС позволяет хранить информацию в

больших объемах.

Внедрение АИС не требует значительных финансовых

затрат.

10

1.2. Цели и основные показатели системы управления

Одной из целей разработки любой АСОИУ является

повышение оперативности (повышение управляемости

объекта), снижение затрат на принятие решений.

Представим цели и задачи АИС графически в виде

дерева.

11

Увеличение времени, затрачиваемого наэксплуатацию трубопроводов

Повышение оперативности контроля надгородскими трубопроводами

Средство достижения основнойцели

Задача АИС

Нахождение путей решения качественнойработы трубопровов

Получениекачественныхтрубопроводов

Получениемаксимального

времениэксплуатации

Лицо, принимающеерешения

Пользователь

Декомпозиция задач

12

1.3. Функции и задачи системы управления

Для снижения времени, затрачиваемого на строительство

подземных коммуникаций , необходимо повышение

оперативности принятия решений о выборе того или иного

места строительства. Программное обеспечение,

разработанное для достижения поставленной цели, выполняет

следующие основные функции:

предоставление удобного пользовательского интерфейса,

позволяющего легко задавать исходные для оптимизации

качества труб данные и различные настройки, а также

представлять полученные результаты в виде наглядных

схем;

расчет строительства надежных подземных коммуникаций;

обработка и анализ полученных результатов;

хранение параметров спроектированной схемы,

представляющей собой географическую среду, в рамках

которой происходит строительство подземных

коммуникаций;

предоставление достаточно быстрого доступа к хранимым

данным с целью их анализа и модификации.

На основе данных, полученных в результате

использования разработанного программного обеспечения,

пользователь получает возможность оперативно принимать

правильные решения о выборе оптимальных для строительства

мест городских коммуникаций.

13

1.4. Ожидаемые технико-экономические результаты

Система позволяет автоматизировать процесс сбора

данных, а также наглядно отобразить всю необходимую

пользователю информацию на дисплее компьютера.

Все исходные данные и внесенные изменения заносятся в

базу данных и могут храниться там неограниченное время.

Эти качества проекта позволяют:

Повышать надежность обработки и хранения информации.

Повышать скорость реагирования оператора на различные

изменения в системе.

Вести строгую отчетность обо всех изменениях и

состоянии системы.

Проектируемая система снабжена меню, различными

подсказками и обозначениями на русском языке, что

приводит к простоте ее использования и малому времени

обучения персонала.

Для функционирования системы достаточно одного IBM PC

совместимого персонального компьютера необходимой

конфигурации под управлением операционной системы

Microsoft Windows.

В качестве информационного обеспечения используется

документация на составление схем маршрутов движения

транспортных средств.

Срок разработки - 2 месяца.

14

В данной работе затраты на разработку системы

произведены по следующим статьям:

1. Затраты на материалы и комплектующие;

2. Основная и дополнительная заработная плата

исполнителей;

3. Отчисления на единый социальный налог;

4. Амортизация оборудования;

5. Затраты на электроэнергию;

6. Накладные расходы.

1.5. Выводы и предложения.

В России и странах СНГ аналогов разработанной АИС не

существует. Система при осуществлении незначительных

изменений может быть внедрена в любую организацию, работа

которой так или иначе связана с городской коммуникацией,

поэтому область применения АИС достаточно широка.

15

2. ТЕОРЕТИЧЕСКИЕ ИССЛЕДОВАНИЯ

2.1. Задачи, подлежащие решению.

Задачи, подлежащие решению с учетом характеристик

объектов геосреды:

Вычисление критерий строительства надежных

трубопроводов;

Вычисление критерий строительства долговечности

трубопроводов;

нахождение оптимального места строительства городских

коммуникаций по критериям надежности и долговечности;

наглядное представление оптимальных объектов

строительства на схеме с указанием минимального расхода

средств на строительство.

Все вышеуказанные задачи технически реализуемы при

помощи средств вычислительной техники.

2.2. Формализация задачи и результаты исследований.

Географическая среда (геосреда), в рамках которой

может проходить строительство городских коммуникаций,

является сложной системой больших масштабов,

следовательно, определение ее наиболее характерных,

существенных параметров является весьма непростой

задачей.

16

С точки зрения оптимизации строительства городских

коммуникаций и контроля за ними интерес может

представлять информация обо всей инфраструктуре геосреды:

жилые, промышленные здания. Можно разделить объекты

геосреды на две большие группы:

динамические объекты;

статические объекты.

Под динамическим объектом можно понимать любой

объект, наиболее характерной и существенной чертой

которого является способность менять свое местоположение

(например, транспортное средство). Динамический объект

характеризуется следующими атрибутами (в скобках даны

примеры):

уникальный идентификатор

описание

характеристики

Статический объект геосреды однозначно не способен к

движению (например, дом). Среди множества атрибутов,

присущих статическим объектам, можно выделить уникальный

идентификатор (номер дома вкупе с названием улицы) и

некоторое описание.

Среди множества статических объектов геосреды можно

выделить две большие группы:

объекты, не влияющих на процесс строительства городских

коммуникаций.

17

объекты, влияющие на процесс строительства городских

коммуникаций.

К ограничителям можно отнести:

- запрещены любые строительные и иные постройки,

другая же, разрешены при строгом соблюдении всех норм и

требований.

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

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

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

- санитарная зона автомобильных и железных дорог.Учёт зоны определяет категория и тип дороги. Средниеразмеры запретной территории под постройки от 25 до 500метров.

- санитарно-промышленные зоны (Очистные сооружения,кладбища, автозаправочные станции, газопроводы,электростанции) Территория определяется от 100 до 2000метров.

18

- объекты культурного наследия. Территорияохраняемой зоны от любых построек определяетсяиндивидуально и рассматривается каждый отдельный случай.

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

- охраняемая природная территория. К этим зонамотносят земли национальных парков, природныхзаповедников, лечебно-оздоровительных пансионатов икурортов. Застройка разрешена при выполнении особойправовой документации с учётом установленного режима.

При анализе строительства подземных коммуникаций

необходимо различать следующие типы ограничителей:

запрет на строительство определенном направлении;

возможный временный запрет на строительство;

ограничитель, не запрещающий строительство, но делающий

его нежелательным на данном участке.

Введем понятие «участок строительства », под которым

будем понимать некоторую логически неделимую часть

объекта в рамках которой будет прокладываться

трубы ,которая характеризуется следующими атрибутами:

площадь;

координаты начала и координаты конца участка

строительства;

19

возможное направление прокладки трубопроводов (либо

только в одну сторону, либо только в другую, либо

прокладка по данному участку трубопроводов вообще

невозможно);

максимально возможная на данном участке прокладка

трубопроводов в данный момент времени.

Объекты-ограничители напрямую влияют на значения

атрибутов именно участков строительства, а поскольку

объекты строительства могут проходить только через

участки строительства, то ограничители косвенно влияют и

на характер прокладки и самих трубопроводов.

20

3. СИСТЕМОТЕХНИЧЕСКИЕ ПРОЕКТНЫЕ РЕШЕНИЯ

3.1. Обоснование и характеристика проектных решений по

функциональному и организационному обеспечению системы

3.1.1 Уточнение первоначального списка задач

АИС проектирования и оптимизации объектов

строительства или ремонта городских коммуникаций является

однопользовательской. Не существует строгой периодичности

принятия пользователем любых решений во время проведения

проектирования и оптимизации строительства или ремонта

городских коммуникаций. Характеристика результатов всех

задач АИС – получение справочной информации.

Список функциональных задач АИС:

получение значения кратчайшего расстояния;

получение значения минимального времени строительства;

выбор объектов строительства.

Под значением кратчайшего расстояния понимается сумма

длин участков строительства, по которым пролегает

кратчайший маршрут прокладки трубопроводов. Минимальное

время находится путем нахождения отношения значения длины

участков строительства, к значению средней скорости

выполнения работы.

21

Выбор оптимальных объектов строительства производится

в соответствии со значениями кратчайшего расстояния или

минимального времени.

22

3.1.2. Определение результатов решения задач

Таблица 3.1.2.1. Список принимаемых решений

№Наименование результата

решения задачиПринимаемые решения

1Значение кратчайшего

расстояния

Выводы о размере финансовых

затрат на осуществление

процесса достижения пункта

назначения

2Значение минимального

времени

Прогноз о затратах времени

на процесс достижения пункта

назначения

3Выбор оптимального

объекта строительства

Решение начать работу по

найденному объекту

Таблица 3.1.2.2. Документы для подготовки решений

№ Наименование задачиНаименование документов для

подготовки принятия решения

1Получение значения

кратчайшего расстояния

1.Список значений длин

участков строительства

2.Список крайних точек

участков строительства2 Получение значения

минимального времени

1.Список значений длин

участков строительства

2.Список значений

23

максимальной скорости

движения по участку

3.Список крайних точек

участков строительства

3 Выбор маршрутов движения

1.Список участков

строительства,

соответствующих

кратчайшему маршруту

2.Список участков движения,

соответствующих

минимальному времени

строительства

3.Список крайних точек

участков строительства

Таблица 3.1.2.3. Состав документов

№ Наименование документа Наименование реквизита

1Список значений длин

участков движения

Код первой крайней точки

Код второй крайней точки

Направление движения

Значение длины участка

строительства2 Список значений

максимальной скорости

строительства по

выбранному объекту

Код первой крайней точки

Код второй крайней точки

Направление движения

Значение максимальной

24

скорости

3Список крайних точек

участков строительства

Код точки

Координата X

Координата Y

4

Список участков

строительства,

соответствующих

кратчайшему маршруту

Код первой крайней точки

Код второй крайней точки

Направление строительства

Значение длины участка

строительства

Значение максимальной

скорости

5

Список участков

движения,

соответствующих

минимальному времени

строительства

Код первой крайней точки

Код второй крайней точки

Направление движения

Значение длины участка

строительства

Значение максимальной

скорости

3.1.3. Определение исходных данных и источников

информации

25

Таблица 3.1.3.1.

№ Наименование задачи Наименования входных

документов1 Получение значения

кратчайшего расстояния

1.Список крайних точек

участков строительства

2.Список направлений участков

строительства

3.Список значений длин

участков строительства2 Получение значения

минимального времени

1.Список крайних точек

участков строительства

2.Список направлений участков

строительства

3.Список значений

максимального времени3 Выбор оптимальных

маршрутов

1.Список крайних точек

участков строительства

2.Список направлений участков

строительства

3.Список значений

максимального времени

4.Список значений длин

участков строительства

26

3.2. Обоснование и характеристика проектных решений по

информационному обеспечению системы

3.2.1 Построение модели информационных потоков

Список внешних объектов.

Е – пользователь АИС.

Список информационных элементов.

М – информационные элементы модели;

М1 - список крайних точек участков строительства;

М2 - список направлений участков строительства;

М3 - список значений длин участков строительства;

М4 - список значений максимального времени эксплуатации.

М5 - список крайних точек участков строительства

кратчайшего маршрута;

М6 - список крайних точек участков строительства,

оптимального по времени;

M7 - список направлений участков строительства

кратчайшего маршрута;

М8 - список направлений участков строительства маршрута,

оптимального по времени;

М9 - список значений длин участков строительства

кратчайшего маршрута;

27

М10 - список значений длин участков строительства ,

оптимального по времени;

M11 - список значений максимального времени эксплуатации

на участках строительства кратчайшего маршрута;

М12 - список значений максимального времени на участках

строительства, оптимального по времени;

Структура информационных элементов

Список задач

P0 – операции автоматизированной обработки данных;

P1 – расчет маршрута кратчайшего пути;

P2 – расчет маршрута минимального времени.

28

Информационныеэлементы модели

(М)

Список крайнихточек (М1)

Списокнаправлений

(М2)

Список значенийдлин (М3)

Списокмаксимальноговремени(М4)

Списоккрайнихточек(М5)

Списоккрайнихточек(М6)

Список

направ-

Список

направ-

Списокзначе-нийдлин

Списокзначе-нийдлин

Списокмакси-мальног

овремени(М11)

Списокмакси-мальньн

оговремени(М12)

29

Операцииавтоматизированной

обработки данных (P0)

Расчет маршрутакратчайшегопути (P1)

Расчет маршрутаминимальноговремени (P2)

3.2.2 Операционная диаграмма

30

P0

Расчет маршрутакратчайшегопути (P1)

Расчет маршрутаминимальноговремени (P2)

Список крайних точек (М1)

Пользова-тель

ЕСписок направле-ний (М2)

Список значений длин (М3)

Список макси-мального времени(М4)

М5

М6

М7

М8

М9

М10

М11

М12

Пользова-тель

Е

3.2.1 Проектирование базы данных

3.2.1.1 Формирование и анализ требований

Таблица 3.2.1.1.1

№Наименование информационного

элемента (обозначение)

Форма хранения

информационного

элемента

1Список крайних точек участков

движения (М1)база данных

2Список направлений участков

движения (М2)база данных

3Список значениий длин участков

движения (М3)база данных

4

Список значениий максимального

времени.

(М4)

база данных

3.2.1.2 Концептуальное проектирование базы данных

Таблица 3.2.1.2.1

Код

сущностиНаименование сущности (обозначние

информационного элемента,

документа)

Количество

экземпляро

в

сущностей

S1 Крайние точки (М1) 10000000S2 Направления (М2) 5000000

31

S3 Длины (М3) 5000000S4 время(М4) 5000000

32

Таблица 3.2.1.2.2

Код

сущности

Наименование атрибута Наименование

доменаS1 1.Код точки

2.Координата X

3.Координата Y

1.Код

2.X

3.YS2 1.Код точки 1

2.Код точки 2

3.Направление движения

1.Код

2.Код

3.НаправлениеS3 1.Код точки 1

2.Код точки 2

3.Длина участка

1.Код

2.Код

3.ДлинаS4 1.Код точки 1

2.Код точки 2

3.Максимальное время

1.Код

2.Код

3.время

Таблица 3.2.1.2.3

№ Наименование домена Тип

элемент

а

данных

Список значений или

пример значения

1 Код Num(7) 1002 X Num(5) 10243 Y Num(5) 7684 Направление Num(1) 3

33

Соответ-

ствуют

Соответ-

ствуют

Соответ-

ствуют

5 Длина Num(7,5

)

56123.096

6 время Num(4,5

)

114.0

В таблице 3.2.1.2.3 использованы следующие обозначения

типов данных:

Num(n,m) - число c количеством разрядов не более n,

включая точку, и m разрядов после десятичной точки;

- Num(n) – неотрицательное целое число с количеством

разрядов не более n.

3.2.1.3 Логическое проектирование базы данных

34

Крайние точки1000000

Направления5000000

Длины5000000

время50000002

2

22

22

1

1

1

10

10

10

Таблица 3.2.1.3.1 - Построение начальной логической

модели базы данных из исходной концептуальной модели.

№ Наимено

-вание

отноше-

ния

Наименование

атрибута

отношения

Наименование

домена

Тип элементов

данных

1 Крайние

точки

Код точки

Координата X

Координата Y

1.Код

2.X

3.Y

1.Num(7)

2.Num(5)

3.Num(5)2 Направ-

ления

Код точки 1

Код точки 2

Направление

строительства

1.Код

2.Код

3.Направление

1.Num(7)

2.Num(7)

3.Num(1)

3 Длины Код точки 1

Код точки 2

Длина участка

1.Код

2.Код

3.Длина

1.Num(7)

2.Num(7)

3.Num(7,5)4 Скорост

и

Код точки 1

Код точки 2

Максимальное

время

эксплуатации

1.Код

2.Код

3.Время

1.Num(7)

2.Num(7)

3.Num(4,5)

Таблица 3.2.1.3.2 - Построение системы полных функциональныхзависимостей, нормализация отношений и получение отношений в третьей нормальной

форме.

Наименование Наименование атрибута отношения ФЗ

35

отношенияКрайние точки Код точки

Координата X

Координата Y

*

Направления Код точки 1

Код точки 2

Направление строительства

*

*

Длины Код точки 1

Код точки 2

Длина участка

*

*

Время Код точки 1

Код точки 2

Максимальное время эксплуатации

*

*

36

3.2.1.4 Поддержание базы данных в актуальном

состоянии

Определим исходные данные задач автоматизированной

обработки данных.

Таблица 3.2.1.4.1. Структуры отношений, соответствующих исходным даннымзадач пользователя.

Наименование отношения Наименование атрибута Ключи

R1

Крайние точки

Код точки

Координата X

Координата Y

*

R2 Код точки 1 *

37

Крайние точкиКод точки

Координата XКоордината Y

НаправленияКод точки1Код точки 2Направление движения

ДлиныКод точки1Код точки 2Длина участка

СкоростиКод точки1Код точки 2Максимальное

время эксплуатации

Код точки

Код точки

Код точки

Направления

Код точки 2

Направление движения

*

R3

Длины

Код точки 1

Код точки 2

Длина участка

*

*

R4

Скорости

Код точки 1

Код точки 2

Максимальная скорость

*

*

Определим список событий, связанных с корректировкой

отношений.

В качестве документа, подтверждающего наступление

события, связанного с корректировкой отношения, всегда

выступает сообщение об изменении атрибутов объектов

геосреды, причем частота формирования сообщений строго не

определена.

События отношений R1, R2, R3, R4:

получение информации об одном или нескольких новых

участках движения (координаты крайних точек,

направление движения, длина участка, максимальная

скорость) – добавление элементов отношений;

исчезновение участка (участков) движения информации –

удаление элементов отношений;

38

изменение характеристик участка (участков) движения

информации – корректировка элементов отношений;

39

3.2.2. Модель технологического процесса обработки данных

Схема ТПОИ, соответствующая выполнению задачи «Расчет

маршрута кратчайшего пути» (P1).

40

Начало

Расчет маршрута

кратчайшего пути (P1)

Список направле-ний (М2)

Список значений длин

участков (М3)

М5, М7, М9, М11

М5, М7, М9, М11

Конец

Список крайних точек (М1)

1

Схема ТПОИ, соответствующая выполнению задачи «Расчет

маршрута минимального времени» (P2).

41

Начало

Расчет маршрута

минимального времени (P2)

Список направле-ний (М2)

Список значений

длин участков

(М3)

Список макси-мальных скоростей (М4)

М6, М8, М10, М12

М6, М8, М10, М12

Конец

Список крайних точек (М1)

1

3.3. Обоснование и характеристика проектных решений по

техническому обеспечению системы.

В качестве технического средства АИС используется

один IBM PC совместимый персональный компьютер. Все

оборудование помещается в одном помещении (одной

комнате).

Требования к техническому обеспечению компьютера

следующие:

- процессор не ниже Pentium II 300 МГц;

- ОЗУ не менее 64 мегабайт;

- жесткий диск не менее 1 Гбайта;

- монитор SVGA;

- видеокарта с видеопамятью объемом не менее 1

мегабайта.

- мышь;

- клавиатура.

С учетом всех требований комплекс технических

средств представлен в таблице.Таблица 3.3.1

№ Наименование технического средства Количеств

о1 Процессор Intel Pentium III 800 МГц

EB

1

2 ОЗУ 512 Мб SDRAM PC-133 13 Жесткий диск IDE IBM 40 Гб 1

42

4 Монитор SVGA SONY Multiscan E100 15” 15 Видеокарта ASUS AGP-V7700 GeForce 2

GTS 32 Мб

1

6 Мышь Microsoft IntelliMouse 17 Клавиатура Microsoft Natural Elite 1

На рис. 1 показан комплекс технических средств

компьютера.

43

Рис. 1

Рис. 3.3.1.

44

3.4. Алгоритмы функционирования.

3.4.1. Общий алгоритм функционирования

3.4.2. Алгоритмы выполнения задачи «Расчет маршрута

кратчайшего пути» и задачи «Расчет маршрута минимального

времени».

Фактически, решение вышеуказанных задач – это решение

задачи нахождения кратчайших путей между всеми парами

вершин в ориентированном или неориентированном графе.

Граф представляет собой множество точек (вершин,

узлов) вместе с линиями, соединяющими некоторые или все

45

Начало

Выполнять задачу?

1

Да

Нет Конец

Оптимиз-ть

маршрут по

расстоянию?

Расчет маршрута кратчайшего пути

(P1)

Да

Нет2

3Расчет маршрута минимального времени (P2)

4

пары точек. Форма линии не играет роли, важно лишь ее

наличие или отсутствие для конкретной пары вершин.

Направленные линии со стрелками называют дугами, не

имеющие направления – ребрами. В прикладных областях

графы часто называют сетями.

В математике граф определяется как пара G=(V,E), где

V – множество вершин, а Е – множество пар вершин из V.

Неупорядоченную пару вершин <u,v> называют ребром,

упорядоченную пару (u,v) – дугой. Ребро также обозначают

u-v, дугу u->v.

Граф, содержащий только ребра, - неориентированный,

содержащий дуги – ориентированный (орграф).

Говорят, что ребро u-v или дуга u->v соединяет

вершины u и v. Дуга u->v начинается в вершине u и

кончаетсяв вершине v (ведет от вершины u к вершине v).

При этом вершину v называют преемником вершины u, u –

предшественником вершины v.

Вершины, соединенные ребром или дугой, называют

смежными. Ребра, имеющие общую вершину, также называют

смежными. Ребро (дуга) и любая из его двух вершин

называются инцидентными. Степень вершиныравна числу

инцидентных ей ребер (дуг). Степень графа – максимальная

степень его вершин. Ребро (дурга), соединяющая вершину с

ней же самой, называется петлей.

У взвешенного графа ребрам и дугам приписывают все –

числовую или символьную характеристику. У размеченного

46

графа каждой вершине соответсвует некоторая информация –

метка.

Путь – это последовательность вершин, в которой

каждая вершина соединена ребром или дугойсо следующей

вершиной. Длина пути равна количеству его ребер (дуг).

Циклом называют замкнутый путь, в котором все ребра

(дуги) различны.

Графы широко применяются в математике, физике, химии,

технике, экономике, биологии, психологии, социологии,

лингвистике и других областях для описания строения

разнообразных систем.

Вершины графа соответсвуют реальным или абстрактным

объектам произвольной природы, а дуги и ребра описывают

различные типы связей между ними: математические,

физические, экономические, биологические, общественные,

грамматические и т.п.

Граф задает бинарное отношение (связи между парами

объектов) на множестве вершин. Неориентированный граф

задает симметричное отношение: ребро можно рассматривать

как две противоположные дуги между одной парой вершин.

Теория графов предоставляет очень удобный язык для

описания программных (да и многих других моделей).

Стройная система специальных терминов и обозначений

теории графов позволяют просто и доступно описывать

сложные тонкие вещи. Само понятие «граф» подразумевает

наличие графической интерпретации. Картинки позволяют

47

сразу «усмотреть» суть дела на интуитивном уровне,

дополняя и украшая утомительные рациональные текстовые

доказательства и сложные формуы.

Задача нахождения кратчайшего пути в графе имеет

огромное количество применений и интерпретаций. Путем

решения этой задачи может быть решена проблема поиска

оптимальных маршрутов движения транспортных средств.

Каждой дуге (x,y) исходного графа G поствим в

соответствие число a(x,y). Если в графе G отсутствует

некоторая дуга (x,y), положим a(x,y)=. Будем называть

число a(x,y) длиной дуги (x,y), хотя a(x,y) можно также

интерпретировать как соответсвующие затраты или

соответсвующий весовой коэффициент. Определим длину пути

как сумму длин отдельных дуг, составляющих этот путь.

Для любых двух вершин s и t графа G могут

существовать несколько путей, соединяющих вершину s с

вершиной t. Далее рассмотрим алгоритм, который определяет

такой путь, ведущий из вершины s в вершину t, который

имеет минимально возможную длину. Этот путь называется

кратчайшими путем между вершинами s и t.

Рассмотрим наиболее известные алгоритмы нахождения

кратчайшего пути в графе.

3.4.2.1 Алгоритм Дейкстры

48

Описываемый в данном разделе алгоритм позволяет

находить в графе кратчайший путь между двумя выделенными

вершинами s и t при положительных длинах дуг. Этот

алгоритм, предложенный в 1959 году Дейкстрой, считается

одним из наиболее эффективных алгоритмов решения задачи.

Шаг i. Перед началом выполнения алгоритма все вершины

и дуги не окрашены. Каждой вершине в ходе выполнения

алгоритма присваивается число d(x), равное длине

кратчайшего пути из s в х, включающего только окрашенные

вершины.

Положить d(s)=0 и d(x)= для всех х, отличных от s.

Окрасить вершину s и положить y=s (у - последняя из

окрашенных вершин).

Шаг 2. Для каждой из неокрашенной вершины х следующим

образом пересчитать величину d(x):

d(x)=min{d(x),d(y)+a(y,x)}. (1)

Если d(x)= для всех неокрашенных вершин х,

закончить процедуру алгоритма: в исходном графе

отсутствуют пути из вершины s в неокрашенные вершины. В

противном случае окрасить ту из вершин х, для которой

величина d(x) является наименьшей. Кроме того, окрасить

дугу, ведущую в выбранную на данном шаге вершину х (для

этой дуги достигается минимум в соответствии с выражением

(1)). Положить у=х/

Шаг 3. Если y=t, закончить процедуру: кратчайший путь

из вершины s в вершину t найден (это единственный путь из

49

s в t, составленный из окрашенных дуг). В противном

случае перейти к шагу 2.

Исходное предположение в алгоритме Дейкстры состояло

в не отрицательности длин дуг исходного графа. К каким

результатам приводил бы алгоритм Дейкстры, если некоторые

из длин дуг были бы отрицательными? Для примера

рассмотрим граф, изображенный на рисунке 1. В этом графе

кратчайшим путем, соединяющим вершины s и t, является

путь, состоящий из дуг (s, а) и (a, t). Длина этого пути

равна 2-2=0. Убеждаемся в том, что алгоритм Дейкстры,

будучи применен к графу» изображенному на рисунке 1,

ошибочно укажет в качестве кратчайшего путь, состоящий из

дуги (s, t). Таким образом, нет никакой гарантии, что

алгоритм Дейкстры будет находить кратчайших путь в

случаях, когда длины дуг могут быть отрицательными.

К счастью, алгоритм Дейкстры может быть обобщен на

случай, когда некоторые из дуг имеют отрицательные длины.

Идея соответствующего обобщения принадлежит Флойду.

Необходимая модификация алгоритма Дейкстры состоит в

следующем:

1. На шаге 2 алгоритма пересчет величин d(x) с

помощью соотношения (1) производится для всех вершин, а

не только для неокрашенных. Следовательно, числа d(x)

могут уменьшаться как для неокрашенных, так и для

окрашенных вершин.

50

s

a

t

-2

1

2

Рис. 3.4.2.1.1

2. Если для некоторой окрашенной вершины х происходит

уменьшение величины d(x), то с этой вершины и инцидентной

ей окрашенной дуги окраска снимается.

3. Процедура алгоритма заканчивается только тогда,

когда все вершины окрашены и когда после выполнения шага

2 ни одно из чисел d(x) не меняется.

В предыдущем разделе была рассмотрена задача

нахождения на графе кратчайшего пути из некоторой

выделенной вершины до любой другой вершины. В данном

разделе будет рассмотрена -задача поиска на графе

кратчайшего пути между каждой парой вершин. Конечно, это

более общая задача могла бы быт решена путем

многократного применения алгоритма Дейкстры с

последовательным выбором каждой вершины графа в качестве

вершины s. Однако реализация соответствующей процедуры

потребовала бы сравнительно больших вычислительных

затрат. К счастью, существуют алгоритмы более

эффективные, чем процедура многократного повторения

алгоритма Дейкстры. Далее рассматриваются два весьма

схожих, алгоритма поиска в графе кратчайших путей между

всеми парами вершин. Эти алгоритмы принадлежат Флойду и

51

Данцигу. В обоих алгоритмах для длин дуг допускаются

отрицательные значения, однако не допускается наличие

контуров отрицательной длины.

Прежде чем предоставлять алгоритмы, необходимо ввести

некоторые обозначения. Перенумеруем вершины сходного

графа целыми числами от 1 до N. Обозначим через dijm длину

кратчайшего пути из вершины i в вершину j, который в

качестве промежуточных может содержать только первые m

вершин графа. Если между вершинами i и j не существует ни

одного пути указанного типа, то условно будем считать,

что dijm = . Из данного определения величин dij

m следует,

что величина dij0 представляет длину кратчайшего пути из

вершины i в вершину j (если такие дуги присутствуют в

графе). Для любой вершины i положим положим dij0 = 0.

Отметим далее, что величина dijm представляет длину

кратчайшего пути между вершинами i и j.

Обозначим через Dm матрицу размера N х N, элемент (i,

j) которой совпадает с dijm. Если в исходном графе нам

известна длина каждой дуги, то мы можем сформировать

матрицу D°. Наша цель состоит в определении матрицы DN,

представляющей кратчайшие пути между всеми вершинами

рассматриваемого графа.

В алгоритме Флойда в качестве исходной выступает

матрица D°. В начале из этой матрицы вычисляется матрица

D1, затем по матрице D1 вычисляется D2 и т. д. Процесс

52

повторяется до тех пор, пока по матрице DN-1 не будет

вычислена матрица DN.

3.4.2.2. Алгоритм Флойда

Шаг 1. Перенумеровать вершины исходного графа целыми

числами от 1 до N. Определить матрицу D0 , задав величину

каждого ее элемента (i, j) равной длине кратчайшей дуги,

соединяющей вершину i с вершиной j. Если в исходном графе

указанные вершины не соединяются дугами, положить dij0 =

. Кроме того, для всех i положить dij0 = 0.

Шаг 2. Для целого m, последовательно принимающего

значения 1, 2, ..., N, определить по величинам элементов

матрицы Dm-1 величины элементов матрицы Dm, используя

рекурсивное соотношение

dmij = min {dm-1

im + dm-1mj, dij

m-1} (2)

При определении величины каждого элемента матрицы Dm

фиксировать соответствующий кратчайший путь.

По окончании данной процедуры величина элемента (i,

j) матрицы DN определяет длину кратчайшего пути, ведущего

из вершины i в вершину j.

В выше представленном данном алгоритме кратчайшие

пути между соответствующими вершинами формируются по мере

выполнения процедуры алгоритма. Очевидно, для задач

53

реальных размерностей такой способ формирования

кратчайших путей является практически малопригодным.

Следовательно, необходимо разработать более эффективный

способ определения дуг, составляющих кратчайший путь.

Введем в рассмотрение предпоследние вершины путей.

Пусть pij обозначает предпоследнюю вершину кратчайшего

пути, соединяющего вершину i с вершиной j. Если между

указанными вершинами имеется несколько соединяющих их

кратчайших путей, то для пары (i, j) может существовать

несколько предпоследних вершин. Однако, если нас

интересует только один кратчайший путь, то можно

ограничить рассмотрение лишь одной из вершин,

составляющих множество рij. Если рij известно для каждой

пары вершин i и j, то все промежуточные вершины

кратчайшего пути из i в j могут быть определены следующим

образом. Пусть предпоследней вершиной искомого пути

является вершина k, т.е. рij = k. Тогда вторая от конца

вершина на этом пути является предпоследней вершиной

кратчайшего пути из i в k, т.е. совпадает с pik. Данную

процедуру можно повторять и далее до тех пор, пока не

будет пройден в обратном направлении весь кратчайший путь

из вершины i в вершину j. Таким образом, для того, чтобы

определить кратчайшие пути между всеми парами вершин,

необходимо располагать лишь элементами рц для всех пар

вершин (i, j).

54

Существует два способа определения рij - встроенный

(tentative) и внешний (terminal). Опишем каждый из них в

отдельности.

1. Встроенный способ. Перед началом работы алгоритма

Флойда (точнее, пред шагом 2) в качестве рц принять

элемент i (это проделать для каждого j). Далее в процессе

выполнения алгоритма при использовании соотношения (2)

каждый раз фиксировать, какая из величин (dm-1im + dm-1

mj)

или dm-1ij меньше. Как только меньшей оказывается первая из

этих величин, положить рij равным m. В противном случае

оставить рij неизменным. Если оказывается, что величины,

входящие в правую часть соотношения (2), одинаковы, то

можно либо не менять рij, либо принять его равным m.

После окончания выполнения алгоритма элементы рij,

сформированные данным способом, действительно определяют

предпоследние вершины кратчайших путей, ведущих из

вершины i в вершину j.

2. Внешний способ. Считая работу алгоритма Флойда

законченной, а значит, и зная матрицу DN, определить

каждое рij, положив его равным любому k, для которого dNik

+ d0kj = dN

ij: при этом для формирования рij требуется

только матрицы D° и DN. Отметим, что в ситуации, когда

алгоритм Флойда уже выполнен, единственное, что остается

сделать для определения кратчайших путей - это

воспользоваться внешним способом формирования рц. Если же

заранее известно, что необходимо определить не только

55

длины кратчайших путей, но и сами пути, то, безусловно,

лучше применять встроенный способ, поскольку реализация

его в рамках основного алгоритма лишь не значительно

увеличивает объем вычислений.

Еще один алгоритм поиска в графе кратчайших путей

между всеми парами вершин был предложен Данцигом.

Алгоритм Данцига весьма близок к алгоритму Флойда и

отличается от последнего лишь иным порядком выполнения

тех же самых операций.

Итак, рассмотрим алгоритм Данцига. Снова перенумеруем

вершины исходного графа целыми числами от 1 до N и

обозначим через dmij длину кратчайшего пути из вершины i

в вершину j, в котором допускается использование в

качестве промежуточных m первых вершин графа. Пусть

теперь в отличии от алгоритма Флойда матрица Dm,

состоящая из величин dmij, при каждом m = 1,2,..., N имеет

размерность не N х N, а m х m. Так же как и раньше

требуется определить матрицу DN, элемент (i, j), который

определяет длину кратчайшего пути из вершины i в вершину

j. Как и в алгоритме Флойда, в алгоритме Данцига матрица

D1 определяется из матрицы D°, матрица D2 из матрицы D1 и

т.д. Наконец, матрица DN из матрицы DN-1.

3.4.2.3. Алгоритм Данцига поиска всех кратчайших путей

56

Шаг -1. Перенумеровать вершины исходного графа целыми

числами от 1 до N. Сформировать матрицу D° (размерность N

х N), каждый элемент i, j которой (d0ij определяет длину

кратчайшей дуги, ведущей из вершины i в вершину j. В

отсутствие такой дуги положить d0ij = .

Шаг 2. Здесь через Dm обозначается матрица

размерностью m х m с элементами dmij = 1, 2, ..., N.

Последовательно определить элементы матрицы Dm из

элементов матрицы Dm-1 для m, принимающего значения

1,2, ..., N :

Кратчайшие пути, длины которых определяются

величинами dNij элементов матрицы DN, могут быть определены

аналогично тому, как это делалось в алгоритме Флойда.

Сколько операций выполняется в алгоритме Данцига?

Чтобы ответить на этот вопрос, нужно заметить, что в

алгоритме Данцига выполняются по существу те же самые

операции, что и в алгоритме Флойда, только в другом

порядке. Действительно, уравнение (2), используемое в

алгоритме Флойда, просто совпадает с уравнением (5)

57

алгоритма Данцига. Уравнения (3) и (4), используемые в

алгоритме Данцига просто (m - 1) раз «повторяют»

уравнение (2) из алгоритма Флойда. Таким образом, оба

алгоритма включают одно и то же число операций.

3.4.2.4. Применение алгоритма Флойда

Фактически, т.н. “участок движения” (это понятие

рассматривалось в разделе 2.2. “Формализация задачи и

результаты исследований”) можно представить как ребро или

дугу графа. Возможность транспортного средства проехать

по участку движения в ту или иную сторону можно

интерпретировать как направление дуги. В том случае, если

движение по данному участку двустороннее, то этот участок

пути можно интерпретировать как ненаправленное ребро

графа.

Можно поставить в соответствие «весу» ребра (дуги)

графа какую-либо качественную или количественную

характеристку участка движения. В нашем случае для

нахождения оптимального пути по критерию минимального

расстояния необходимо ставить в соответствие весу ребра

или дуги графа значение длины участка движения. Если же

необходимо оптимизировать маршрут по критерию

минимального времени преодоления транспортным средством

расстояния от исходного пункта до пункта назначения, то в

соответствие весу дуги или ребра графа может ставиться,

58

например, максимально возможная на данном участке

скорость движения транспортных средств.

Очень важным является вопрос о том, каким образом

необходимо представить граф в памяти ЭВМ для решения

задачи выбора оптимальных маршрутов.

Существует множество способов представления графов в

памяти: матрица смежности, матрица весов, матрица

инцидентности, структуры смежности, сеть, списковые

структуры. Для решения нашей задачи наиболее подходят

такие структуры хранения данных, как матрица весов и

списковая структура (или просто список).

Матрица весов – квадратная матрица n*n с элементами

W[i,j] = вес дуги i->j

В зависимости от задачи отсутствующим дугам (ребрам)

приписывают нулевой или бесконечный вес. Например, при

поиске пути с максимальным весом, чтобы программа не

включала в него отсутвующие дуги, они должны иметь вес

ноль; при поиске пути минимального веса – бесконечность.

Для неориентированного графа матрица весов симметрична

относительно главной диагонали.

Список в общем случае представляет собой совокупность

элементов, состоящих из двух основных частей:

информационная часть и ссылка (указатель) на следующий

элемент.

Выбор способа представления графа в памяти компьютера

между матрицей весов и списком зависит от характера

59

операций, производимых над графом: если приходится часто

добавлять и удалять элементы графа, то целесообразно

использовать список. Если же необходимо, чтобы над графом

с высокой скоростью производились операции, не связанные

с добавлением или удалением элементов, то для

представления графа в памяти компьютера лучше

использовать матрицу, поскольку к любому элементу массива

можно обратиться напрямую путем указания его индекса.

Было принято следующее решение. Во время

проектирования схемы (нанесения на схему условных

обозначений) граф представляется в виде списка, чтобы

можно было легко добавлять и удалять элементы схемы. При

поиске же оптимального маршрута список преобразуется в

матрицу весов, для того чтобы процесс оптимизации не

отнимал слишком много процессорного времени.

После того как все параметры схемы становятся

определенными, при запросе на поиск оптимального маршрута

выполняется алгоритм Флойда, логика работы которого уже

была рассмотрена ранее.

60

3.5. Обоснование и характеристика проектных решений по

программному обеспечению системы.

Программное обеспечесние АИС состоит из СУБД Paradox

7 фирмы Borland, соответствующего приложения баз данных.

СУБД и приложение работают под управлением операционной

системы Windows 9x.

Windows 9x – это обобщенное название операционных

систем Windows 95 и Windows 98 фирмы Microsoft для

массового пользователя. Выбор этих операционных систем

был обусловлен большой степенью распространенности среди

пользователей.

Исходные тексты на языке Object Pascal приложения АИС

находятся в восьми модулях (AboutForm, FloydAlgorithm,

MainUnit, PaintFormUnit, ParametersFormUnit,

SchemeObjects, Shapes, WizardFormUnit), каждый из которых

сответствует определенной задаче, выполняемой при

функционировании приложения АИС. Листинги программ,

содержащихся в соответствующих модулях, приведены в

Приложении. При компиляции все модули собираются в единый

исполняемый модуль.

AboutForm отвечает за работу экранной формы, выдающей

пользователю сведения о программе.

В модуле FloydAlgorithm в виде соответсвующего класса

реализован алгоритм Флойда.

61

Модуль MainUnit ответственен за логику работы главной

формы приложения.

PaintFormUnit управляет дочерними по отношению к

главной форме формами, в рабочей области которых можно

проектировать схемы маршрутов движения транспортных

средств.

ParametersFormUnit управляет работой формы, которая

выполняет задачу настройки приложения.

В модуле Shapes реализован класс, объекты которого

могут содержать элементы схемы и выполнять над ними

различные операции (добавлять, изменять, модифицировать,

удалять). Все изменения, прозводимые таким объектом,

автоматически отображаются на изображении схемы.

В модуле SchemeObjects определен класс, объекты

которого способны хранить граф и производить над его

элементами различные манипуляции.

WizardFormUnit представляет собой реализацию логики

мастера настройки схемы (определение различных атрибутов

объектов схемы).

Изображения экранных форм приводятся в следующем

разделе.

Программное обеспечение построено так, что при

необходимости можно легко перейти на работу с другой

СУБД.

62

4.КОНСТРУКТОРСКО-ТЕХНОЛОГИЧЕСКИЕ ПРОЕКТНЫЕ РЕШЕНИЯ

4.1. Выбор инструментальных средств

Как уже отмечалось, АИС была разработана с

использованием системы программирования Borland Delphi 6.

Delphi – это мощная универсальная система

программирования, ориентированная, в первую очередь, на

ускоренное создание приложений под операционную систему

Windows.

Иллюстрация возможностей этой системы применительно к

разработке СУБД будет проводиться на примере данного

проекта.

База данных (БД) и соответствующее приложение были

разработаны не только при помощи системы программирования

Borland Delphi 6, но и с помощью различных других

приложений, входящих в поставку Delphi 6 (SQL Explorer,

SQL Builder, Database Desktop). Код программы был написан

на языке Object Pascal (объектный Паскаль), который

применяется в вышеуказанной системе программирования.

Запросы к БД были написаны на языке SQL (Structured Query

Language, структурированный язык запросов). Интерфейс

пользователя был спроектирован с использованием

визуальных и невизуальных средств системы

программирования Delphi. Физически данные БД находятся в

файлах формата СУБД Paradox. Управление этими данными

63

осуществляется пользователем при помощи приложения RZ

через т. н. «драйвер» управления данными на физическом

уровне Paradox и «надстройки» над этим драйвером BDE

(Borland Database Engine, что в переводе на русский язык

означает примерно следующее: “машина базы данных фирмы

Borland”). BDE выступает в роли посредника между

приложением RZ и драйвером Paradox.

Достаточно условно, укрупненно и, соответственно,

упрощенно схему взаимодействия пользователя с данными БД

можно представить в виде следующей схемы (рис. 1):

Рис. 4.1.1

Для взаимодействия пользователя с БД автором данной

работы в среде Delphi было разработано специальное

приложение.

64

ПОЛЬЗОВАТЕЛЬ

ПриложениеBDE

СУБД

БАЗА ДАННЫХ

Как уже было отмечено выше, для взаимодействия

приложения с БД используется технология BDE. Однако

возникает вопрос: «А каким образом сообщить BDE о

существовании спроектированной и сохраненной в виде

файлов БД?» Для этого существует специальное приложение

SQL Explorer, входящее в поставку Borland Delphi 6.

В этом приложении необходимо просто указать каталог,

в котором хранятся файлы БД, и название (псевдоним,

алиас, alias), под которым БД будет зарегистрирована в

системе Delphi.

Кроме того, необходимо особо отметить, что в Delphi

существует понятие модуля данных (класс TDataModule),

который служит для получения доступа к базе данных и

представляет собой хранилище объектов, которое позволяет

централизованно управлять их работой и отделяет

программную логику, связанную с базами данных, от

программного кода, выполняющего высчислительные действия

и отображение данных на форме.

Необходимо отметить, что в системе программирования

Delphi 6 есть панель компонентов DataAccess (рис. 4.1.2).

Компоненты этой панели служат

65

Рис. 4.1.2

целям доступа к данным БД.

На этой панели есть следующие (имеющие значение для

данной работы) компоненты:

Table (класс TTable);

DataSource (класс TDataSource);

Query (класс TQuery);

Свойства и методы объектов класса TTable определяют

взаимодействие приложения с какой-либо таблицей, входящей

в состав БД.

Компонент DataSource служит для создания объектов,

являющихся промежуточным звеном при взаимодействии

различных компонентов приложения (таких, как, например,

таблицы, отображаемые на экране и используемые для

манипулирования данными таблиц физической БД, т. е.

объекты класса TDBGrid, создаваемые при помощи компонента

DBGrid c панели компонентов DataControls на рис. 4) с

компонентами панели DataAccess. Компонент DataSource

является своего рода источником данных для различных

компонентов приложения, размещенных на форме и требующих

источниика данных, например, для их отображения на

66

экране. Для таких компонентов просто нужно указать имя

соответвующего объекта класса TDataSource.

Рис. 4.1.3

Компонент Query служит для создания объектов,

определяющих запросы к БД. Например, свойство SQL служит

для хранения кода запроса на языке SQL.

Таким образом, модуль данных в данной работе содержит

следующие объекты:

Проектирование структуры БД проводилось с

использованием возможностей приложения Database Desktop.

Это приложение является инструментальным средством

визуального проектирования реляционных БД, обладающее

необходимыми для этого возможностями.

Данное приложение поддерживает большое количество

форматов известных в настоящее время СУБД. Оно позволяет

полностью спроектировать БД и подготовить ее к

применению, т. е. определить структуру всех таблиц, связи

между ними, свойства полей этих таблиц и сохранить

таблицы в виде файлов.

Запросы к БД были спроектированы с использованием

средства разработки запросов SQL Builder, которое

позволяет визуально и невизуально спроектировать любой

сколь угодно сложный запрос.

4.2. Формы

67

После запуска программы АИС на экране появляется

главная форма приложения АИС (рис. 4.2.1):

Рис. 4.2.1

В рабочей области окна, подчиненного по отношению к

главному, можно проектировать схемы маршрутов движения с

использованием инструментальных средств приложения,

управление которыми осуществляется при помощи кнопок

панели инструментов, расположенных слева. На этой панели

есть следующие кнопки, при наведении на которые

появляются всплывающие подсказки:

«режим выделения»;

«проложить транспортные пути»;

«установить метки»;

«пометить непроходимые участки»;

«установить светофоры (шлагбаумы)»;

«установить знаки нежелательных участков дорог»;

«установить исходный пункт»;

68

«установить конечный пункт»;

«режим удаления».

Верхняя панель инструментов содержит кнопки, которые

служат для выполнения наиболее часто используемых команд:

«создать новый файл»;

«открыть файл»;

«сохранить файл»;

«приблизить изображение схемы»;

«отдалить изображение схемы»;

«привести изображение схемы к нормальному размеру»;

«оптимизировать маршрут по времени»;

«оптимизировать маршрут по расстоянию».

В строке состояния, которая находится внизу главного

окна приложения, отображаются текущие координаты курсора

мыши относительно левого верхнего угла рабочей области.

Кроме того, в строке состояния указываются значения

минимального пути и минимального времени по завершении

процесса оптимизации маршрута движения транспортного

средства.

Меню «Файл» содержит следующие пункты, смысл которых

очевиден:

«Создать»;

«Открыть…»;

«Сохранить»;

«Сохранить как…»;

«Выход».

69

Меню «Правка» содержит следующие пункты:

«Удалить участки движения»

«Удалить метки»

«Удалить знаки «кирпич»»

«Удалить все элементы схемы»

«Параметры…»

Меню «Вид» состоит из следующих пунктов:

«Приблизить»

«Отдалить»

«Нормальный размер»

Меню «Маршрут» составляют следующие пункты:

«Оптимизировать по времени»

«Оптимизировать по длине пути»

«Настроить транспортные пути»

Меню «Окно» содержит стандартные пункты:

«Расположить каскадом»

«Свернуть все окна»

«Разделить по горизонтали»

«Разделить по вертикали»

Меню «?» состоит из единственного пункта «О

программе…».

В том случае, если вся схема настроена полностью

(т.е. определены все атрибуты всех объектов схемы)

происходит оптимизация маршрута по одному из двух

критериев по алгоритму Флойда. Наиболее оптимальный путь

выделяется цветом.

70

Если же схема не настроена или настроена не

полностью, то вызывается мастер настройки участков

движения, вид окна которого представлен на рис. 4.2.2:

Рис. 4.2.2

71

5.БЕЗОПАСНОСТЬ ЖИЗНЕДЕЯТЕЛЬНОСТИ

5.1 Анализ опасных и вредных факторов

Целью работы является разработка автоматизированной

системы проектирования и анализа маршрутов движения

транспортных средств в географической среде. Разработка

проводится на одной IBM PC совместимой ПЭВМ в

лаборатории, находящейся на третьем этаже корпуса «О»

КГТУ (КХТИ). В результате работы возможно поражение

электрическим током, вредное воздействие статического

электричества, утомление при работе с монитором.

5.2 Характеристики лаборатории

По пожарной безопасности помещение лаборатории

относится к учебной лаборатории. Согласно правил

устройства электроустановок (ПУЭ 86) лаборатория

относится к зонам класса П-IIа.

5.3 Шум и вибрация

При данной работе установок, являющихся источником

шума и вибрации нет.

5.4 Вентиляция

Зданиями предусмотрена естественная вентиляция,

осуществляемая с помощью вентиляционных шахт. По условиям

работы применение искусственной вентиляции не требуется.

72

5.5 Отопление

В соответствии со СНИП 2.04.05-91 для поддержания

оптимальных условий в лабораториях в холодный и

переходный периоды года предусмотрено обогревание

помещения с помощью центрального водяного отопления.

5.6 Метеорологические условия в лаборатории

Метеорологические условия помещения, действующими на

организм человека, - это сочетание действия температуры,

относительной влажности и скорости движения воздуха в

рабочей зоне. По энергозатратам работы, выполняемые в

лаборатории относятся к легким (Iа - производимая сидя и

сопровождающаяся незначительным физическим напряжением).

На основании характера выполняемой работы и согласно ГОСТ

12.1.ОО5-88 "Общие санитарно-гигиенические требования к

воздуху рабочей зоны" оптимальными метеорологическими

параметрами среды для переходного года являются:

1. температура - 21-250С;

2. относительная влажность - 75%;

3. скорость воздуха не более 0.1 м/с.

Режим труда и отдыха при работе с ПЭВМ имеет группу В

(творческая работа, но не более 6 часов в день) и

категорию I (устанавливается в зависимости от количества

знаков, обрабатываемых за смену и продолжительности

работы) трудовой деятельности. Регламентированные

73

перерывы для I категории работ через каждые 2 часа

продолжительностью 15 минут каждый.

5.7 Освещение

В лаборатории используется боковое естественное и

люминесцентное искусственное освещение.

В соответствии со СниП 23-05-95 по характеру

зрительной работы помещение относится к IV разряду и

минимальная освещенность равна 300 лк. Расчет

естественного освещения сводится к определению площади

окон, обеспечивающей нормальную освещенность и сравнению

с существующей. Формула расчета необходимой площади:

S0 = (ln * r0 *K3 * Sw) / ( K0 *

K1 * 100), ì3 (4.1)

где ln=1.5 % - минимальное значение коэффициента

освещенности для IV разряда, r0=1.5 - световая

характеристика окон, K3=1 - коэффициент, учитывающий

затемнение окон здания, Sw=22.5 м2 - площадь пола, K1=1.3

- коэффициент, учитывающий влияние отражения света,

S0 = 1.5 * 1.5 * 1* 22.5 / 0.3 * 1.3

* 100 = 0.93 ì2. (4.3.2)

В действительности площадь окон больше, чем

расчетная. Этим обеспечивается нормальная освещенность в

дневное время.

Расчет искусственного освещения сводится к расчету

светового потока при известном количестве света.

74

Определение ведется по методу коэффициента использования

по формуле:

F = E * K * S * Z /

N * , (4.3.3)

где F- общий световой поток, S=22.5 м2 - площадь

пола, E=300 лм - минимальная освещенность, K=1.3 -

коэффициент запаса, зависящий от прозрачности атмосферы,

N = 20 - число светильников, = 0.3 - коэффициент

использования светового потока, определяемый индексом

помещения i:

i = A * B / h

* (A + B),

(4.3.4)

где А = 9м - длина лаборатории, В = 2.5м - ширина

лаборатории, h = 4м - расчетная величина подвеса

светильников

i = 9 * 2.5 / 4

* (9 + 2.5) = 0.5 (4.3.5)

F = 300 * 1.3 * 22.5 * 1.15 / 20

* 0.3 = 2990 лм (4.3.6)

Согласно световому потоку выбираем лампу ЛБ-40 со

световым потоком 3/20лм.

5.8 Средства индивидуальной зашиты

75

Так как в ходе исследования работы с веществами не

предусматривается, то нет и необходимости в средствах

индивидуальной защиты.

5.9 Электробезопасность

Все электрические приборы заземлены. Так как

используемые оборудование питается от сети напряжение

линии 1000 В, то сопротивление не превышает 4 Ом.

Заземление выполнено из медного провода диаметром 1.5 мм.

Для защиты работающего предусмотрено также зануление и

защитное отключение.

Все приборы питаются от сети напряжением 220-380 В.

Согласно правил установки электрооборудования,

лаборатория относится к пожарной зоне класса П-IIа.

Лаборатория имеет стационарно установленное неискрящееся

оборудование. Тип исполнения электрооборудования IP-44.

Электрооборудование отвечает требованиям ГОСТ 14254-80.

Расшифровка маркировки IP - обозначение защиты; 4-

степень защиты переноса от соприкосновения сопротивления

с движущимися частями и находящимися под напряжением

частями машины, находящимися внутри оболочки, а так же

степень защиты изделия от попадания внутрь посторонних

предметов размеров 1 мм и более; 4- защита от брызг.

5.10 Защита от статического электричества и

молниезащита

76

Зашита от статического электричества проводится путем

заземления всех металлических частей проводится путем

заземления всех металлических частей медным проводом. Для

предотвращения поражения электрическим током все приборы

заземлены. На полу имеются диэлектрические коврики.

Согласно требованиям ГОСТ 12.1.030-81 сопротивление

заземляющего устройства не должно превышать 10 Ом в

стационарных сетях и изолированной нейтралью и до 1000 В;

0.5 Ом в установках напряжением выше 1000 В. В

соответствии с ПУЭ величина Rиз для распределительных

щитов, устройств токопроводов, работающих при напряжении

до 1000 В, должна быть не менее 0.5 Ом.

Для защиты от молнии применяется одиночный тросовый

молниеотвод с опорами, стоящими одна от другой на

расстоянии 50 м.

5.11 Пожарная профилактика

Строительные конструкции относятся к группе

трудносгораемых - степень огнестойкости I (СНиП 2.01.02-

85*).

На случай воспламенения в лаборатории предусмотрены

следующие средства пожаротушения: огнетушитель пенный

ОХП-10, асбестовое одеяло, ящик с сухим песком. Для

тушения электроустановок предусмотрены огнетушители ОУ-I.

В случае воспламенения одежды на работающих пламя

надо гасить, обернув пострадавшего асбестовым одеялом.

77

Применение беспламенных нагревательных приборов уменьшает

опасность пожара, исключает загрязнение воздуха

продуктами сгорания газа. Перед уходом из лаборатории все

приборы и освещение должны быть выключены, водоснабжение

лаборатории перекрыто.

5.12 Утилизация отходов и охрана окружающей среды

При выполнении работы вредных отходов не имеется.

5.13 Охрана труда

Поскольку научно-исследовательская работа проводится

на персональных ЭВМ, то предусмотрена защита от вредного

для здоровья человека излучения монитора. Для этой цели

все мониторы в лаборатории расставлены так, чтобы задняя

часть монитора, на которую приходится наибольший уровень

излучения, не была направлена на находящегося в

лаборатории человека, а направлена на стены лаборатории.

Таким образом, мониторы расположены на столах вдоль стен

с направленной на эти стены задней частью

Во избежание переутомления глаз каждый работающий за

ПЭВМ каждые два часа должен делать пятнадцатиминутный

перерыв.

78

ЗАКЛЮЧЕНИЕ

Спроектированная АИС успешно решает поставленную

задачу оптимизации маршрутов движения транспортных

средств по критериям минимальной протяженности

преодолеваемого пути и минимального времени,

затрачиваемого на движение к пункту назначения.

АИС позволяет снизить время движения транспортного

средства до пункта назначения, повышает надежность

принятия правильных решений, достоверность получаемой

информации.

Система может представлять интерес с точки зрения ее

применения в самых различных организациях, работа которых

так или иначе связана с движением транспортных средств:

сотрудников противопожарной службы, милиции, скорой

помощи, службы срочной доставки грузов и т. п. с точки

зрения повышения эффективности работы, качества

предоставляемых услуг, экономии средств.

Необходимо отметить, что несмотря на вполне

определенную практическую направленность, система может

применяться и во многих других областях, где возникают

проблемы решения задач, связанных с нахождением

оптимальных путей в графе. Если разработанная АИС может

строить схемы маршрутов движения и оптимизировать их, то

для решения иных задач, связанных с нахождением

кратчайших путей в графе, требуется незначительная

79

модификация существующей АИС с учетом конкретных

требований. А поскольку подобные задачи на практике

встречаются очень часто, то большая практическая

значимость АИС несомненна.

Несмотря на то, что АИС свою основную задачу

выполняет, эту систему можно и нужно улучшать с учетом

конкретных требований, которые могут предъявляться к

разработчику пользователями АИС.

80

СПИСОК ИСПОЛЬЗОВАННОЙ ЛИТЕРАТУРЫ

1. Новиков В.А. Дискретная математика для

программистов. Санкт-Петербург: Питер, 2000. – 304 с.

2. Хохлов Д.Г. Структуры данных и комбинаторные

алгоритмы: Учебное пособие. Казань: КГТУ (КАИ), 2000. –

102 с.

3. Хохлов Д.Г., Захарова З.Х. Введение в системное

программирование: Учебное пособие. Казань: КГТУ (КАИ),

1999. – 126 с.

4. Ризаев И.С., Яхина З.Т. Базы данных: Учебное

пособие. Казань: КГТУ (КАИ), 2000. – 100 с.

5. Кэнту М. Delphi 6 для профессионалов. Санкт-

Петербург: Питер, 2002. – 1088 с.

6. Бобровский С. Delphi 5: Учебный курс. Санкт-

Петербург: Питер, 2000. – 640 с.

81

ПРИЛОЖЕНИЕ

Листинги основных программunit FloydAlgorithm;

interface

uses Windows, Classes, SysUtils, Registry;

type

TDoubleDynArray = array of array of Double;

TIntDynArray = array of array of Integer;

TFloydAlgorithmDynamic = class(TObject)

private

FNumberOfTops: Integer;

FInfinity: Double;

Fc,Ft: TDoubleDynArray;

Fh: TIntDynArray;

FFloatingPoint: string;

function GetWeightMatrix: TDoubleDynArray;

function GetPathes: TIntDynArray;

function GetLengthes: TDoubleDynArray;

public

constructor Create (const AttributeOfInfinity: Double = 1000000.0);

destructor Destroy; override;

procedure Execute (const WeightMatrix: TStrings);

property NumberOfTops: Integer read FNumberOfTops;

property AttributeOfInfinity: Double read FInfinity;

property WeightMatrix: TDoubleDynArray read GetWeightMatrix;

property MatrixOfShortestPathes: TIntDynArray read GetPathes;

property MatrixOfLengthesOfShortestPathes: TDoubleDynArray read

GetLengthes;

end;

implementation

{ TFloydAlgorithmDynamic }

constructor TFloydAlgorithmDynamic.Create(const AttributeOfInfinity:

Double);

var Reg: TRegistry;

82

begin

FInfinity:=AttributeOfInfinity;

FNumberOfTops:=0;

Reg:=TRegistry.Create;

Reg.RootKey:=HKEY_CURRENT_USER;

try

if not Reg.OpenKey('\Control Panel\International',False) then

begin

FFloatingPoint:=',';

raise Exception.Create('Не удается открыть ключ реестра! Дальнейшая

работа, возможно, будет некорректной!');

end

else FFloatingPoint:=Reg.ReadString('sDecimal');

finally

Reg.CloseKey;

Reg.Free;

end;

if Length(FFloatingPoint)>1 then

raise Exception.Create('Некорректное значение разделителя целой и

дробной частей,'+

' состоящее более, чем из одного символа! Замените в настройках

Windows'+

' это значение на один символ (желательно, точку или запятую), иначе

программа'+

' может работать некорректно!');

if FFloatingPoint=' ' then

raise Exception.Create('Некорректное значение разделителя целой и

дробной частей,'+

' равное пробелу! Замените в настройках Windows'+

' это значение на другой символ (желательно, точку или запятую),

иначе программа'+

' может работать некорректно!');

end;

destructor TFloydAlgorithmDynamic.Destroy;

begin

83

Fc:=nil; Ft:=nil; Fh:=nil;

inherited;

end;

procedure TFloydAlgorithmDynamic.Execute(const WeightMatrix: TStrings);

var i,j,k,NumOfStr,NumOfCol,LenOfStr: Integer;

s,SNum,NormalS: String;

NormalMatrix: TStringList;

begin

NormalMatrix:=TStringList.Create;

NumOfStr:=WeightMatrix.Count;

for i:=0 to NumOfStr-1 do

begin

s:=WeightMatrix.Strings[i];

LenOfStr:=Length(s);

SNum:=''; NormalS:='';

NumOfCol:=0;

for j:=1 to LenOfStr do

begin

if s[j]<>' ' then

begin

if ((Ord(s[j]) < 48) and (s[j] <> Self.FFloatingPoint[1])) or

((Ord(s[j]) > 57) and (s[j]<>Self.FFloatingPoint[1])) then

begin

NormalMatrix.Free;

raise Exception.Create('Некорректно задана матрица весов

графа');

exit;

end

else

begin

SNum:=SNum+s[j];

if j=LenOfStr then

begin

NormalS:=NormalS+SNum;

NumOfCol:=NumOfCol+1;

84

end;

end;

end

else

begin

if SNum<>'' then

begin

SNum:=SNum+' ';

NormalS:=NormalS+SNum;

NumOfCol:=NumOfCol+1;

SNum:='';

end;

end;

end;

if NumOfCol <> NumOfStr then

begin

NormalMatrix.Free;

raise Exception.Create('Некорректно задана матрица весов графа');

exit;

end;

NormalS:=TrimRight(NormalS);

NormalMatrix.Add(NormalS);

end;

Self.FNumberOfTops:=NumOfStr;

try

Fc:=nil; Fh:=nil; Ft:=nil;

SetLength (Fc,FNumberOfTops);

SetLength (Ft,FNumberOfTops);

SetLength (Fh,FNumberOfTops);

for i:=0 to FNumberOfTops-1 do

begin

SetLength (Fc[i],FNumberOfTops);

SetLength (Ft[i],FNumberOfTops);

SetLength (Fh[i],FNumberOfTops);

end;

85

except

on EHeapException do

begin

Fc:=nil; Ft:=nil; Fh:=nil;

NormalMatrix.Free;

raise Exception.Create('Неверное динамическое распределение

памяти');

exit;

end;

on EOutOfMemory do

begin

Fc:=nil; Ft:=nil; Fh:=nil;

NormalMatrix.Free;

raise Exception.Create('Недостаточно памяти');

exit;

end;

end;

for i:=0 to NumOfStr-1 do

begin

SNum:='';

s:=NormalMatrix.Strings[i];

LenOfStr:=Length(s);

NumOfCol:=-1;

for j:=1 to LenOfStr+1 do

begin

if (s[j]<>' ') and (j<>LenOfStr+1) then SNum:=SNum+s[j]

else

begin

NumOfCol:=NumOfCol+1;

if not TryStrToFloat(SNum, Self.Fc[i,NumOfCol]) then

begin

Fc:=nil; Fh:=nil; Ft:=nil;

NormalMatrix.Free;

raise Exception.Create('Неверное преобразование строки в

вещественное число');

86

exit;

end;

SNum:='';

end;

end;

end;

NormalMatrix.Free;

// Алгоритм поиска кратчайшего пути между любыми двумя

// точками в графе, хранящемся в матрице весов.

//

// Флойд, 1962 г.

for i:=0 to Self.FNumberOfTops-1 do

begin

for j:=0 to FNumberOfTops-1 do

begin

Ft[i,j]:=Fc[i,j];

if Fc[i,j]=FInfinity then Fh[i,j]:=0

else Fh[i,j]:=j+1;

end;

end;

for i:=0 to FNumberOfTops-1 do

begin

for j:=0 to FNumberOfTops-1 do

begin

for k:=0 to FNumberOfTops-1 do

begin

if (i<>j) and (Ft[j,i]<>FInfinity) and (i<>k) and

(Ft[i,k]<>FInfinity) and

((Ft[j,k]=FInfinity) or (Ft[j,k]>Ft[j,i]+Ft[i,k])) then

begin

Fh[j,k]:=Fh[j,i];

Ft[j,k]:=Ft[j,i]+Ft[i,k];

end;

87

end;

end;

for j:=0 to FNumberOfTops-1 do

begin

if Ft[j,j]<0 then

begin

raise Exception.Create('Нет решения!');

exit;

end;

end;

end;

end;

function TFloydAlgorithmDynamic.GetLengthes: TDoubleDynArray;

begin

if Assigned(Self.Ft) then Result:=Ft

else Result:=nil;

end;

function TFloydAlgorithmDynamic.GetPathes: TIntDynArray;

begin

if Assigned(Self.Fh) then Result:=Fh

else Result:=nil;

end;

function TFloydAlgorithmDynamic.GetWeightMatrix: TDoubleDynArray;

begin

if Assigned(Self.Fc) then Result:=Fc

else Result:=nil;

end;

end.

unit MainUnit;

88

interface

uses

Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls,

Forms,

Dialogs, FloydAlgorithm, Menus, ComCtrls, ToolWin, ActnList, StdActns,

ImgList;

type

TMainForm = class(TForm)

MainMenu1: TMainMenu;

File1: TMenuItem;

New1: TMenuItem;

Edit1: TMenuItem;

Cfncel1: TMenuItem;

N1: TMenuItem;

N2: TMenuItem;

N3: TMenuItem;

N4: TMenuItem;

N5: TMenuItem;

N6: TMenuItem;

N7: TMenuItem;

N8: TMenuItem;

N9: TMenuItem;

N10: TMenuItem;

N11: TMenuItem;

N12: TMenuItem;

ToolBar1: TToolBar;

ToolButton1: TToolButton;

ToolButton2: TToolButton;

ToolButton3: TToolButton;

ToolButton5: TToolButton;

StatusBar: TStatusBar;

N13: TMenuItem;

N14: TMenuItem;

N15: TMenuItem;

89

N16: TMenuItem;

N17: TMenuItem;

ActionList1: TActionList;

DeleteAllPieces: TAction;

DeleteAllCircles: TAction;

DeleteAllBricks: TAction;

DeleteAllShapes: TAction;

ShowParametersForm: TAction;

N18: TMenuItem;

NewFile: TAction;

N19: TMenuItem;

OpenDialog: TOpenDialog;

OpenFile: TAction;

SaveDialog: TSaveDialog;

SaveFileAs: TAction;

SaveFile: TAction;

WindowCascade: TWindowCascade;

WindowTileHorizontal: TWindowTileHorizontal;

WindowTileVertical: TWindowTileVertical;

WindowMinimizeAll: TWindowMinimizeAll;

N20: TMenuItem;

N22: TMenuItem;

N23: TMenuItem;

N24: TMenuItem;

MakeWizard: TAction;

OptimizeByDistace: TAction;

OptimizeByTime: TAction;

ZoomIn: TAction;

ZoomOut: TAction;

N21: TMenuItem;

N25: TMenuItem;

NormalSize: TAction;

N26: TMenuItem;

About: TAction;

ToolButton6: TToolButton;

ToolButton7: TToolButton;

90

ToolButton9: TToolButton;

ToolButton10: TToolButton;

ImageList1: TImageList;

ToolButton4: TToolButton;

ToolButton8: TToolButton;

procedure N12Click(Sender: TObject);

procedure BMP1Click(Sender: TObject);

procedure N4Click(Sender: TObject);

procedure DeleteAllPiecesExecute(Sender: TObject);

procedure DeleteAllCirclesExecute(Sender: TObject);

procedure DeleteAllBricksExecute(Sender: TObject);

procedure DeleteAllShapesExecute(Sender: TObject);

procedure ShowParametersFormExecute(Sender: TObject);

procedure NewFileExecute(Sender: TObject);

procedure OpenFileExecute(Sender: TObject);

procedure SaveFileAsExecute(Sender: TObject);

procedure SaveFileExecute(Sender: TObject);

procedure MakeWizardExecute(Sender: TObject);

procedure OptimizeByDistaceExecute(Sender: TObject);

procedure OptimizeByTimeExecute(Sender: TObject);

procedure ZoomInExecute(Sender: TObject);

procedure ZoomOutExecute(Sender: TObject);

procedure NormalSizeExecute(Sender: TObject);

procedure AboutExecute(Sender: TObject);

private

Counter: Integer;

Top1,Top2: Integer;

public

{ Public declarations }

end;

var

MainForm: TMainForm;

implementation

91

uses PaintFormUnit, ParametersFormUnit, AboutFormUnit;

{$R *.dfm}

procedure TMainForm.N12Click(Sender: TObject);

begin

ParametersForm.ShowModal;

end;

procedure TMainForm.BMP1Click(Sender: TObject);

begin

PaintForm.Image.Picture.Bitmap.SaveToFile('Image.bmp');

end;

procedure TMainForm.N4Click(Sender: TObject);

begin

Application.Terminate;

end;

procedure TMainForm.DeleteAllPiecesExecute(Sender: TObject);

begin

PaintForm.Shapes.ClearPieces;

end;

procedure TMainForm.DeleteAllCirclesExecute(Sender: TObject);

begin

PaintForm.Shapes.ClearCircles;

end;

procedure TMainForm.DeleteAllBricksExecute(Sender: TObject);

begin

PaintForm.Shapes.ClearBricks;

end;

procedure TMainForm.DeleteAllShapesExecute(Sender: TObject);

begin

92

PaintForm.Shapes.Clear;

end;

procedure TMainForm.ShowParametersFormExecute(Sender: TObject);

begin

ParametersForm.ShowModal;

end;

procedure TMainForm.NewFileExecute(Sender: TObject);

begin

Inc(Counter);

with TPaintForm.Create(Self) do

begin

Caption:='noname'+IntToStr(Counter)+'.scm';

Show;

end;

end;

procedure TMainForm.OpenFileExecute(Sender: TObject);

begin

if OpenDialog.Execute then

begin

PaintForm.Shapes.LoadFromFile(OpenDialog.FileName);

PaintForm.Caption:=ExtractFileName(OpenDialog.FileName);

PaintForm.CurFileName:=OpenDialog.FileName;

end;

end;

procedure TMainForm.SaveFileAsExecute(Sender: TObject);

begin

if SaveDialog.Execute then

begin

if SaveDialog.FilterIndex=2 then

PaintForm.Image.Picture.Bitmap.SaveToFile(SaveDialog.FileName)

else

begin

93

PaintForm.Shapes.SaveToFile(SaveDialog.FileName);

PaintForm.CurFileName:=SaveDialog.FileName;

end;

end;

end;

procedure TMainForm.SaveFileExecute(Sender: TObject);

begin

if PaintForm.CurFileName='' then MainForm.SaveFileAsExecute(MainForm)

else PaintForm.Shapes.SaveToFile(PaintForm.CurFileName);

end;

procedure TMainForm.MakeWizardExecute(Sender: TObject);

begin

PaintForm.Graph.Clear;

PaintForm.MakeWizard;

end;

procedure TMainForm.OptimizeByDistaceExecute(Sender: TObject);

var Time,Dist: Double;

s: String;

begin

if PaintForm.Graph.NumberOfTops>0 then

begin

if PaintForm.GetTopSuccess(Top1,Top2) then

begin

PaintForm.FindOptimalPath(PaintForm.Graph.WeightMatrixDist,Top1,Top2

,Dist,Time);

if Dist=PaintForm.Graph.Infinity then s:='Нет пути в указанную

точку.'

else s:='Длина кратчайшего пути равна '+FloatToStr(Dist)+

' единиц расстояния.';

StatusBar.SimpleText:=s;

end

else

94

raise Exception.Create('Вы не указали на схеме положение

транспортного средства и пункта назначения!');

end

else PaintForm.MakeWizard;

end;

procedure TMainForm.OptimizeByTimeExecute(Sender: TObject);

var Time,Dist: Double;

s: String;

begin

if PaintForm.Graph.NumberOfTops>0 then

begin

if PaintForm.GetTopSuccess(Top1,Top2) then

begin

PaintForm.FindOptimalPath(PaintForm.Graph.WeightMatrixTime,Top1,Top2

,Dist,Time);

if Time=PaintForm.Graph.Infinity then s:='Нет пути в указанную

точку.'

else s:='Этот путь можно преодолеть за '+FloatToStr(Time)+

' единиц времени.';

StatusBar.SimpleText:=s;

end

else

raise Exception.Create('Вы не указали на схеме положение

транспортного средства и пункта назначения!');

end

else PaintForm.MakeWizard;

end;

procedure TMainForm.ZoomInExecute(Sender: TObject);

begin

PaintForm.ScrollBox.HorzScrollBar.Range:=PaintForm.ScrollBox.HorzScrollB

ar.Range+200;

PaintForm.ScrollBox.VertScrollBar.Range:=PaintForm.ScrollBox.VertScrollB

ar.Range+200;

PaintForm.Image.Width:=PaintForm.Image.Width+200;

95

PaintForm.Image.Height:=PaintForm.Image.Height+200;

If PaintForm.Image.Width=1024 then

begin

PaintForm.ImageHasNormalSize:=true;

PaintForm.Image.Cursor:=crCross;

end

else

begin

PaintForm.ImageHasNormalSize:=false;

PaintForm.Image.Cursor:=crNo;

end;

end;

procedure TMainForm.ZoomOutExecute(Sender: TObject);

begin

if PaintForm.Image.Width>200 then

begin

PaintForm.ScrollBox.HorzScrollBar.Range:=PaintForm.ScrollBox.HorzScrol

lBar.Range-200;

PaintForm.ScrollBox.VertScrollBar.Range:=PaintForm.ScrollBox.VertScrol

lBar.Range-200;

PaintForm.Image.Width:=PaintForm.Image.Width-200;

PaintForm.Image.Height:=PaintForm.Image.Height-200;

end;

If PaintForm.Image.Width=1024 then

begin

PaintForm.ImageHasNormalSize:=true;

PaintForm.Image.Cursor:=crCross;

end

else

begin

PaintForm.ImageHasNormalSize:=false;

PaintForm.Image.Cursor:=crNo;

end;

end;

96

procedure TMainForm.NormalSizeExecute(Sender: TObject);

begin

PaintForm.ScrollBox.HorzScrollBar.Range:=1024;

PaintForm.ScrollBox.VertScrollBar.Range:=768;

PaintForm.Image.Width:=1024;

PaintForm.Image.Height:=768;

PaintForm.ImageHasNormalSize:=true;

PaintForm.Image.Cursor:=crCross;

end;

procedure TMainForm.AboutExecute(Sender: TObject);

begin

AboutBox.ShowModal;

end;

end.

unit PaintFormUnit;

interface

uses

Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls,

Forms,

Dialogs, ExtCtrls, ComCtrls, StdCtrls, Spin, ToolWin, Shapes,

Buttons, Math, SchemeObjects, FloydAlgorithm;

type

TPaintForm = class(TForm)

Panel2: TPanel;

ScrollBox: TScrollBox;

Image: TImage;

SpeedButton1: TSpeedButton;

SpeedButton2: TSpeedButton;

SpeedButton3: TSpeedButton;

SpeedButton4: TSpeedButton;

SpeedButton5: TSpeedButton;

97

SpeedButton6: TSpeedButton;

SpeedButton7: TSpeedButton;

SpeedButton8: TSpeedButton;

SpeedButton9: TSpeedButton;

procedure FormClose(Sender: TObject; var Action: TCloseAction);

procedure ImageMouseUp(Sender: TObject; Button: TMouseButton;

Shift: TShiftState; X, Y: Integer);

procedure ImageMouseDown(Sender: TObject; Button: TMouseButton;

Shift: TShiftState; X, Y: Integer);

procedure ImageMouseMove(Sender: TObject; Shift: TShiftState; X,

Y: Integer);

procedure FormCreate(Sender: TObject);

procedure FormActivate(Sender: TObject);

procedure ImageClick(Sender: TObject);

private

X1, Y1, X2, Y2, CanvasHeight, CanvasWidth: Integer;

procedure CorrectCoordOfPiece;

procedure CorrectCoordOfPoint (var x,y: Integer);

public

ImageHasNormalSize: Boolean;

Shapes: TShapes;

Graph: TGraph;

Floyd: TFloydAlgorithmDynamic;

CurFileName: TFileName;

procedure ImageChange (Sender: TObject);

procedure PaintGrid;

procedure MakeWizard;

procedure FindOptimalPath(const WeightMatrix: TStringList; const

Top1,Top2: Integer;

out Dist,Time: Double);

function LengthOfPath (const x1,y1,x2,y2: Integer; LenOfPix: Double):

Double;

function GetTopSuccess(out Top1,Top2: Integer): Boolean;

end;

var

98

PaintForm: TPaintForm;

implementation

uses MainUnit, WizardFormUnit;

{$R *.dfm}

procedure TPaintForm.FormClose(Sender: TObject; var Action: TCloseAction);

begin

Shapes.Free;

Graph.Free;

Action:=caFree;

end;

procedure TPaintForm.ImageMouseUp(Sender: TObject; Button: TMouseButton;

Shift: TShiftState; X, Y: Integer);

var Index: Integer;

begin

If ImageHasNormalSize then

begin

if Button=mbLeft then

begin

if SpeedButton1.Down then

begin

ShowMessage('Диалоговое окно настройки');

end

else if SpeedButton2.Down then

begin

X2:=X;

Y2:=Y;

CorrectCoordOfPiece;

Shapes.AddPiece(X1,Y1,X2,Y2);

X1:=-1;Y1:=-1;

99

end

else if SpeedButton3.Down then

Shapes.AddCircle(X,Y,10)

else if SpeedButton4.Down then

Shapes.AddBrick(x,y)

else if SpeedButton5.Down then

Shapes.AddTrafficLight(x,y)

else if SpeedButton6.Down then

Shapes.AddUnDes(x,y)

else if SpeedButton7.Down then

begin

CorrectCoordOfPoint(x,y);

if (x<>-1) and (y<>-1) then

Shapes.SetTransportPos(x,y);

end

else if SpeedButton8.Down then

begin

CorrectCoordOfPoint(x,y);

if (x<>-1) and (y<>-1) then

if Shapes.NumberOfCheckPoints<>0 then

Shapes.ClearCheckPoints;

Shapes.AddCheckPoint(x,y);

end

else if SpeedButton9.Down then

begin

if Shapes.ThePointSelectsPiece(X,Y,10,Index) then

Shapes.DeletePiece(Index);

if Shapes.ThePointSelectsBrick(x,y,10,Index) then

Shapes.DeleteBrick(Index);

if Shapes.ThePointSelectsTrafficLight(x,y,10,Index) then

Shapes.DeleteTrafficLight(Index);

if Shapes.ThePointSelectsUnDes(x,y,10,Index) then

Shapes.DeleteUnDes(Index);

if Shapes.ThePointSelectsCircle(X,Y,Index) then

Shapes.DeleteCircle(Index);

end;

100

end;

end;

end;

procedure TPaintForm.ImageMouseDown(Sender: TObject; Button: TMouseButton;

Shift: TShiftState; X, Y: Integer);

begin

if Button=mbLeft then

begin

X1:=X; Y1:=Y;

end;

end;

procedure TPaintForm.ImageMouseMove(Sender: TObject; Shift: TShiftState;

X, Y: Integer);

var d: Double;

begin

if (SpeedButton2.Down) and (x1<>-1) and (y1<>-1) then

begin

X2:=X; Y2:=Y;

CorrectCoordOfPiece;

d:=LengthOfPath(x1,y1,x2,y2,1);

MainForm.StatusBar.SimpleText:=Format('%d : %d; Длина: %f',[X,Y,d]);

end

else MainForm.StatusBar.SimpleText:=Format('%d : %d',[X,Y]);

end;

procedure TPaintForm.FormCreate(Sender: TObject);

var Rect: TRect;

begin

Image.Height:=768; CanvasHeight:=Image.Height;

Image.Width:=1024; CanvasWidth:=Image.Width;

ImageHasNormalSize:=True;

Image.Canvas.Brush.Color:=clSkyBlue;

Rect.Left:=0;

101

Rect.Top:=0;

Rect.Right:=1024;

Rect.Bottom:=768;

Image.Canvas.FillRect(Rect);

Shapes:=TShapes.Create;

Shapes.OnChange:=ImageChange;

Graph:=TGraph.Create(1000000.0);

Self.PaintGrid;

CurFileName:='';

x1:=-1; y1:=-1;

end;

procedure TPaintForm.ImageChange(Sender: TObject);

var i,x1,y1,x2,y2,cx,cy,r,x,y: Integer;

k,b: Double;

Rect: TRect;

begin

Rect.Left:=0;

Rect.Top:=0;

Rect.Right:=1024;

Rect.Bottom:=768;

Image.Canvas.FillRect(Rect);

PaintGrid;

Image.Canvas.Pen.Width:=10;

Image.Canvas.Pen.Color:=clYellow;

for i:=0 to Shapes.NumberOfPieces-1 do

begin

Shapes.GetPiece(i,x1,y1,x2,y2,k,b);

Image.Canvas.MoveTo(x1,y1);

Image.Canvas.LineTo(x2,y2);

end;

Image.Canvas.Pen.Width:=1;

Image.Canvas.Brush.Color:=clBlue;

for i:=0 to Shapes.NumberOfCircles-1 do

begin

Shapes.GetCircle(i,x1,y1,x2,y2,cx,cy,r);

102

Image.Canvas.Ellipse(x1,y1,x2,y2);

end;

for i:=0 to Shapes.NumberOfBricks-1 do

begin

Shapes.GetBrick(i,x,y);

Image.Canvas.Brush.Color:=clRed;

Image.Canvas.Rectangle(x-5,y-5,x+5,y+5);

end;

for i:=0 to Shapes.NumberOfTrafficLights-1 do

begin

Shapes.GetTrafficLight(i,x,y);

Image.Canvas.Brush.Color:=clLime;

Image.Canvas.Rectangle(x-5,y-5,x+5,y+5);

end;

for i:=0 to Shapes.NumberOfUnDeses-1 do

begin

Shapes.GetUnDes(i,x,y);

Image.Canvas.Brush.Color:=clFuchsia;

Image.Canvas.Rectangle(x-5,y-5,x+5,y+5);

end;

for i:=0 to Shapes.NumberOfCheckPoints-1 do

begin

Shapes.GetCheckPoint(i,x,y);

Image.Canvas.Brush.Color:=clAqua;

Image.Canvas.Rectangle(x-10,y-10,x+10,y+10);

end;

Image.Canvas.Pen.Width:=3;

Image.Canvas.Pen.Color:=clRed;

if (Shapes.TransportPos.X>-1) and (Shapes.TransportPos.Y>-1) then

begin

Image.Canvas.MoveTo(Shapes.TransportPos.X-10,Shapes.TransportPos.Y);

Image.Canvas.LineTo(Shapes.TransportPos.X+10,Shapes.TransportPos.Y);

Image.Canvas.MoveTo(Shapes.TransportPos.X,Shapes.TransportPos.Y-10);

Image.Canvas.LineTo(Shapes.TransportPos.X,Shapes.TransportPos.Y+10);

end;

103

Image.Canvas.Pen.Color:=clYellow;

Image.Canvas.Brush.Color:=clSkyBlue;

end;

procedure TPaintForm.PaintGrid;

var j: Integer;

begin

Image.Canvas.Pen.Width:=1;

Image.Canvas.Pen.Color:=clBlue;

j:=0;

while j<768 do

begin

Inc(j,20);

Image.Canvas.MoveTo(0,j);

Image.Canvas.LineTo(1024,j);

end;

j:=0;

while j<1024 do

begin

Inc(j,20);

Image.Canvas.MoveTo(j,0);

Image.Canvas.LineTo(j,768);

end;

end;

procedure TPaintForm.FormActivate(Sender: TObject);

begin

PaintForm:=Self;

end;

function TPaintForm.LengthOfPath(const x1, y1, x2, y2: Integer; LenOfPix:

Double): Double;

begin

if x1=x2 then Result:=(Max(y1,y2)-Min(y1,y2))*LenOfPix

else

104

Result:=LenOfPix*Round(Sqrt((Max(x1,x2)-Min(x1,x2))*(Max(x1,x2)-

Min(x1,x2))+

(Max(y1,y2)-Min(y1,y2))*(Max(y1,y2)-Min(y1,y2))));

end;

procedure TPaintForm.CorrectCoordOfPiece;

var lx1,ly1,lx2,ly2,Index,MaxX,MinX,MaxY,MinY: Integer;

k,b: Double;

begin

if Shapes.ThePointSelectsPiece(X1,Y1,10,Index) then

begin

Shapes.GetPiece(Index,lx1,ly1,lx2,ly2,k,b);

if lx1=lx2 then

begin

MaxY:=Max(ly1,ly2);

MinY:=Min(ly1,ly2);

X1:=lx1;

if (Y1-MinY)<(MaxY-Y1) then Y1:=MinY

else Y1:=MaxY;

end

else

begin

MaxX:=Max(lx1,lx2);

MinX:=Min(lx1,lx2);

MaxY:=Max(ly1,ly2);

MinY:=Min(ly1,ly2);

if (X1-MinX)<(MaxX-X1) then X1:=MinX

else X1:=MaxX;

if (Y1-MinY)<(MaxY-Y1) then Y1:=MinY

else Y1:=MaxY;

end;

end;

if Shapes.ThePointSelectsPiece(X2,Y2,10,Index) then

begin

Shapes.GetPiece(Index,lx1,ly1,lx2,ly2,k,b);

if lx1=lx2 then

105

begin

MaxY:=Max(ly1,ly2);

MinY:=Min(ly1,ly2);

X2:=lx1;

if (Y2-MinY)<(MaxY-Y2) then Y2:=MinY

else Y2:=MaxY;

end

else

begin

MaxX:=Max(lx1,lx2);

MinX:=Min(lx1,lx2);

MaxY:=Max(ly1,ly2);

MinY:=Min(ly1,ly2);

if (X2-MinX)<(MaxX-X2) then X2:=MinX

else X2:=MaxX;

if (Y2-MinY)<(MaxY-Y2) then Y2:=MinY

else Y2:=MaxY;

end;

end;

end;

procedure TPaintForm.MakeWizard;

var WizForm: TWizardForm;

begin

WizForm:=TWizardForm.Create(Self);

WizForm.Show;

PaintForm.Enabled:=false;

MainForm.Enabled:=false;

end;

procedure TPaintForm.ImageClick(Sender: TObject);

begin

if (not SpeedButton8.Down) and (not SpeedButton7.Down)

and (not SpeedButton1.Down) then

if Graph.NumberOfTops>0 then Graph.Clear;

106

end;

procedure TPaintForm.FindOptimalPath(const WeightMatrix: TStringList;

const Top1,Top2: Integer; out Dist,Time: Double);

var i,j,k,Num,x,y,x1,y1,x2,y2: Integer;

begin

Floyd:=TFloydAlgorithmDynamic.Create(1000000.0);

Floyd.Execute(WeightMatrix);

Time:=-1; Dist:=-1;

if WeightMatrix=Graph.WeightMatrixTime then

Time:=Floyd.MatrixOfLengthesOfShortestPathes[Top1-1,Top2-1]

else Dist:=Floyd.MatrixOfLengthesOfShortestPathes[Top1-1,Top2-1];

i:=-1;j:=Top1-1;

while i<>Top2 do

begin

i:=Floyd.MatrixOfShortestPathes[j,Top2-1];

x1:=-1;y1:=-1;x2:=-1;y2:=-1;

for k:=0 to Graph.NumberOfTops-1 do

begin

Graph.GetTop(k,x,y,Num);

if Num=j+1 then

begin

x1:=x; y1:=y;

break;

end;

end;

for k:=0 to Graph.NumberOfTops-1 do

begin

Graph.GetTop(k,x,y,Num);

if Num=i then

begin

x2:=x; y2:=y;

break;

107

end;

end;

if (x1>-1) and (y1>-1) then

PaintForm.Image.Canvas.MoveTo(x1,y1);

PaintForm.Image.Canvas.Pen.Width:=10;

if WeightMatrix=Graph.WeightMatrixTime then

PaintForm.Image.Canvas.Pen.Color:=clLime

else PaintForm.Image.Canvas.Pen.Color:=clAqua;

if (x2>-1) and (y2>-1) then

PaintForm.Image.Canvas.LineTo(x2,y2);

j:=i-1;

if j=-1 then

begin

FreeAndNil(Floyd);

exit;

end;

end;

FreeAndNil(Floyd);

end;

procedure TPaintForm.CorrectCoordOfPoint(var x, y: Integer);

var lx1,ly1,lx2,ly2,Index,MaxX,MinX,MaxY,MinY: Integer;

k,b: Double;

begin

if Shapes.ThePointSelectsPiece(X,Y,10,Index) then

begin

Shapes.GetPiece(Index,lx1,ly1,lx2,ly2,k,b);

if lx1=lx2 then

begin

MaxY:=Max(ly1,ly2);

MinY:=Min(ly1,ly2);

x:=lx1;

if (y-MinY)<(MaxY-y) then y:=MinY

else y:=MaxY;

exit;

end

108

else

begin

MaxX:=Max(lx1,lx2);

MinX:=Min(lx1,lx2);

MaxY:=Max(ly1,ly2);

MinY:=Min(ly1,ly2);

if (x-MinX)<(MaxX-x) then x:=MinX

else x:=MaxX;

if (y-MinY)<(MaxY-y) then y:=MinY

else y:=MaxY;

exit;

end;

end;

x:=-1; y:=-1;

end;

function TPaintForm.GetTopSuccess(out Top1, Top2: Integer): Boolean;

var i,x,y,Num,x1,y1: Integer;

begin

Top1:=0; Top2:=0;

if (Shapes.TransportPos.X>-1) and

(Shapes.TransportPos.Y>-1) and

(Shapes.NumberOfCheckPoints>0) then

begin

Shapes.GetCheckPoint(0,x1,y1);

for i:=0 to Graph.NumberOfTops-1 do

begin

Graph.GetTop(i,x,y,Num);

if (x=Shapes.TransportPos.X) and (y=Shapes.TransportPos.Y) then

Top1:=Num;

if (x=x1) and (y=y1) then Top2:=Num;

end;

if (Top1>0) and (Top2>0) then

begin

Result:=true;

exit;

109

end;

end;

Result:=false;

end;

end.

unit SchemeObjects;

interface

uses Classes, SysUtils, IniFiles, Graphics, Math, Types, Shapes;

type

TDynArrDoub = array of array of Double;

TGraph = class (TObject)

private

FOnChange: TNotifyEvent;

FTops: TStringList;

FArches: TStringList;

FWeightMatrixDist: TStringList;

FWeightMatrixTime: TStringList;

FInfinity: Double;

function GetNumberOfArches: Integer;

function GetNumberOfTops: Integer;

function GetWeightMatrixDist: TStringList;

function GetWeightMatrixTime: TStringList;

protected

procedure DoChange; dynamic;

public

constructor Create (const AttrOfInfinity: Double);

procedure AddTop (const x,y,Num: Integer);

procedure AddArch (const Top1,Top2,Direction,UnDes: Integer; const

Distance,MaxSpeed: Double);

procedure GetArch (const Index: Integer;

110

out Top1,Top2,Direction,UnDes: Integer; out

Distance,MaxSpeed: Double);

procedure GetTop (const Index: Integer; out x,y,Num: Integer);

procedure Clear;

procedure FillWeightMatrixes;

property WeightMatrixDist: TStringList read GetWeightMatrixDist;

property WeightMatrixTime: TStringList read GetWeightMatrixTime;

property NumberOfTops: Integer read GetNumberOfTops;

property NumberOfArches: Integer read GetNumberOfArches;

property Infinity: Double read FInfinity;

end;

implementation

{ TSchemeObjects }

procedure TGraph.AddArch (const Top1,Top2,Direction,UnDes: Integer;

const Distance,MaxSpeed: Double);

var Dir: Integer;

begin

Dir:=Direction;

if Dir<0 then Dir:=0;

if Dir>3 then Dir:=3;

FArches.Add(IntToStr(Top1)+';'+IntToStr(Top2)+';'+IntToStr(Dir)+';'+

FloatToStr(Distance)+';'+FloatToStr(MaxSpeed)+';'+IntToStr(UnDes)+';');

DoChange;

end;

procedure TGraph.AddTop(const x, y, Num: Integer);

begin

FTops.Add(IntToStr(x)+';'+IntToStr(y)+';'+IntToStr(Num)+';');

DoChange;

end;

procedure TGraph.Clear;

begin

111

FTops.Clear;

FArches.Clear;

FWeightMatrixDist.Clear;

FWeightMatrixTime.Clear;

end;

constructor TGraph.Create (const AttrOfInfinity: Double);

begin

FTops:=TStringList.Create;

FArches:=TStringList.Create;

FWeightMatrixDist:=TStringList.Create;

FWeightMatrixTime:=TStringList.Create;

FInfinity:=AttrOfInfinity;

end;

procedure TGraph.DoChange;

begin

if Assigned (FOnChange) then FOnChange (Self);

end;

procedure TGraph.FillWeightMatrixes;

var i,n,j: Integer;

Top1,Top2,Direction,UnDes: Integer;

Distance,MaxSpeed,Time: Double;

WMatrix: TDynArrDoub;

s: String;

begin

FWeightMatrixDist.Clear;

FWeightMatrixTime.Clear;

n:=FTops.Count;

WMatrix:=nil;

try

SetLength (WMatrix,n);

for i:=0 to n-1 do SetLength(WMatrix[i],n);

except

on EHeapException do

112

begin

WMatrix:=nil;

raise Exception.Create('Неверное динамическое распределение

памяти');

exit;

end;

on EOutOfMemory do

begin

WMatrix:=nil;

raise Exception.Create('Недостаточно памяти');

exit;

end;

end;

// Заполнение матрицы весов значениями расстояния

for i:=0 to n-1 do

for j:=0 to n-1 do

if i=j then WMatrix[i,j]:=0.0 else WMatrix[i,j]:=FInfinity;

for i:=0 to FArches.Count-1 do

begin

Self.GetArch(i,Top1,Top2,Direction,UnDes,Distance,MaxSpeed);

case Direction of

// 0: WMatrix[Top1-1,Top2-1]:=FInfinity

1: WMatrix[Top1-1,Top2-1]:=Distance;

2: WMatrix[Top2-1,Top1-1]:=Distance;

3:

begin

WMatrix[Top1-1,Top2-1]:=Distance;

WMatrix[Top2-1,Top1-1]:=Distance;

end;

end;

end;

113

for i:=0 to n-1 do

begin

s:='';

for j:=0 to n-1 do

s:=s+FloatToStr(WMatrix[i,j])+' ';

FWeightMatrixDist.Add(s);

end;

// Заполнение матрицы весов значениями времени

for i:=0 to n-1 do

for j:=0 to n-1 do

if i=j then WMatrix[i,j]:=0.0 else WMatrix[i,j]:=FInfinity;

for i:=0 to FArches.Count-1 do

begin

Self.GetArch(i,Top1,Top2,Direction,UnDes,Distance,MaxSpeed);

Time:=Distance/MaxSpeed;

case Direction of

1: WMatrix[Top1-1,Top2-1]:=Time;

2: WMatrix[Top2-1,Top1-1]:=Time;

3:

begin

WMatrix[Top1-1,Top2-1]:=Time;

WMatrix[Top2-1,Top1-1]:=Time;

end;

end;

end;

for i:=0 to n-1 do

begin

s:='';

for j:=0 to n-1 do

s:=s+FloatToStr(WMatrix[i,j])+' ';

FWeightMatrixTime.Add(s);

114

end;

WMatrix:=nil;

end;

procedure TGraph.GetArch(const Index: Integer;

out Top1, Top2, Direction, UnDes: Integer; out Distance,

MaxSpeed: Double);

var i,j: Integer;

s,SNum: String;

begin

s:=FArches.Strings[Index];

SNum:=''; j:=0;

for i:=1 to Length(s) do

begin

if s[i]<>';' then SNum:=SNum+s[i]

else

begin

j:=j+1;

case j of

1: Top1:=StrToInt(SNum);

2: Top2:=StrToInt(SNum);

3: Direction:=StrToInt(SNum);

4: Distance:=StrToFloat(SNum);

5: MaxSpeed:=StrToFloat(SNum);

else

UnDes:=StrToInt(SNum);

end;

SNum:='';

end;

end;

end;

function TGraph.GetNumberOfArches: Integer;

begin

Result:=FArches.Count;

115

end;

function TGraph.GetNumberOfTops: Integer;

begin

Result:=FTops.Count;

end;

procedure TGraph.GetTop(const Index: Integer; out x, y, Num: Integer);

var i,j: Integer;

s,SNum: String;

begin

s:=FTops.Strings[Index];

SNum:=''; j:=0;

for i:=1 to Length(s) do

begin

if s[i]<>';' then SNum:=SNum+s[i]

else

begin

j:=j+1;

case j of

1: x:=StrToInt(SNum);

2: y:=StrToInt(SNum);

else

Num:=StrToInt(SNum);

end;

SNum:='';

end;

end;

end;

function TGraph.GetWeightMatrixDist: TStringList;

begin

if FWeightMatrixDist.Count <> 0 then Result:=FWeightMatrixDist

else Result:=nil;

end;

116

function TGraph.GetWeightMatrixTime: TStringList;

begin

if FWeightMatrixTime.Count <> 0 then Result:=FWeightMatrixTime

else Result:=nil;

end;

end.

unit Shapes;

interface

uses Classes, SysUtils, IniFiles, Graphics, Math, Types;

type

TTerminatorType = (ttBrick, ttTrafficLight, ttUnDes, ttCheckPoint);

TShapes = class (TObject)

private

FOnChange: TNotifyEvent;

FPieces: TStringList;

FCircles: TStringList;

FBricks: TStringList;

FTrafficLights: TStringList;

FUndeses: TStringList;

FCheckPoints: TStringList;

FTransport: TPoint;

function GetNumberOfCheckPoints: Integer;

function GetNumberOfPieces: Integer;

function GetNumberOfCircles: Integer;

function GetNumberOfBricks: Integer;

function GetNumberOfTrafficLights: Integer;

function GetNumberOfUnDeses: Integer;

function GetTransportPos: TPoint;

function CheckTransportExists: Boolean;

117

function ThePointSelectsTerminator (const x,y,SizeOfTer: Integer;

const TerType: TTerminatorType; out Index: Integer):

Boolean;

function ThePointBelongsForTerminator (const x,y: Integer;

const TerType: TTerminatorType; out Index: Integer):

Boolean;

procedure GetTerminator (const Index: Integer;

const TerType: TTerminatorType; out x,y: Integer);

procedure DeleteTerminator (const x,y: Integer;

const TerType: TTerminatorType); overload;

procedure DeleteTerminator (const Index: Integer;

const TerType: TTerminatorType); overload;

protected

procedure DoChange; dynamic;

public

constructor Create;

function ThePointBelongsForCheckPoint (const X,Y: Integer;

out Index: Integer): Boolean;

function ThePointBelongsForUnDes (const X,Y: Integer;

out Index: Integer): Boolean;

function ThePointBelongsForTrafficLight (const X,Y: Integer;

out Index: Integer): Boolean;

function ThePointBelongsForBrick (const X,Y: Integer;

out Index: Integer): Boolean;

function ThePointBelongsForPiece (const X,Y: Integer;

out Index: Integer): Boolean;

function ThePointBelongsForCircle (const X,Y: Integer;

out Index: Integer): Boolean;

function ThePointSelectsCheckPoint (const X,Y,SizeOfCheckPoint:

Integer;

out Index: Integer): Boolean;

function ThePointSelectsBrick (const X,Y,SizeOfBrick: Integer;

out Index: Integer): Boolean;

function ThePointSelectsTrafficLight (const X,Y,SizeOfTrLight:

Integer;

out Index: Integer): Boolean;

118

function ThePointSelectsUnDes (const X,Y,SizeOfUnDes: Integer;

out Index: Integer): Boolean;

function ThePointSelectsCircle (const X,Y: Integer;

out Index: Integer): Boolean;

function ThePointSelectsPiece (const X,Y,WidthOfPiece: Integer;

out Index: Integer): Boolean;

procedure SetTransportPos(const X,Y: Integer);

function GetX1 (const Index: Integer): Integer;

function GetY1 (const Index: Integer): Integer;

function GetX2 (const Index: Integer): Integer;

function GetY2 (const Index: Integer): Integer;

function GetK (const Index: Integer): Double;

function GetB (const Index: Integer): Double;

procedure AddCheckPoint (const x,y: Integer);

procedure AddUnDes (const x,y: Integer);

procedure AddTrafficLight (const x,y: Integer);

procedure AddBrick (const x,y: Integer);

procedure AddCircle (const CenterX, CenterY, Radius: Integer);

procedure AddPiece (const x1, y1, x2, y2: Integer);

procedure GetCheckPoint (const Index: Integer; out x,y: Integer);

procedure GetUnDes (const Index: Integer; out x,y: Integer);

procedure GetTrafficLight (const Index: Integer; out x,y: Integer);

procedure GetBrick (const Index: Integer; out x,y: Integer);

procedure GetCircle (const Index: Integer; out x1,y1,x2,y2,

CenterX,CenterY,Radius: Integer);

procedure GetPiece (const Index: Integer; out x1,y1,x2,y2: Integer;

out k,b: Double);

procedure DeleteCheckPoint (const x, y: Integer); overload;

procedure DeleteCheckPoint (const Index: Integer); overload;

procedure DeleteUnDes (const x, y: Integer); overload;

procedure DeleteUnDes (const Index: Integer); overload;

procedure DeleteTrafficLight (const x, y: Integer); overload;

procedure DeleteTrafficLight (const Index: Integer); overload;

procedure DeleteBrick (const x, y : Integer); overload;

procedure DeleteBrick (const Index: Integer); overload;

procedure DeletePiece (const x, y : Integer); overload;

119

procedure DeletePiece (const Index: Integer); overload;

procedure DeleteCircle (const x, y : Integer); overload;

procedure DeleteCircle (const Index: Integer); overload;

procedure DeleteTransport;

procedure SaveToFile (const FileName: String);

procedure LoadFromFile (const FileName: String);

procedure ClearCheckPoints;

procedure ClearUndeses;

procedure ClearTrafficLights;

procedure ClearBricks;

procedure ClearPieces;

procedure ClearCircles;

procedure Clear;

property OnChange: TNotifyEvent read FOnChange write FOnChange;

property NumberOfPieces: Integer read GetNumberOfPieces;

property NumberOfCircles: Integer read GetNumberOfCircles;

property NumberOfBricks: Integer read GetNumberOfBricks;

property NumberOfTrafficLights: Integer read

GetNumberOfTrafficLights;

property NumberOfUnDeses: Integer read GetNumberOfUnDeses;

property NumberOfCheckPoints: Integer read GetNumberOfCheckPoints;

property TransportPos: TPoint read GetTransportPos;

property TransportExists: Boolean read CheckTransportExists;

end;

implementation

{ TShapes }

procedure TShapes.AddPiece(const x1, y1, x2, y2: Integer);

begin

FPieces.Add(IntToStr(x1)+';'+IntToStr(y1)+';'+IntToStr(x2)+';'+

IntToStr(y2)+';');

DoChange;

end;

120

procedure TShapes.Clear;

begin

FPieces.Clear;

FCircles.Clear;

FBricks.Clear;

FTrafficLights.Clear;

FUndeses.Clear;

FCheckPoints.Clear;

FTransport.X:=-1;

FTransport.Y:=-1;

DoChange;

end;

constructor TShapes.Create;

begin

inherited;

FPieces:=TStringList.Create;

FCircles:=TStringList.Create;

FBricks:=TStringList.Create;

FTrafficLights:=TStringList.Create;

FUndeses:=TStringList.Create;

FCheckPoints:=TStringList.Create;

FTransport.X:=-1;

FTransport.Y:=-1;

end;

procedure TShapes.DeletePiece(const x, y: Integer);

var Index: Integer;

begin

if Self.ThePointBelongsForPiece(x,y,Index) then

begin

FPieces.Delete(Index);

DoChange;

exit;

end;

end;

121

procedure TShapes.DeletePiece(const Index: Integer);

begin

FPieces.Delete(Index);

DoChange;

end;

function TShapes.GetB(const Index: Integer): Double;

var x1,y1,x2,y2: Integer;

k,b: Double;

begin

Self.GetPiece(Index,x1,y1,x2,y2,k,b);

Result:=b;

end;

function TShapes.GetK(const Index: Integer): Double;

var x1,y1,x2,y2: Integer;

k,b: Double;

begin

Self.GetPiece(Index,x1,y1,x2,y2,k,b);

Result:=k;

end;

function TShapes.GetNumberOfPieces: Integer;

begin

Result:=FPieces.Count;

end;

procedure TShapes.GetPiece(const Index: Integer; out x1, y1, x2, y2:

Integer;

out k, b: Double);

var i,j: Integer;

s,SNum: String;

Dx1,Dy1,Dx2,Dy2: Double;

begin

s:=FPieces.Strings[Index];

122

SNum:=''; j:=0;

for i:=1 to Length(s) do

begin

if s[i]<>';' then SNum:=SNum+s[i]

else

begin

j:=j+1;

case j of

1: x1:=StrToInt(SNum);

2: y1:=StrToInt(SNum);

3: x2:=StrToInt(SNum);

else

y2:=StrToInt(SNum);

end;

SNum:='';

end;

end;

Dx1:=x1; Dy1:=y1; Dx2:=x2; Dy2:=y2;

if x1=x2 then k:=0

else k := (Dy2 - Dy1) / (Dx2 - Dx1);

b := Dy1 - k*Dx1;

end;

function TShapes.GetX1(const Index: Integer): Integer;

var x1,y1,x2,y2: Integer;

k,b: Double;

begin

Self.GetPiece(Index,x1,y1,x2,y2,k,b);

Result:=x1;

end;

function TShapes.GetX2(const Index: Integer): Integer;

var x1,y1,x2,y2: Integer;

k,b: Double;

begin

Self.GetPiece(Index,x1,y1,x2,y2,k,b);

123

Result:=x2;

end;

function TShapes.GetY1(const Index: Integer): Integer;

var x1,y1,x2,y2: Integer;

k,b: Double;

begin

Self.GetPiece(Index,x1,y1,x2,y2,k,b);

Result:=y1;

end;

function TShapes.GetY2(const Index: Integer): Integer;

var x1,y1,x2,y2: Integer;

k,b: Double;

begin

Self.GetPiece(Index,x1,y1,x2,y2,k,b);

Result:=y2;

end;

procedure TShapes.LoadFromFile(const FileName: String);

var ImageFile: TIniFile;

StrLst: TStringList;

i: Integer;

function ParameterValue(Str: String): string;

var i,j: Integer;

s: String;

begin

s:='';

for i:=1 to Length(Str) do

if Str[i]='=' then

for j:=i+1 to Length(Str) do s:=s+Str[j];

Result:=s;

end;

124

begin

if not FileExists(FileName) then

begin

raise Exception.Create('Файл '+FileName+' не существует!');

exit;

end;

ImageFile:=TIniFile.Create(FileName);

StrLst:=TStringList.Create;

try

Self.FPieces.Clear; StrLst.Clear;

ImageFile.ReadSectionValues('PIECES',StrLst);

for i:=0 to StrLst.Count-1 do

Self.FPieces.Add(ParameterValue(StrLst.Strings[i]));

Self.FCircles.Clear; StrLst.Clear;

ImageFile.ReadSectionValues('CIRCLES',StrLst);

for i:=0 to StrLst.Count-1 do

Self.FCircles.Add(ParameterValue(StrLst.Strings[i]));

Self.FBricks.Clear; StrLst.Clear;

ImageFile.ReadSectionValues('BRICKS',StrLst);

for i:=0 to StrLst.Count-1 do

Self.FBricks.Add(ParameterValue(StrLst.Strings[i]));

Self.FTrafficLights.Clear; StrLst.Clear;

ImageFile.ReadSectionValues('TRAFFICLIGHTS',StrLst);

for i:=0 to StrLst.Count-1 do

Self.FTrafficLights.Add(ParameterValue(StrLst.Strings[i]));

Self.FUnDeses.Clear; StrLst.Clear;

ImageFile.ReadSectionValues('UNDESES',StrLst);

for i:=0 to StrLst.Count-1 do

Self.FUnDeses.Add(ParameterValue(StrLst.Strings[i]));

Self.FCheckPoints.Clear; StrLst.Clear;

ImageFile.ReadSectionValues('CHECKPOINTS',StrLst);

for i:=0 to StrLst.Count-1 do

Self.FCheckPoints.Add(ParameterValue(StrLst.Strings[i]));

FTransport.X:=ImageFile.ReadInteger('TRANSPORT','X',-1);

FTransport.Y:=ImageFile.ReadInteger('TRANSPORT','Y',-1);

125

finally

ImageFile.Free;

StrLst.Free;

end;

DoChange;

end;

procedure TShapes.SaveToFile(const FileName: String);

var i: Integer;

ImageFile: TIniFile;

begin

if FileExists(FileName) then DeleteFile(FileName);

ImageFile:=TIniFile.Create(FileName);

try

for i:=0 to Self.GetNumberOfPieces-1 do

ImageFile.WriteString('PIECES','PIECE('+IntToStr(i)+')',

Self.FPieces.Strings[i]);

for i:=0 to Self.GetNumberOfCircles-1 do

ImageFile.WriteString('CIRCLES','CIRCLE('+IntToStr(i)+')',

Self.FCircles.Strings[i]);

for i:=0 to Self.GetNumberOfBricks-1 do

ImageFile.WriteString('BRICKS','BRICK('+IntToStr(i)+')',

Self.FBricks.Strings[i]);

for i:=0 to Self.GetNumberOfTrafficLights-1 do

ImageFile.WriteString('TRAFFICLIGHTS','TRAFFICLIGHT('+IntToStr(i)

+')',

Self.FTrafficLights.Strings[i]);

for i:=0 to Self.GetNumberOfUnDeses-1 do

ImageFile.WriteString('UNDESES','UNDES('+IntToStr(i)+')',

Self.FUnDeses.Strings[i]);

for i:=0 to Self.GetNumberOfCheckPoints-1 do

ImageFile.WriteString('CHECKPOINTS','CHECKPOINT('+IntToStr(i)+')',

Self.FCheckPoints.Strings[i]);

ImageFile.WriteInteger('TRANSPORT','X',FTransport.X);

ImageFile.WriteInteger('TRANSPORT','Y',FTransport.Y);

126

finally

ImageFile.Free;

end;

end;

procedure TShapes.DoChange;

begin

if Assigned (FOnChange) then FOnChange (Self);

end;

procedure TShapes.AddCircle(const CenterX, CenterY, Radius: Integer);

begin

FCircles.Add(IntToStr(CenterX)+';'+IntToStr(CenterY)

+';'+IntToStr(Radius)+';');

DoChange;

end;

procedure TShapes.ClearPieces;

begin

FPieces.Clear;

DoChange;

end;

procedure TShapes.ClearCircles;

begin

FCircles.Clear;

DoChange;

end;

function TShapes.GetNumberOfCircles: Integer;

begin

Result:=FCircles.Count;

end;

procedure TShapes.GetCircle(const Index: Integer; out x1, y1, x2, y2,

127

CenterX, CenterY, Radius: Integer);

var i,j: Integer;

s,SNum: String;

begin

s:=FCircles.Strings[Index];

SNum:=''; j:=0;

for i:=1 to Length(s) do

begin

if s[i]<>';' then SNum:=SNum+s[i]

else

begin

j:=j+1;

case j of

1: CenterX:=StrToInt(SNum);

2: CenterY:=StrToInt(SNum);

else

Radius:=StrToInt(SNum);

end;

SNum:='';

end;

end;

x1:=CenterX-Radius;

x2:=CenterX+Radius;

y1:=CenterY-Radius;

y2:=CenterY+Radius;

end;

function TShapes.ThePointBelongsForPiece(const X, Y: Integer;

out Index: Integer): Boolean;

var i,j,x1,y1,x2,y2: Integer;

k,b,Dx,Dy,Dxx,Dyy: Double;

begin

Dx:=x; Dy:=y;

for i:=0 to FPieces.Count-1 do

128

begin

Self.GetPiece(i,x1,y1,x2,y2,k,b);

if ((x=x1) and (y=y1)) or ((x=x2) and (y=y2)) then

begin

Index:=i;

Result:=true;

exit;

end

else if (x=x1) and (x=x2) and (y>Min(y1,y2)) and (y<Max(y1,y2)) then

begin

Index:=i;

Result:=true;

exit;

end

else

begin

if Dy=Round(k*Dx+b) then

begin

for j:=Min(x1,x2) to Max(x1,x2) do

begin

Dxx:=j;

Dyy:=Round(k*Dxx+b);

if (Dxx=Dx) and (Dyy=Dy) then

begin

Index:=i;

Result:=true;

exit;

end;

end;

end;

end;

end;

Index:=-1;

Result:=false;

129

end;

function TShapes.ThePointBelongsForCircle(const X, Y: Integer;

out Index: Integer): Boolean;

var i,x1,y1,x2,y2,CenterX,CenterY,Radius: Integer;

f: Real;

begin

for i:=0 to FCircles.Count-1 do

begin

Self.GetCircle(i,x1,y1,x2,y2,CenterX,CenterY,Radius);

f:=(X-CenterX)*(X-CenterX)+(Y-CenterY)*(Y-CenterY);

if Radius>=Sqrt(f) then

begin

Index:=i;

Result:=true;

exit;

end;

end;

Index:=-1;

Result:=false;

end;

function TShapes.GetTransportPos: TPoint;

begin

Result.X:=FTransport.X;

Result.Y:=FTransport.Y;

end;

procedure TShapes.SetTransportPos(const X, Y: Integer);

begin

if (X>-1) and (Y>-1) then

begin

FTransport.X:=X;

FTransport.Y:=Y;

DoChange;

end;

130

end;

procedure TShapes.DeleteCircle(const Index: Integer);

begin

FCircles.Delete(Index);

DoChange;

end;

procedure TShapes.DeleteCircle(const x, y: Integer);

var Index: Integer;

begin

if Self.ThePointBelongsForCircle(x,y,Index) then

begin

FCircles.Delete(Index);

DoChange;

exit;

end;

end;

procedure TShapes.DeleteTransport;

begin

FTransport.X:=-1;

FTransport.Y:=-1;

DoChange;

end;

function TShapes.CheckTransportExists: Boolean;

begin

if (FTransport.X>-1) and (FTransport.Y>-1) then Result:=true

else Result:=false;

end;

procedure TShapes.AddBrick(const x, y: Integer);

begin

FBricks.Add(IntToStr(X)+';'+IntToStr(Y)+';');

DoChange;

131

end;

function TShapes.GetNumberOfBricks: Integer;

begin

Result:=FBricks.Count;

end;

procedure TShapes.GetTerminator (const Index: Integer; const TerType:

TTerminatorType;

out x,y: Integer);

var i,j: Integer;

s,SNum: String;

begin

s:='';

case TerType of

ttBrick: s:=FBricks.Strings[Index];

ttTrafficLight: s:=FTrafficLights.Strings[Index];

ttUnDes: s:=FUndeses.Strings[Index];

ttCheckPoint: s:=FCheckPoints.Strings[Index];

end;

SNum:=''; j:=0;

for i:=1 to Length(s) do

begin

if s[i]<>';' then SNum:=SNum+s[i]

else

begin

j:=j+1;

if j=1 then X:=StrToInt(SNum)

else Y:=StrToInt(SNum);

SNum:='';

end;

end;

end;

132

procedure TShapes.GetBrick(const Index: Integer; out x, y: Integer);

begin

Self.GetTerminator(Index,ttBrick,x,y);

end;

function TShapes.ThePointBelongsForTerminator(const x, y: Integer;

const TerType: TTerminatorType; out Index: Integer): Boolean;

var i,x1,y1,n: Integer;

begin

n:=-1;

case TerType of

ttBrick: n:=FBricks.Count-1;

ttTrafficLight: n:=FTrafficLights.Count-1;

ttUnDes: n:=FUnDeses.Count-1;

ttCheckPoint: n:=FCheckPoints.Count-1;

end;

for i:=0 to n do

begin

Self.GetTerminator(i,TerType,x1,y1);

if (x=x1) and (y=y1) then

begin

Index:=i;

Result:=true;

exit;

end;

end;

Index:=-1;

Result:=false;

end;

procedure TShapes.DeleteTerminator(const x, y: Integer;

133

const TerType: TTerminatorType);

var Index: Integer;

begin

if ThePointBelongsForTerminator(x,y,TerType,Index) then

begin

case TerType of

ttBrick: FBricks.Delete(Index);

ttTrafficLight: FTrafficLights.Delete(Index);

ttUnDes: FUndeses.Delete(Index);

ttCheckPoint: FCheckPoints.Delete(Index);

end;

end;

end;

procedure TShapes.DeleteTerminator(const Index: Integer;

const TerType: TTerminatorType);

begin

case TerType of

ttBrick: FBricks.Delete(Index);

ttTrafficLight: FTrafficLights.Delete(Index);

ttUnDes: FUndeses.Delete(Index);

ttCheckPoint: FCheckPoints.Delete(Index);

end;

end;

procedure TShapes.AddTrafficLight(const x, y: Integer);

begin

FTrafficLights.Add(IntToStr(x)+';'+IntToStr(y)+';');

DoChange;

end;

procedure TShapes.AddUnDes(const x, y: Integer);

begin

FUnDeses.Add(IntToStr(x)+';'+IntToStr(y)+';');

DoChange;

end;

134

function TShapes.ThePointBelongsForBrick(const X, Y: Integer;

out Index: Integer): Boolean;

begin

if Self.ThePointBelongsForTerminator(x,y,ttBrick,Index) then

Result:=true

else Result:=false;

end;

function TShapes.ThePointBelongsForTrafficLight(const X, Y: Integer;

out Index: Integer): Boolean;

begin

if Self.ThePointBelongsForTerminator(x,y,ttTrafficLight,Index) then

Result:=true

else Result:=false;

end;

function TShapes.ThePointBelongsForUnDes(const X, Y: Integer;

out Index: Integer): Boolean;

begin

if Self.ThePointBelongsForTerminator(x,y,ttUnDes,Index) then

Result:=true

else Result:=false;

end;

procedure TShapes.GetTrafficLight(const Index: Integer; out x, y:

Integer);

begin

Self.GetTerminator(Index,ttTrafficLight,x,y);

end;

procedure TShapes.GetUnDes(const Index: Integer; out x, y: Integer);

begin

Self.GetTerminator(Index,ttUnDes,x,y);

end;

135

procedure TShapes.DeleteBrick(const x, y: Integer);

begin

Self.DeleteTerminator(x,y,ttBrick);

DoChange;

end;

procedure TShapes.DeleteBrick(const Index: Integer);

begin

Self.DeleteTerminator(Index,ttBrick);

DoChange;

end;

procedure TShapes.DeleteTrafficLight(const x, y: Integer);

begin

Self.DeleteTerminator(x,y,ttTrafficLight);

DoChange;

end;

procedure TShapes.DeleteTrafficLight(const Index: Integer);

begin

Self.DeleteTerminator(Index,ttTrafficLight);

DoChange;

end;

procedure TShapes.DeleteUnDes(const x, y: Integer);

begin

Self.DeleteTerminator(x,y,ttUnDes);

DoChange;

end;

procedure TShapes.DeleteUnDes(const Index: Integer);

begin

Self.DeleteTerminator(Index,ttUnDes);

DoChange;

end;

136

procedure TShapes.ClearBricks;

begin

FBricks.Clear;

DoChange;

end;

procedure TShapes.ClearTrafficLights;

begin

FTrafficLights.Clear;

DoChange;

end;

procedure TShapes.ClearUndeses;

begin

FUnDeses.Clear;

DoChange;

end;

function TShapes.GetNumberOfTrafficLights: Integer;

begin

Result:=FTrafficLights.Count;

end;

function TShapes.GetNumberOfUnDeses: Integer;

begin

Result:=FUnDeses.Count;

end;

function TShapes.ThePointSelectsCircle(const X, Y: Integer;

out Index: Integer): Boolean;

begin

if Self.ThePointBelongsForCircle(x,y,Index) then Result:=true

else Result:=false;

end;

function TShapes.ThePointSelectsPiece(const X, Y, WidthOfPiece: Integer;

137

out Index: Integer): Boolean;

var i,j,hw: Integer;

tmp: Real;

CurPoint: TPoint;

begin

if Self.ThePointBelongsForPiece(x,y,j) then

begin

Index:=j;

Result:=true;

exit;

end;

tmp:=WidthOfPiece/2;

hw:=Round(tmp);

for i:=1 to hw do

begin

CurPoint.X:=X-i;

if Self.ThePointBelongsForPiece(CurPoint.X,Y,j) then

begin

Index:=j;

Result:=true;

exit;

end;

end;

for i:=1 to hw do

begin

CurPoint.X:=X+i;

if Self.ThePointBelongsForPiece(CurPoint.X,Y,j) then

begin

Index:=j;

Result:=true;

exit;

end;

end;

for i:=1 to hw do

begin

CurPoint.Y:=Y-i;

138

if Self.ThePointBelongsForPiece(X,CurPoint.Y,j) then

begin

Index:=j;

Result:=true;

exit;

end;

end;

for i:=1 to hw do

begin

CurPoint.Y:=Y+i;

if Self.ThePointBelongsForPiece(X,CurPoint.Y,j) then

begin

Index:=j;

Result:=true;

exit;

end;

end;

Index:=-1;

Result:=false;

end;

function TShapes.ThePointSelectsTerminator(const x, y, SizeOfTer: Integer;

const TerType: TTerminatorType; out Index: Integer): Boolean;

var i,j,hs: Integer;

f: Real;

begin

if Self.ThePointBelongsForTerminator(x,y,TerType,Index) then

begin

Result:=true;

exit;

end

else

begin

f:=SizeOfTer/2;

hs:=Round(f);

for i:=0 to hs-1 do

139

begin

for j:=0 to hs-1 do

begin

if Self.ThePointBelongsForTerminator(X+i,y+j,TerType,Index) then

begin

Result:=true;

exit;

end;

end;

end;

for i:=0 to hs-1 do

begin

for j:=0 to hs-1 do

begin

if Self.ThePointBelongsForTerminator(X+i,y-j,TerType,Index) then

begin

Result:=true;

exit;

end;

end;

end;

for i:=0 to hs-1 do

begin

for j:=0 to hs-1 do

begin

if Self.ThePointBelongsForTerminator(X-i,y+j,TerType,Index) then

begin

Result:=true;

exit;

end;

end;

end;

for i:=0 to hs-1 do

begin

for j:=0 to hs-1 do

begin

140

if Self.ThePointBelongsForTerminator(X-i,y-j,TerType,Index) then

begin

Result:=true;

exit;

end;

end;

end;

end;

Index:=-1;

Result:=false;

end;

function TShapes.ThePointSelectsBrick(const X, Y, SizeOfBrick: Integer;

out Index: Integer): Boolean;

begin

if Self.ThePointSelectsTerminator(x,y,SizeOfBrick,ttBrick,Index) then

Result:=true

else Result:=false;

end;

function TShapes.ThePointSelectsTrafficLight(const X, Y,

SizeOfTrLight: Integer; out Index: Integer): Boolean;

begin

if

Self.ThePointSelectsTerminator(x,y,SizeOfTrLight,ttTrafficLight,Index) then

Result:=true

else Result:=false;

end;

function TShapes.ThePointSelectsUnDes(const X, Y, SizeOfUnDes: Integer;

out Index: Integer): Boolean;

begin

if Self.ThePointSelectsTerminator(x,y,SizeOfUnDes,ttUnDes,Index) then

Result:=true

else Result:=false;

end;

141

procedure TShapes.AddCheckPoint(const x, y: Integer);

begin

FCheckpoints.Add(IntToStr(x)+';'+IntToStr(y)+';');

DoChange;

end;

function TShapes.ThePointBelongsForCheckPoint(const X, Y: Integer;

out Index: Integer): Boolean;

begin

if Self.ThePointBelongsForTerminator(x,y,ttCheckPoint,Index) then

Result:=true

else Result:=false;

end;

function TShapes.ThePointSelectsCheckPoint(const X, Y,

SizeOfCheckPoint: Integer; out Index: Integer): Boolean;

begin

if

Self.ThePointSelectsTerminator(x,y,SizeOfCheckPoint,ttCheckPoint,Index) then

Result:=true

else Result:=false;

end;

function TShapes.GetNumberOfCheckPoints: Integer;

begin

Result:=FCheckPoints.Count;

end;

procedure TShapes.GetCheckPoint(const Index: Integer; out x, y: Integer);

begin

Self.GetTerminator(Index,ttCheckPoint,x,y);

end;

procedure TShapes.DeleteCheckPoint(const x, y: Integer);

begin

142

Self.DeleteTerminator(x,y,ttCheckPoint);

DoChange;

end;

procedure TShapes.DeleteCheckPoint(const Index: Integer);

begin

Self.DeleteTerminator(Index,ttCheckPoint);

DoChange;

end;

procedure TShapes.ClearCheckPoints;

begin

FCheckPoints.Clear;

DoChange;

end;

end.

143