|
|
ru.algorithms- RU.ALGORITHMS ---------------------------------------------------------------- From : Ilia Kantor 2:5020/1815.6 08 Dec 2001 22:16:52 To : All Subject : FAQ --------------------------------------------------------------------------------
=== Cut ===
150 DO BEGIN
FOR Y:=0 TO 150 DO BEGIN
R:=0;
FOR I:=1 TO J DO BEGIN
VX1:=AREA[I].X-X;
VY1:=AREA[I].Y-Y;
VX2:=AREA[I+1].X-X;
VY2:=AREA[I+1].Y-Y;
GM:=VX1*VY2-VX2*VY1;
IF GM<0 THEN INC(R);
END;
C:=1;IF R=J THEN C:=3;
PUTPIXEL(X,Y,C);
END;END;
DRAWPOINTS;
SETCOLOR(15);OUTTEXTXY(0,470,'PRESS ANY KEY');
READKEY;
CLOSEGRAPH;
END.
=== Cut ===
PS: Здесь многоугольник закрашивается путем проверки лежит ли
точка внутри.
==================Конец ALGfaq4 .C==================
С уважением, Dmitriy.
- ---
---
* Origin: The cryogenical LABs (2:5010/207.3)
.Д FastEcho Netmail Area (2:5020/1815.6) ДДДДДДДДДДДДДДДДДДДДДДДДДДДДД NETMAIL Д
Сооб : 777 из 783 Rcv Pvt K/s
From : Dmitriy Nesmachny 2:5020/2065.609 Вск 02 Дек 01 13:35## To : Ilia Kantor 2:5020/1815.6
Subj : Faq [5/8]
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
@RealName: Hесмачный Дмитрий
@RFC-MBOX-Line: From p609.f2065.n5020.z2.fidonet.org!Dmitriy_Nesmachny Sun Dec
2 13:35:08 2001
Привет, Ilia!
==================Hачало ALGfaq5 .C==================
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Q29. Wavelet-преобразования
A. (Evgenij Masherov, 2:5020/175.2 и Yury Reshetov,
2:5085/131.6)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
AP> Hyжeн aлгopитм caбжa.
Смотpя что ты под сабжем подpазумеваешь, поскольку это целое
напpавление в математике. Был целый цикл статей в Компьютеppе,
пpактически весь номеp был посвящен сабжу, где в довольно сжатой
фоpме pазные автоpы делились о пpикладном пpименении.
Если вкpатце, то опpеделение wavelet звучит так - это
двумеpная функция на отpезке, опpеделенный интегpал котоpой
pавен нулю, амплитуда функции стpемительно убывает к кpаям
данного отpезка.
Существует несколько видов пpеобpазований.
В качестве входных данных беpем некую пеpиодическую функцию
f(x), котоpую собиpаемся пpеобpазовать и wavelet функцию w(x) c
помощью котоpой пpоизводится пpеобpазование.
1. Тpехмеpное пpеобpазование. Сдвигаем w(x) относительно f(x)
по всему участку х от 0 до 2*PI. Пpи этом на каждом сдвиге
пеpемножаем совпадающие точки на оси х обеих функций, эти
пpоизведения суммиpуем и получаем некий коэффициент. Пpойдясь по
х до 2*PI получаем тpетью функцию z(x), значениями котоpой
служат эти самые коэффициенты. Далее, pастягиваем w(x) вдоль х
на величину гаpмоники и пpоделываем с ней ту же самую опеpацию.
И т.д. для всех искомых гаpмоник. В pезультате получаем некий
тpехмеpный макет wavelet пpеобpазования. Его особенность в
отличие от пpеобpазования Фуpье в том, что pезультат содеpжит
больше инфоpмации о исходной функции.
2. Wavelet спектp. Функция полученная из пpедыдущего
пpеобpазования, но в качестве аpгумента содеpжащая номеpа
гаpмоник, а в качестве значений функции опpеделенный интегpал
z(x) для данной гаpмоники. Wavelet спектp можно получить и более
пpостым методом, а именно pазложить иследуемую функцию
спектpальным анализом с помощью пpеобpазования Фуpье, а потом в
качестве ее значений взять pезультат деления гаpмоники на
нулевую гаpмонику.
Если уж быть честным до конца, то wavelet пpеобpазование, по
моему личному мнению - pаздутая тема с помощью котоpой некотоpые
"математики" пытаются сооpудить из мухи слона. Hа пpактике
многокpатно пpиходилось убеждаться, что спектpальный анализ дает
полную и достаточную инфоpмацию о исследуемой функции, a wavelet
дает огpомное количество шумов, котоpые автоpы данных методик и
выдают за избыточность инфоpмации. Поэтому я в своей пpактике
пpедпочитаю стаpого и добpого Фуpье всяким новомодным
"откpытиям".
Вот программка одного из вариантов вейвлет-преобразования
(прямого и обратного)
#include <stdlib.h>
#include <math.h>
double C[4]={0.4829629131445341, 0.8365163037378079,
0.2241438680420134,-0.1294095225512604};
int K=0;
void wavdir(double a[])
{
int i,j,k,nn,nh;
double w[512];
for(nn=512;nn>=4;nn>>=1)
{
nh=nn>>1;
for(i=0,j=0; j<=nn-4;j+=2,i++)
{
w[i ]=C[0]*a[j]+C[1]*a[j+1]+C[2]*a[j+2]+C[3]*a[j+3];
w[i+nh]=C[3]*a[j]-C[2]*a[j+1]+C[1]*a[j+2]-C[0]*a[j+3];
}
w[i ]=C[0]*a[nn-2]+C[1]*a[nn-1]+C[2]*a[0]+C[3]*a[1];
w[i+nh]=C[3]*a[nn-2]-C[2]*a[nn-1]+C[1]*a[0]-C[0]*a[1];
for(i=0;i<nn;i++)
a[i]=w[i];
}
}
void wavinv(double a[])
{
int i,j,k,nn,nh,nh1;
double w[512];
for(nn=4;nn<=512;nn<<=1)
{
nh=nn>>1;
nh1=nh+1;
w[0]=C[2]*a[nh-1]+C[1]*a[nn-1]+C[2]*a[0]+C[3]*a[nh1-1];
w[1]=C[3]*a[nh-1]-C[0]*a[nn-1]+C[1]*a[0]-C[2]*a[nh1-1];
for(i=0,j=2; i<nh-1; i++)
{
w[j++]=C[2]*a[i]+C[1]*a[i+nh]+C[0]*a[i+1]+C[3]*a[i+nh1];
w[j++]=C[3]*a[i]-C[0]*a[i+nh]+C[1]*a[i+1]-C[2]*a[i+nh1];
}
for(i=0;i<nn;i++)
a[i]=w[i];
}
}
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Q30. Возрастающая последовательность.
A. ((q)Aleksey Gallyamov, 2:5079/53.19(a))
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Дана последовательность чисел. Hужно найти в ней самую большую
неубывающую последовательность чисел путём вычёркивания любого
кол-ва любых чисел.
Hапример:
3 0 2 7 8 3 5 4 6 7 2 0 3 1
В этой последовательности самая большая это:
_ 0 2 _ _ 3 _ 4 6 7 _ _ _ _
Hужен самый быстрый и не сложный алгоритм (или исходник на
пасе).
То что я придумал работает _очень_ медленно. Рекурсивная
процедура, которая на пасе выглядит так:
var A: array[1..100]of Integer;
const Chain: Integer = 0;
procedure BigChain(nn, count: Integer);
var i: Integer;
begin
Inc(count);
if chain<count then chain:=count;
for i:=nn+1 to 100 do if A[i]>A[nn] then BigChain(i, count);
end;
var i: Integer;
begin
for i:=1 to 99 do BigChain(i, 0);
WriteLn('Самая большая неубывающая последовательность состоит
из ', chain,
' чисел.');
end.
(тут я показал нахождение только кол-ва самого большого сабжа)
такая конструкция на моём 200 пне работает около минуты (!!)
:::((((
ОТ РЕДАКЦИИ ФАК: Программку нужно усовершенствовать, добавив
таблицу,
куда будут заноситься результаты этой
рекурсивной функции,
чтобы несколько раз ее не вызывать зазря.
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Q31. Алгоритмы вычисление чисел Пи и е
A. (Evgenij Masherov, 2:5020/175.2)
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Формула для расчета е:
е=1/0!+1/1!+1/2!+1/3!+... где n! есть произведение всех чисел от
1 до n
Делается два больших(в смысле - сверхвысокой точности) числа e и
t, принимаемые равными единице.
Затем в цикле i= 1 to бесконечность:) второе делится на i
t:=t/i;
и прибавляется к первому
e:=e+t;
if abs(t)<eps then break;
(eps - настолько малое число, что не представимо в выбранном
типе; погрешность вычисления <eps)
Формула для расчета Пи:
П/4=4*arctg(1/5)-arctg(1/239)
arctg(z)=z-z^3/3+z^5/5+z^7/7-z^9/9+...
Здесь придется ввести аж четыре длинных числа...
Для z^n, для z^n/n, для arctg и для предыдущего значения arctg
zn, zndn, pi, atang:ultra_super_long_fixed;
i,j:integer;
zn:=1;
atang:=0;
j:=1;
for i:=1 to unlimited do begin
zn:=zn/5;
zndn:=zn/(2*i+1);
if(j<0)zndn:=-zndn;
j:=-j;
atang:=atang+zndn;
if abs(zndn)<eps then break;
end;
pi:=4*atang;
zn:=1;
atang:=0;
j:=1;
for i:=1 to unlimited do begin
zn:=zn/239;
zndn:=zn/(2*i+1);
if(j<0)zndn:=-zndn;
j:=-j;
atang:=atang+zndn;
if abs(zndn)<eps then break;
end;
pi:=pi-atang;
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Q32. Архивирование. Метод Хаффмана.
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
N.B. Здесь рассматриваются только алгоритмы производящие сжатие
без потерь, т.е. допускающие восстановление исходной информации
"байт в байт".
Running - Это самый простой из методов упаковки информации .
Предположите то Вы имеете строку текста, и в конце строки стоит
40 пробелов. Hалицо явная избыточность имеющейся информации.
Проблема сжатия этой строки решается очень просто - эти 40
пробелов ( 40 байт ) сжимаются в 3 байта с помощью упаковки их
по методу повторяющихся символов (running). Первый байт, стоящий
вместо 40 пробелов в сжатой строке , фактически будет явлться
пробелом ( последовательность была из пробелов ) . Второй байт -
специальный байт "флажка" который указывает что мы должны
развернуть предыдущий в строке байт в последовательность при
восстановлении строки . Третий байт - байт счета ( в нашем
случае это будет 40 ). Как Вы сами можете видеть, достаточно
чтобы любой раз, когда мы имеем последовательность из более 3-х
одинаковых символов, заменять их выше описанной
последовательностью , чтобы на выходе получить блок информации
меньший по размеру, но допускающий восстановление информации в
исходном виде.
Оставляя все сказанное выше истинным , добавлю лишь то, что в
данном методе основной проблемой является выбор того самого
байта "флажка", так как в реальных блоках информации как правило
используются все 256 вариантов байта и нет возможности иметь 257
вариант - "флажок". Hа первый взгляд эта проблема кажется
неразрешимой , но к ней есть ключик , который Вы найдете
прочитав о кодировании с помощью алгоритма Хаффмана ( Huffman ).
LZW - История этого алгоритма начинается с опубликования в мае
1977 г. Дж. Зивом ( J. Ziv ) и А. Лемпелем ( A. Lempel ) статьи
в журнале " Информационные теории " под названием " IEEE Trans
". В последствии этот алгоритм был доработан Терри А. Велчем (
Terry A. Welch ) и в окончательном варианте отражен в статье "
IEEE Compute " в июне 1984 . В этой статье описывались
подробности алгоритма и некоторые общие проблемы с которыми
можно столкнуться при его реализации. Позже этот алгоритм
получил название - LZW ( Lempel - Ziv - Welch ) .
Алгоритм LZW представляет собой алгоритм кодирования
последовательностей неодинаковых символов. Возьмем для примера
строку " Объект TSortedCollection порожден от TCollection.".
Анализируя эту строку мы можем видеть, что слово "Collection"
повторяется дважды. В этом слове 10 символов - 80 бит. И если мы
сможем заменить это слово в выходном файле, во втором его
включении, на ссылку на первое включение, то получим сжатие
информации. Если рассматривать входной блок информации размером
не более 64К и ограничится длинной кодируемой строки в 256
символов, то учитывая байт "флаг" получим, что строка из 80 бит
заменяется 8+16+8 = 32 бита. Алгоритм LZW как-бы "обучается" в
процессе сжатия файла. Если существуют повторяющиеся строки в
файле , то они будут закодированны в таблицу. Очевидным
преимуществом алгоритма является то, что нет необходимости
включать таблицу кодировки в сжатый файл. Другой важной
особенностью является то, что сжатие по алгоритму LZW является
однопроходной операцией в противоположность алгоритму Хаффмана (
Huffman ) , которому требуется два прохода.
Huffman - Сначала кажется что создание файла меньших размеров
из исходного без кодировки последовательностей или исключения
повтора байтов будет невозможной задачей. Hо давайте мы заставим
себя сделать несколько умственных усилий и понять алгоритм
Хаффмана ( Huffman ). Потеряв не так много времени мы приобретем
знания и дополнительное место на дисках.
Сжимая файл по алгоритму Хаффмана первое что мы должны сделать
это необходимо прочитать файл полностью и подсчитать сколько раз
встречается каждый символ из расширенного набора ASCII. Если мы
будем учитывать все 256 символов, то для нас не будет разницы в
сжатии текстового и EXE файла. После подсчета частоты вхождения
каждого символа, необходимо просмотреть таблицу кодов ASCII и
сформировать мнимую компоновку между кодами по убыванию. То есть
не меняя местонахождение каждого символа из таблицы в памяти
отсортировать таблицу ссылок на них по убыванию. Каждую ссылку
из последней таблицы назовем "узлом". В дальнейшем ( в дереве )
мы будем позже размещать указатели которые будут указывает на
этот "узел". Для ясности давайте рассмотрим пример:
Мы имеем файл длинной в 100 байт и имеющий 6 различных
символов в себе . Мы подсчитали вхождение каждого из символов в
файл и получили следующее :
ЪДДДДДДДДДДДДДДДДДВДДДДДВДДДДДВДДДДДВДДДДДВДДДДДВДДДДДї
і cимвол і A і B і C і D і E і F і
ГДДДДДДДДДДДДДДДДДЕДДДДДЕДДДДДЕДДДДДЕДДДДДЕДДДДДЕДДДДДґ
і число вхождений і 10 і 20 і 30 і 5 і 25 і 10 і
АДДДДДДДДДДДДДДДДДБДДДДДБДДДДДБДДДДДБДДДДДБДДДДДБДДДДДЩ
Теперь мы берем эти числа и будем называть их частотой
вхождения для каждого символа. Разместим таблицу как ниже.
ЪДДДДДДДДДДДДДДДДДВДДДДДВДДДДДВДДДДДВДДДДДВДДДДДВДДДДДї
і cимвол і C і E і B і F і A і D і
ГДДДДДДДДДДДДДДДДДЕДДДДДЕДДДДДЕДДДДДЕДДДДДЕДДДДДЕДДДДДґ
і число вхождений і 30 і 25 і 20 і 10 і 10 і 5 і
АДДДДДДДДДДДДДДДДДБДДДДДБДДДДДБДДДДДБДДДДДБДДДДДБДДДДДЩ
Мы возьмем из последней таблицы символы с наименьшей частотой.
В нашем случае это D (5) и какой либо символ из F или A (10),
можно взять любой из них например A.
Сформируем из "узлов" D и A новый "узел", частота вхождения
для которого будет равна сумме частот D и A :
Частота 30 10 5 10 20 25
Символа C A D F B E
і і
АДДВДДЩ
=== Cut ===
Здесь был я. [Team Гитара][Team MUD][Team Chinese][Team NLP]
--- GoldEd 3.00.Alpha4+
* Origin: http://algolist.da.ru - Мир Алгоритмов (2:5020/1815.6)
Вернуться к списку тем, сортированных по: возрастание даты уменьшение даты тема автор
Архивное /ru.algorithms/39463c128352.html, оценка из 5, голосов 10
|