Как создать тип алгоритма? - PullRequest
2 голосов
/ 06 октября 2010

Скажем, у меня есть две последовательности чисел, A и B .

Как я могу создать объект, чтобы описать отношения между двумя последовательностями?

Например:

A : 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ...

B : 0, 2, 4, 6, 8, 10, 12, 14, 16, 18 ...

B = 2A

Отношение f () - это то, как мы получаем от A до B .

Но, учитывая две произвольные последовательности, как я могу построить f ?

Кроме того, как я могу вернуть f вызывающему методу, чтобы он мог сразу использовать его с любым номером? - Можете ли вы использовать delegate в качестве типа возврата?

У меня есть одна идея, но, возможно, вы могли бы посоветовать мне это: я мог бы использовать шаблон декоратора для создания объекта, содержащего различные операторы и константы и т. Д. ... Затем просто сгенерируйте код. Это очень грязно, и я не хочу использовать этот метод.


Я не спрашиваю, как найти f , я могу это сделать. Я спрашиваю, как модель f .

Извините, если все это неясно, я не знаю, как еще это объяснить.

Ответы [ 3 ]

7 голосов
/ 06 октября 2010

Вы можете использовать деревья выражений LINQ :

var x = Expression.Parameter(typeof(int), "x");
var body = Expression.Multiply(Expression.Constant(2), x);
var lambda = Expression.Lambda<Func<int, int>>(body, x);
var f = lambda.Compile();

или (если функция известна)

Expression<Func<int, int>> lambda = x => 2 * x;
var f = lambda.Compile();

или (без деревьев выражений)

Func<int, int> f = x => 2 * x;

Использование:

var a = new int[] { 0, 1, 2, 3, 4, 5 };
var b = a.Select(f).ToArray();
// b == new int[] { 0, 2, 4, 6, 8, 10 };

См .: Класс выражений

См. Также: Основы дерева выражений

3 голосов
/ 06 октября 2010

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

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

2 голосов
/ 06 октября 2010

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

ОБНОВЛЕНИЕ: Что касается представления, это очень просто. Если вы решите не использовать LINQ (я не знаю много об этом, но пример, приведенный @dtb, выглядит очень хорошо, и я не знаю, почему вы этого не сделаете), вы можете очень легко свернуть свой собственный (конечно, они не будут так хорошо скомпилированы автоматически, вам придется их интерпретировать):

Просто создайте вложенные объекты Expressions, которые могут быть Value или Function. Value может быть Variable (x) или Constant (1), Function может быть UnaryFunction (Sin) или BinaryFunction (Plus). Классы практически пусты (конструктор и рекурсивная функция evaluate).

Это стандартный подход, который вы бы использовали, если бы использовали его на любом другом языке, скажем, на Haskell (только с ADT вместо классов, но в этом случае различие довольно тривиально).

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