2012-04-23 6 views
0

я понял алгоритм сжатия, предположим, что я EXEC его, называя:Найти правильный параметр с помощью грубой силы алгоритм

myCompression(data, th) 

й параметр вещественное число между 0 и 1. Иногда это может быть действительно маленьким числом, например 212.19e-013.

num = length(myCompression(data, th)) 

дал мне количество данных, оставшихся после сжатия. Если я хочу num быть больше, мне нужно выбрать более низкий th параметр. Viceversa, если я хочу более высокий num, я должен выбрать ниже th.

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

target = 304; 
th = 2.49e-011; 
num = 0; 

while(num~=target)  
    num = length(MCSimplify3(time, latitudes, longitudes, th)); 
    disp(horzcat('tol: ', num2str(th), ' num: ', num2str(num))); 

    if (num>target) 
     th = th+(rand()*th); 
    else 
     th = th-(rand()*th); 
    end 

    th = abs(th); 
end 

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

tol: 2.67e-012 num: 333 
tol: 4.0685e-012 num: 303 
tol: 2.9909e-012 num: 320 
tol: 3.1953e-012 num: 316 
tol: 4.5895e-012 num: 298 
tol: 3.7916e-012 num: 308 
tol: 3.8906e-012 num: 308 
tol: 7.6049e-012 num: 257 
tol: 4.3302e-012 num: 299 
tol: 1.6646e-013 num: 624 
tol: 2.9337e-013 num: 562 
tol: 2.9553e-013 num: 561 
tol: 4.965e-013 num: 503 
tol: 8.47e-013 num: 448 
tol: 1.3934e-012 num: 391 
tol: 2.163e-012 num: 350 
tol: 2.6348e-012 num: 335 
tol: 4.6699e-012 num: 296 

Может кто-нибудь мне помочь?

ответ

1

Сначала нарисуйте график данных, которые вы нам показали. Это должно дать вам четкое представление о том, где направить поиск по значению th, который дает вам целевое значение, которое вы ищете.

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

Просто взглянув на ваши данные, предположим, что для целевого значения 304 значение для th должно лежать в диапазоне (3.7916e-012,4.0685e-012).

+0

Да, это именно то, что я хотел бы, грубо заставляя сокращать интервал толерантности. Но, очевидно, что-то пошло не так. –

+0

@Mariano: из вашего кода не видно, что это именно то, что вы делаете. Я не понимаю использование «rand» (которое я принимаю как генератор случайных чисел). Я также не понимаю ваше постоянное использование «грубой силы». –

+0

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

1

Есть более чем один способ кожи вашей кошки, и первое, что вам нужно сделать, удалить rand, так как это очень непредсказуемый параметр. При этом я отсылаю вас к Nelder-Mead.

С более практичной точки зрения, вы должны заменить rand() на константу (например, 0,1) или переменную, которая измеряет расстояние между num и target, умноженное на изменяющийся параметр.

В качестве альтернативы вы можете использовать процедуры минимизации, такие как fminsearch (который использует Nelder-Mead) с возможными небольшими изменениями для разрывов.

Трудно дать больше информации, не имея возможности запускать код (т. Е. Мне нужен MCSimplify3).

0

С драгоценными кончиками высокоэффективной марки, как я решил.

target = 304; 
len = 0; 

a = 0; 
b = 1; 

while(len~=target) 
    c = (a+b)/2; 
    len = length(MCSimplify3(time, latitudes, longitudes, c)); 
    if(len<target) 
     b = c; 
    end 
    if (len>target) 
     a = c; 
    end 
    if (len==target) 
     disp(horzcat('tol: ', num2str(th), ' num: ', num2str(len))); 
    end 
end