2014-05-30 4 views
2

Интересно, существуют ли установленные шаблоны для этих или даже функций, доступных в основных или сторонних библиотеках, которые поддерживают это?шаблоны для последовательности «обратная инженерия»

Я написал сложную последовательность, используя выражение seq, которое принимает время начала и список правил, диктующих, когда определенным событиям разрешено возникать в строке времени, идущей вперед, чтобы создать бесконечную последовательность. Легко поставить любое начальное значение DateTime и просто начать шаг вперед. Результирующая последовательность представляет собой следующий этап: <DateTime>, соответствующий событиям, отмеченным по времени.

Что бы я хотел сделать, так это быть в состоянии вернуться на эту теоретическую шкалу событий. Я хочу сказать: «Вернитесь на десять шагов и дайте мне эту DateTime», чтобы я знал, должен ли я применить результат к исходной последовательности в качестве ввода, я бы вернулся туда, где я начал.

Должен ли я просто изменить сложную логику, чтобы сделать эту работу? Или был бы способ, которым я могу эффективно «переборщить» свою форвардную логику, чтобы я мог продолжать подавать входные данные, пока не получаю результат, который правильно дает мне 10 шагов до указанного DateTime?

Я понимаю, что я плохо разбираюсь в этом, поэтому, возможно, упрощенный пример, чтобы помочь визуализировать то, что мне нужно. Предположим, что я создал последовательность ints с использованием некоторого логического шаблона. Давайте просто скажем, кратные 2, чтобы держать это просто:

let seq = [ 2; 4; 6; 8; 10; 12; 14; 16; 18; 20; ] 

(Это лениво сгенерированную последовательность, используя мой предопределенный логику, хотя)

Я могу начать генерировать эту последовательность из любого из значений внутри нее легко, так учитывая 12 я могу продолжать идти вперед

let seqFrom12 = [ 12; 14; 16; 18; 20; ] 

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

Так что я хочу, чтобы все значения последовательности, так что X = еще 3 шага приведет меня к значению 12 в последовательности. Поэтому мне нужно будет пересчитать до 10, затем 8, затем 6. Только в реальном сценарии гораздо сложнее применить обратную логику

+0

Похоже, вы хотите реализовать функциональность отмены. Является ли это более-менее правильным? – mydogisbox

+0

@mydogisbox Я это другой способ визуализации его наверняка –

ответ

8

Это не вопрос для SO. Даже для сообщения в блоге, но реалистично, для интересной научной статьи. Но одна важная часть информации отсутствует - вы сами пишете выражения последовательности, или вы просто получаете последовательность дат (не зная, как она была создана)?

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

В первом случае вы можете что-то сделать, переместившись от seq<'T> и вместо этого используя свой собственный тип данных, который поддерживает перемещение вперед и назад. Например, что-то вроде этого:

type BiSeq<'T> = 
    { Next : unit -> BiSeq<'T> 
    Prev : unit -> BiSeq<'T> 
    Current : 'T } 

Учитывая значение BiSeq<'T>, мы можем получить текущую, следующую последовательность, а также последовательности, начиная с предыдущей точки.Базовая реализация всегда возвращает то же значение:

let rec always n = 
    { Current = n 
    Prev = fun() -> always n 
    Next = fun() -> always n } 

Или, вы можете написать функцию, которая принимает BiSeq<'T> и делает что-то для него. Например, мы можем увеличить текущее значение на 0, предыдущее на -2 и далее на +2. В более общем смысле:

let rec add by start c = 
    { Current = c.Current + start 
    Next = fun() -> add by (start+by) (c.Next()) 
    Prev = fun() -> add by (start-by) (c.Next()) } 

Это позволяет создавать двунаправленные последовательности, как последовательность четных чисел:

let evens = add 2 0 (always 0) 
evens.Next()      // 2 
evens.Next().Next()     // 4 
evens.Next().Next().Next()   // 6 
evens.Next().Next().Next().Prev() // 4 
evens.Prev()      // -2 

Теперь у вас есть последовательность, которая позволяет двигаться в обоих направлениях! Чтобы реализовать что-либо реалистичное на основе этой идеи, вам, вероятно, придется добавить некоторую форму кэширования и много других примитивов. Но это может быть интересное направление!

0

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

Смежные вопросы