Задача оптимальной упаковки; комбинированный алгоритм; волновой алгоритм; ресурсная эффективность




Скачать 210.16 Kb.
НазваниеЗадача оптимальной упаковки; комбинированный алгоритм; волновой алгоритм; ресурсная эффективность
Дата17.02.2013
Размер210.16 Kb.
ТипЗадача


УДК 004.021, код ВАК 05.13.11

КОМБИНИРОВАННЫЙ И ВОЛНОВОЙ АЛГОРИТМЫ РЕШЕНИЯ ЗАДАЧИ УПАКОВКИ: ПРИНЦИПЫ ПОСТРОЕНИЯ И ОСОБЕННОСТИ

Ульянов Михаил Васильевич,

Московский государственный университет печати (МГУП), Россия, Москва, профессор кафедры «Прикладная математика и моделирование систем», профессор, д-р техн. наук.

muljanov@mail.ru

Наумова Ольга Анатольевна,

Московский государственный университет приборостроения и информатики (МГУПИ), Россия, Москва, студентка кафедры «Персональная электроника».

helga_13_07@mail.ru

Корреспондентский адрес: 127550 Москва, ул. Прянишникова, 2а, кафедра «Прикладная математика и моделирование систем», Ульянов М.В. 8-916-589-94-04.

Аннотация

В статье рассмотрены базовые алгоритмы точного решения задачи одномерной оптимальной по стоимости упаковки: рекурсивный и табличный. На основе их рационального совмещения предлагаются комбинированный и волновой алгоритмы, обладающие лучшими ресурсными характеристиками. Указаны особенности их применения и различия в ресурсных требованиях.

Ключевые слова: Задача оптимальной упаковки; комбинированный алгоритм; волновой алгоритм; ресурсная эффективность.

1. Введение

Начиная с конца 50-х годов XX века, когда Р. Беллман предложил и обосновал идеи метода динамического программирования, задача оптимальной по стоимости одномерной упаковки привлекает внимание программистов и ученых, занимающихся разработкой и анализом алгоритмов. Именно этой задачей открывается ряд иллюстративных примеров в классической книге Р. Беллмана и Р. Дрейфуса «Прикладные задачи динамического программирования» [1]. Повышенный интерес к этой задаче, равно как и к ее многочисленным модификациям, связан как с разнообразными практическими областями применения, так и с отсутствием «быстрых» алгоритмов её решения. Постановки, сводимые к задаче оптимальной упаковки, возникают при решении целого ряда экономических задач, задач планирования бизнеса и логистики. Мощности современных компьютеров позволяют в настоящее время получать точное решение этой задачи в практически значимом сегменте длин входов, однако требование повышения временной эффективности её решения в настоящее время остаётся актуальным.

Точный классический алгоритм Беллмана для задачи одномерной упаковки может быть реализован двумя принципиально разными алгоритмами:

  • табличным алгоритмом, опирающимся на вычисление и хранение векторов оптимальной упаковки для всех последовательных целочисленных значений объема;

  • рекурсивным алгоритмом, непосредственно реализующим основное функциональное уравнение Белламна.

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

2. Математическая постановка задачи одномерной упаковки

Постановка задачи: пусть задано множество

,

где каждый элемент обладает целочисленным линейным размером — , или «объемом» в общепринятых терминах задачи упаковки, и ценовой характеристикой — , которая содержательно отражает практически значимые предпочтения для загрузки объектов данного типа. Так же целочисленным значением задан основной объем упаковки . В классической постановке элементы называются типами грузов. Для описания количества загружаемых в объем элементов введем в рассмотрение характеристический вектор: , где — неотрицательное целое. Значение компонента вектора соответствует загрузке элементов типа в объем . Таким образом, описание некоторой упаковки грузов представляет собой точку в -мерном целочисленном пространстве . Среди всех возможных упаковок объема грузами из должна существовать по крайней мере одна упаковка, максимизирующая суммарную стоимость, что приводит к постановке задачи как задачи максимизации линейного функционала [1]:

, при . (1)

Содержательно ограничение в (1) означает, что суммарный объем, занимаемый грузами всех типов в количествах, указанных компонентами характеристического вектора , не должен превышать общего объема упаковки. Поскольку и целевая функция и ограничение линейны, а значения — неотрицательные целые числа, то задача (1) является задачей линейного целочисленного программирования.

