Б. Страуструп - Язык программирования С++. Специальное издание, 3-изд. Бином. 2004 (1160791), страница 169
Текст из файла (страница 169)
Зто позволяет результату быть той же последовательностью, что и входная; ас1/асеп1 йЯегепсе () ведет себя аналогично. Так раг!!а1 вит (ибеугп (), оепИ (), обеуГп ()), превратит последовательность а, Ь, с, с( в а, а+Ь, а+Ь+с, а+Ь+с+с1и т. д., а ай/асеп! сНХХегепсе (ибера (), о.епИ(), о.беу1п ()); превратит ее в изначальную. В частности, раг11а1 зит () снова превратит17, 2, 1, О, — 3 в 17,19,20,20,17. Эти операции полезны для анализа последовательности изменений. Например, анализ изменений цен на акции включает в себя две такие операции.
22.7. Случайные числа Случайные числа очень важны во многих видах моделирования и в играх. В <сз!с(1!Ь> и <зЫЙЬ.Ь> стандартная библиотека предоставляет простые необходимые средства для генерирования случайных чисел: ис1е~шейА14Р МАХ)тр(етепза!1оп йеЯпед /* больиьое положительное целое'/ 1п! гатl (), // псевдослучайные числа от О доЯА!>О МАХ оои1вгапд (ипз!дпедгпг!); // инициализирует генератор случайных чисел числол~ ! Создать хороший генератор псевдослучайных чисел не так легко, и, к сожалению, не все системы снабжены хорошим галЫ (). В частности, младшие биты в случайном числе часто вызывают подозрение, поэтому галс/ ()%п — нельзя назвать хорошим переносимым способом генерирования случайных чисел от 0 до и-1. Часто приемлемый результат получается в результате (ИоиЬ1е (галс! ())/ЯАЬ/Р МА1х) *и.
Однако для серьезного использования этой формулы мы должны позаботиться о малой вероятности того, что результат может быть и. Вызов згапс1 () начинает новую последовательность случайных чисел с семени (веем), заданного в качестве аргумента. Для отлалки часто важно, чтобы псевдослучайная последовательность отданного семени повторялась. Однако часто нам нужно Глава 22. Численные методы 754 начинать каждое новое реальное выполнение программы с новым семенем. Чтобы сделать игру фактически непредсказуемой, часто полезно выбирать семя из окружения программы.
Для таких программ хорошее семя получается из битов счетчика реального времени. Если вы должны написать собственный генератор случайных чисел, обязательно тщательно его проверьте Я 22.9Щ). Генератор случайных чисел часто оказывается удобнее, если его представить как класс. В этом случае генераторы случайных чисел с разными видами распределений ле~ко строятся следующим способом: с!аяяйалдгл1( //равномерное распределение, предполагает 32-битный тип 1опВ ипя!днес! !опл гапках; риЫк: йапс11л1 (!опа я = О) ( галс(х = я; ) оо(с! все<1 (!опия) ( галдя = я; ) // проведенные ниже магические числа нулсны //для вьи1еления 31 бита ия 32-битного числа типа 1опцг !опа аья (!она х) ( ге!игл х3 Ох 7~ЩЩ ) я1а1!с доиЫе глах () (1 с!игл 2147483648 0;) //внимание.
'доиЫе !опл с(гав () ( ге1игп гапдх =гапдх*1103515245+ 12345; ) доиЫеЯгав () ( ге1игл аЬя (с1гав ())/тая();) // интервал /О, 1/ !опя орега1ог () () ( ге!игл адя (дгав); ) О интервал /О, ров!2,31) ! с!аяя !!галс!: риЫ(с йапд(п1 ( //равномерное распределение в интервале(О:и( 1п1п; риЫк 1ггапд(т1пп)(а= па;) (л1 орега 1ог () () ( 1пгг = и 7с!гав (); ге!игл (г == л) г л — 1 г ) с!аяя Егапд . риЫкйапдгпс( // генератор с<0 чайн их чисел с якгпоненц ааль нылг распределением га1 теап; // среднее риЫк Егапд(ш1т) ( теап =-т;) ш1 орега1ог () () ( ге1игп — теап * !оц( (тах () — <!гав ())/тах ()+ .5; ) Вот простой тест: (п1та!п () ( Егапд с!гав (115; тар<т1 т1ь ЬисИе1; /ог (ш11=0, 1<1000000; 1++) Ьисдег(дгав Ячь; /ог (1п1/ =О;/<1О /ь+) сои!«Ьис!ье1(!)» "~п'; Если все значения Ьисне1 не равны приблизительно 100 000, где-то в программе ошибка. 755 22.9.
Упражнения Эти генераторы случайных чисел являются слегка подредактированными версиями того, что я поставлял вместе с самой первой библиотекой С++ (в действительности, с библиотекой чС с классами», 9 1А). 22.8. Советы [1] Численные проблемы часто очень тонки. Если ны не на 100% уверены в математическом аспекте задачи, воспользуйтесь сонетом специалиста или поэкспериментируйте; 9 22.1.
[2] Чтобы определить свойства нстроенных типов, пользуйтесь питег(с 11т11з; 9 22.2. [3] Для ска.чарных типов, определяемых пользователем, специализируйте питегпс 11т11з; 9 22.2, [4] Для математических вычислений, когда быстродействие вюкнее гибкости по отношению к операциям и типам элементов, пользуйтесь массивами па1аг ау; 9 22А. [5] Операции над частью массива выражайте при помощи срезон, а не циклов; й224. [6] Для достижения аффективности, чтобы избавиться от временных массивов и использовать лучшие алгоритмы, пользуйтесь композиторами; 9 22А.7, [7) Для арифметики с комплексными числами пользуйтесь з1с(ссотр1ех; 5 22.5.
[8] Старый код, использующий класс сотр1ех, при помощи 1уреде1'вы можете преобразовать лля работы с шаблоном зМ;:сотр1ех; 9 22.5. [9] Прежде чем писать цикл для вычисления значения по списку, рассмотрите применение алгоритмов ассити(а1е (), 1ппегргодис1 (), раг11а1 зит () и аг11асеп1 йДегепсе (); 9 22.6.
[10) Для конкретного вида распределения предпочитайте класс случайных чисел, а не пользуйтесь напрямую гат1 (); 9 22.7. [11] Убедитесь в том, что ваши случайные числа действительно случайны; 9 22.7. 22.9. Упражнения 1. ('1.5) Напишите функцию, которая вела бы себя как арр1у () из 9 22.4.3, за исключением того, что была бы функцией-не-членом н принимала бы в качестве аргументов объекты-функпии. 2. ("1.5) Напишите функцшо, которая вела бы себя как арр1у () из 9 22А.З, за исключением того, что была бы функцией-не-членом, принимала бы в качестве аргументов объекты-функции и изменяла свой аргумент па1 аггау. 3.
("2) Завершите бойсе 11ег (9 22А.5). Будьте особенно внимательны при определении деструктора. 4. ("1.5) Перепишите программу из 9 17.4.1.3, применив ассити1а1е (). 5. (*2) Реализуйте операторы ввода/вывода «и» лля па1 аг ау. Реализуйте функцию де1 аггау (), которая создавала бы массив на1 аггау с размером, который определялся бы при вводе. 6. (*2.5) Определите и реализуйте трехмерную матрицу с соответствующими операциями. 756 Глава 22. Численные методы 7.
(*2.5) Определите и реализуйте и-мерную матрицу с соответствующими операциями. 8. (*2.5) Реализуйте класс, подобный оа1аггау, п определите для него операторы ч- и *. Сравните их быстродействие с реализацией оа1аггау в вашей версии С++. Подсказка: Включите в проверку выражение х=0.5 '[х+у)-х и попробуйте его с разными размерами векторов х, д и г.
9. (*3) Реализуйте массив Гог1 аггад в стиле Рогггап; где индексы начинаются с1, а несу. 10. ('3) Реализуйте Ма1г1х, используя для представления элементов члены оа1аггау (а не указатель или ссылку на иа!аггау). 11. (*2.5) При помощи композиторов Я 22А.7) реализуйте эффективное многомерное индексирование с использованием обозначения П. Например, в1[х), о2[х1[у~, о2[х), пЗ[хЩ[г), пЗ[хЩ и оЗ[х) должны выдать соответствующие элементы и подмассивы при помощи простых вычислений с индексом.
12. ("2) Обобщите идею из программы в 3 22.7 в функцию, которая, получив в качестве аргумента генератор случайных чисел, вывела бы простое графическое пред ставление их распределения, что могло бы стать грубой наглядной проверкой правильности работы генератора. 13. ("1) Если и относится к типу ш1, каково распределение (доиЫе[гаиа1 Я/ 1(АЛ~0 МАа)*и? 14. ('2 5) Выведите на экран ттшки в квадратной области.
Пары координат для точек должны выдаваться генератором (7гаиг( [)ч), где л( — число пикселей вдоль соответствующей стороны области вывода. 15. ('2) Реализуйте генератор л1гаиИ, выдающий случайные числа с нормальным распределением. ®4АС ГЬ ®%ЕТВЕРТАЯ РОЕКТИРОВАНИŠ— С ИСПОЛЬЗОВАНИЕМ С++ Эта часть знакомит читателя с методами С++, облегчающими разработку программного обеспечения. Упор делается на проектирование и эффективную реализацию проекта в терминах конструкций языка.
ч... Тол ысо сейчас я начинаю открывать яля себя вс1о сложи ость выражения илсй иа бумаге. Пока речь илст искл|очитсльио об описании, рабоо ать иросго; ио ли~вь только в игру встуиаст рассуждеиио, как соблюдение Лоляаивк взаимоевязей, ясиости и отоосительиой логкости восприятия оказывается той упомяоутой вь о~с сложоостью, о которой я раньше и п<зиятия ис имел...ь — Чарльз Ларами 23. Разработка и проектирование .....
797 24. Проектирование и программирование 25. Роли классов .841 Разработка и проектирование Не свшесглвцегл серебряной пульс -- Ф. Брукс Построение программного продукта — цели и средства — процесс разработки — цикл разработки — этапы проектирования — выявление классов — определение операций — определение зависимостей определение интерфейсов -- реорганизация иерархии классов — модели— экспериментирование и анализ — тестирование -. сопровождение программного продукта — эффективность — руководство разработкой— повторное использование — масштаб — важность личностей — гибридное проектирование -- библиография — советы.