Оценку вычислительной сложности решения данной задачи методом полного перебора можно получить, если рассматривать прямоугольный параллелепипед в пространстве , размеры сторон которого определяются типами грузов. Это приводит к верхней оценке количества точек перебора в виде [2]

.

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

Отметим, в этой связи, что рассматриваемая задача является - трудной [1], и для нее в общем виде отсутствуют сегодня полиномиальные по точные алгоритмы решения. Это приводит к необходимости использования более эффективных точных методов решения задачи одномерной оптимальной упаковки, существенно сокращающих полный перебор, одним из которых является метод динамического программирования.

3. Функциональное уравнение Беллмана

Опираясь на терминологию метода динамического программирования, будем считать, что в рассматриваемой задаче распределяемым ресурсом является объем упаковки , а максимизизация дохода, заданного линейным функционалом производится путем распределения ограниченного ресурса между грузами указанных типов. Поскольку целевой функционал обладает свойством аддитивности, то метод динамического программирования применим, и основное функциональное уравнение Беллмана имеет вид [1]

(2)

Таким образом, метод предусматривает последовательное решение одномерных задач целочисленной оптимизации с использованием информации об оптимальной упаковке объема предыдущими типами грузов. Решением поставленной задачи является значение и соответствующий вектор оптимальной упаковки. Поскольку значения могут быть элементарно вычислены на основе (2), то в дальнейшем будет рассматриваться следующее основное функциональное уравнение для задачи одномерной оптимальной упаковки, записанное в виде рекуррентного соотношения, определяющего рекурсивно заданную функцию [2]

(3)

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

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

Рассмотрим пример решения задачи одномерной упаковки с использованием данного алгоритма — нас интересует порожденное дерево рекурсии. Пусть необходимо решить задачу для трех типов грузов при общем объеме упаковки . Информация об объемах и стоимостях для типов грузов приведена в таблице 1.

Таблица 1. Описание типов грузов







1

2

3

2

3

5

3

4

7


Решением поставленной задачи будет значение функции Беллмана , при этом алгоритм порождает дерево рекурсии, показанное на рисунке 1.



Рис. 1. Дерево рекурсии, порождаемое рекурсивным алгоритмом упаковки.


Характерным недостатком данного алгоритма является повторное вычисление значений функции в различных фрагментах дерева рекурсии. При этом чем дерево шире, а глубина рекурсии больше, тем выше вероятность повторных вычислений. В общем случае трудоёмкость этого алгоритма асимптотически определяется биномиальными коэффициентами при специальной параметризации [1], что приводит ряда входов к значительному времени получения решения.

5. Табличный алгоритм решения задачи упаковки

Рассмотрим другой алгоритм точного решения этой задачи методом динамического программирования — табличный алгоритм A2, позволяющий получить оптимальное решение не только для заданного объема , но и набор оптимальных решений для всех промежуточных дискретных значений этого объема. Обозначим вектор оптимальной упаковки для объема элементами , через , а через стоимость оптимальной упаковки в этом объеме. В силу принципа оптимальности [1]


,

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

Пример формирования таблицы оптимальной упаковки для исходных данных, приведённых в табл. 1, представлен в табл. 2.

Таблица 2. Таблица оптимальной упаковки.































1

0

0




1

0

0

0




1

0

0

0

0

2

1

3




2

1

0

3




2

1

0

0

3

3

1

3




3

0

1

5




3

0

1

0

5

4

2

6




4

2

0

6




4

0

0

1

7

5

2

6



5

1

1

8



5

1

1

0

8

6

3

9




6

0

2

10




6

0

2

0

10

7

3

9




7

2

1

11




7

0

1

1

12

8

4

12




8

1

2

13




8

0

0

2

14

9

4

12




9

0

3

15




9

0

3

0

15

10

5

15




10

2

2

16




10

0

2

1

17


Очевидным недостатком данного алгоритма являются «пустые» вычисления в тех строках таблицы, которые не будут задействованы в будущем. Таким образом, алгоритм выполняет лишние вычисления, объем которых может быть значительным. Явная зависимость трудоёмкости данного алгоритма от объёма упаковки приводит к тому, что для больших значений объём лишних вычислений возрастает.

6. Комбинированный алгоритм

Совместное рассмотрение недостатков рекурсивного и табличного алгоритмов позволяет сделать вывод о том, что в крайних случаях, например при значительном объёме упаковки и больших значениях объёмов грузов рекурсия будет существенно эффективнее табличных расчетов, а при малых объёмах грузов мы будем наблюдать противоположную ситуации. Таким образом, мы можем говорить, что эти два классических алгоритма являются в определённом смысле комплементарными — они дополняют друг друга, обладая противоположным поведением функции трудоёмкости [3]. Эта особенность позволяет создать комбинированный алгоритм, использующий табличный расчет и рекурсию в их рациональных диапазонах.

Комбинированное алгоритмическое решение состоит в выборе одного из двух алгоритмов, что может быть реализовано при заданных значениях , на основе сравнения их трудоемкостей [3]. При определенных условиях, зависящих от исходных данных, более рациональным является построение комбинированного алгоритма, основной идеей которого является предвычисление оптимальных упаковок для некоторого числа типов грузов табличным алгоритмом и дальнейшее решение задачи рекурсивным алгоритмом с сокращенным числом типов грузов. Каков оптимальный по трудоемкости порог, т. е. оптимальное число типов грузов обрабатываемых табличным алгоритмом? Ответ на этот вопрос можно получить на основе следующих рассуждений.

Предположим, что табличным алгоритмом находится оптимальное решение для упаковки первыми (в порядке предъявления) типами грузов, причем , при этом для остальных типов задача решается рекурсивным алгоритмом. В листьях порожденного дерева рекурсии на уровне происходит копирование вектора оптимальной упаковки, полученного табличным алгоритмом. Это приводит к необходимости модификации рекурсивного алгоритма. Этот модифицированный алгоритм, обозначим его через A1M, отличается от алгоритма A1 фрагментом останова рекурсии, в котором происходит копирование строки результатов табличного алгоритма.

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

.

Тогда оптимальное значение может быть найдено как

. (4)

Отметим, что значение . Поскольку значение является целым числом, то может быть найдено простым перебором значений функции при . Тогда трудоемкость комбинированного алгоритма, назовём его AC, составит

.

В общем случае возникает задача построения комбинированного алгоритмического решения — рационального выбора одного из трех алгоритмов на основе анализа текущего входа. Мы сравниваем между собой рекурсивный, табличный и комбинированный алгоритмы — A1, A2, AC. Критерием выбора является минимум значения функций трудоёмкости. Понимая под аргументом оптимизации индекс алгоритма, и фиксируя значения , определённые текущим входом, можно записать

, (5)

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

1. Случай 1 — . В этом случае рекурсивный алгоритм A1 обеспечивает минимальную трудоемкость и комбинации с табличным алгоритмом не требуется.

2. Случай 2 — В этом случае табличный алгоритм A2 имеет минимальную трудоемкость для данного входа и комбинации с рекурсивным алгоритмом не требуется.

3. Случай 3 — , . В этом случае рациональным является применение комбинированного алгоритма AC с порогом переключения равным . При этом на первом этапе табличный алгоритм получает таблицу оптимальной упаковки заданного объёма грузами типов , а рекурсивный алгоритм на втором этапе, порождает дерево рекурсии от груза с номером до груза с номером , останавливает рекурсию на уровне , копирует результаты табличного алгоритма в свою структуру данных, и цепочкой рекурсивных возвратов получает вектор оптимальной упаковки и значение целевого функционала для исходной задачи.

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

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

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

7. Волновой алгоритм

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

Так как табличный алгоритм на каждом шаге вычисляет оптимальную упаковку для всех дискретных значений объема от 0 до , то его разумно использовать, когда следующий шаг рекурсии будет порождать значительное число листьев с различными значениями объема упаковки. К тому же эффективность рекурсии при обработке каждого последующего груза в общем случае падает, т. к. возрастает число вершин, имеющих одинаковый аргумент целевой функции. Исходя из этого, на первом этапе волнового алгоритма управление передается рекурсии. Но в отличие от комбинированного и рекурсивного алгоритма в чистом виде, здесь используется иная структура данных. Мы «разворачиваем» рекурсию в таблицу хранения рекурсивных обращений. Что это означает? Порождение очередной вершины дерева рекурсии обрабатывается как создание строки таблицы с номером, соответствующим значению оставшегося объема упаковки, и записью дополнительной информации, позволяющей организовать быстрые вычисления на последнем этапе волны обратных расчётов, эквивалентном цепочке рекурсивных возвратов. Для следующего типа груза создаётся новая таблица, при этом рекурсивные вызовы, порождающие цепочку таблиц, будут продолжаться до передачи управления табличному алгоритму. Порог переключения между алгоритмами определяется динамически, исходя из условия рационального продолжения развёртывания рекурсии. После обработки очередного уровня рекурсии, т. е. создания таблицы для соответствующего типа груза, подсчитывается число заполненных строк текущей структуры данных — таблицы хранения рекурсивных обращений. Если число обращений достигло значения , то, мы предполагаем, что на следующем шаге число рекурсивных вызовов будет больше, чем число строк таблицы, и, следовательно, управление передается табличному алгоритму. Структура данных табличного алгоритма идентична структуре таблиц таблицы хранения рекурсивных обращений, что позволяет при обратном ходе волны непосредственно копировать результаты табличного алгоритма в соответствующую структуру. Схема волнового алгоритма показана на рисунке 2.



Динамическая граница переключения

Волна обратных расчетов в цепочке таблиц

Волна порождения цепочки таблиц, эквивалентных рекурсии

Расчет табличным алгоритмом до границы


Рис. 2. Схема волнового алгоритма упаковки


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

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

— после обработки груза с номером заполненными оказываются более половины строк таблицы хранения рекурсивных обращений, и управление передается табличному алгоритму;

— число заполненных строк не достигает значения даже при рассмотрении предпоследнего груза. В этом случае табличный алгоритм не участвует в поиске решения.

8. Сравнение комбинированного и волнового алгоритмов

Рациональное совмещение рекурсивного и табличного алгоритмов решения задачи одномерной упаковки — общий принцип построения волнового и комбинированного алгоритмов. Этот принцип во многом обусловливает и схожесть структур этих алгоритмов. Так какой же из методов предпочтительнее использовать для получения быстрого решения? Ответ на этот вопрос не является вполне очевидным и зависит от аппаратных возможностей.

Если определяющим фактором является время получения точного решения, то выбор за волновым алгоритмом. Он обеспечивает более быстрое решение за счет:

— отсутствия модуля предвычисления порога переключения;

— отсутствия повторных рассчетов целевой функции с одинаковым аргументом для вершин дерева рекурсии разных уровней;

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

Но, как известно, за все приходится платить. В случае волнового алгоритма расплачиваться за временную эффективность приходится дополнительными затратами оперативной памяти на хранение полных ссылок рекурсивных вызовов. Волновой алгоритм демонстрирует классическую дилемму ресурсной эффективности — улучшение временной эффективности за счёт ухудшения ёмкостных характеристик.

9. Заключение

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

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

Волновой алгоритм не выполняет статического расчета порога переключения. Порог в данном алгоритме определяется динамически на основе подсчёта числа заполненных строк специальной таблицы хранения рекурсивных обращений. За счёт дополнительных затрат оперативной памяти предлагаемый волновой алгоритм имеет лучшую временную эффективность.

Предложенные алгоритмы могут быть использованы при решении практических постановок задач бизнес-информатики, сводимых к задаче оптимальной одномерной упаковки.

Список литературы

1. Беллман Р., Дрейфус Р. Прикладные задачи динамического программирования: Пер. с англ. — М.: Наука, 1965, — 457 с.

2. Головешкин В. А., Ульянов М. В. Теория рекурсии для программистов. — М.: Издательство «Наука ФИЗМАТЛИТ», 2006. — 296 с.

3. Ульянов М. В., Гурин Ф. Е., Исаков А. C., Бударагин В. Е. Сравнительный анализ табличного и рекурсивного алгоритмов точного решения задачи одномерной упаковки // Exponenta Pro Математика в приложениях. 2004. №2(6). С. 64–70.

COMBINED AND WAVE SOLUTION ALGORITHMS FOR THE PROBLEM OF THE PACKING: THE PRINCIPLES OF CONSTRUCTION AND SPECIAL FEATURE

Uljyanov Mikhail Vasiljevich,

The Moscow State University of Print (MGUP), Russia, Moscow.

Naumova Olga Anatoljevna

The Moscow State University of Instrumental Engineering and Computer Sciences (MGUPI), Russia, Moscow.

Annotation

The article is viewing basic exact solution algorithms for the problem of one-dimensional optimum for the cost packing - recursive and table algorithms. Combined and wave algorithms are suggested since rational combination of basic algorithms allows them to have better resource characteristics. Differences in use and in the resource requirements of suggested algorithms are indicated.

Key words: Problem of optimum packing; combined algorithm; wave algorithm; resource effectiveness.



Похожие:

Задача оптимальной упаковки; комбинированный алгоритм; волновой алгоритм; ресурсная эффективность iconТическое планирование предмета по выбору «Информатика и икт»
Основные понятия: алгоритм, исполнитель, система команд исполнителя алгоритмического языка, блок-схема, линейный, разветвляющийся,...
Задача оптимальной упаковки; комбинированный алгоритм; волновой алгоритм; ресурсная эффективность iconАлгоритм экcмо Москва, 2005 удк 94(47)
У 84 Месть за победу — новая война. — М.: Изд-во Алгоритм, Изд-во Эксмо, 2005. — 544 с
Задача оптимальной упаковки; комбинированный алгоритм; волновой алгоритм; ресурсная эффективность iconАлгоритм написания эссе по обществознанию
В рамках ответа необходимо привести аргументацию своей позиции. Предлагаем к рассмотрению основные требования к эссе и приблизительный...
Задача оптимальной упаковки; комбинированный алгоритм; волновой алгоритм; ресурсная эффективность iconАлгоритм москва 2005 удк 94(47)
П 48 Покушение на Великую Победу. — М.: Изд-во Алгоритм, Изд-во Эксмо, 2005. 384 с
Задача оптимальной упаковки; комбинированный алгоритм; волновой алгоритм; ресурсная эффективность iconГалины Ягенской «Подготовка школьных команд к Турниру юных биологов»
В процессе многолетней работы у нас произвелся определенный алгоритм подготовки к турниру (на рис. 1 представлен алгоритм работы...
Задача оптимальной упаковки; комбинированный алгоритм; волновой алгоритм; ресурсная эффективность iconАннотация Слово «алгоритм»
Слово «алгоритм» не случайно введено в название книги: мне представляется, что есть возможность «разложить по полочкам» самые сложные...
Задача оптимальной упаковки; комбинированный алгоритм; волновой алгоритм; ресурсная эффективность iconПрограмма на алгоритмическом языке совокупность описаний и действий, представляющая единый алгоритм. Программирование Процесс решения задачи «алгоритм»
Язык. Основной элемент абстрактного языка – алфавит – конечное множество символов (неделимых знаков). Конечная последовательность...
Задача оптимальной упаковки; комбинированный алгоритм; волновой алгоритм; ресурсная эффективность iconБанк данных Внутренние болезни и впт алгоритм лечения острой
Алгоритм лечения острой пневмонии [Текст] : метод рекоменд для студ., интернов и врачей / Гродн гос мед ун-т; Сост. В. М. Борец,...
Задача оптимальной упаковки; комбинированный алгоритм; волновой алгоритм; ресурсная эффективность icon1. Задача состоит из 3-ёх частей
Алгоритм решения задач по химическому уравнению, если один из реагентов взят в избытке
Задача оптимальной упаковки; комбинированный алгоритм; волновой алгоритм; ресурсная эффективность iconАлгоритм москва, 2004
У 84 Унижение России: Брест, Версаль, Мюнхен. — М.: Изд-во Эксмо, Изд-во Алгоритм, 2004. — 624 с. — (История России. Современный...
Разместите кнопку на своём сайте:
Библиотека


База данных защищена авторским правом ©lib.znate.ru 2014
обратиться к администрации
Библиотека
Главная страница