Общая Линейная Кусочная Таблица Поиска - PullRequest
5 голосов
/ 02 июля 2010

Я ищу общий оптимизированный поисковый объект, который принимает функцию f (x) и создает кусочно-линейную аппроксимацию с настраиваемыми параметрами для диапазона x и интервалов заполнения.

Очевидно, что это не сложно написать, но, учитывая, что это полезно для многих дорогих функций (триг, доходность, расстояние), я подумал, что общая функция может уже существовать. Пожалуйста, дайте мне знать.

Еще одна полезная функция - сериализация / десериализация таблицы поиска, поскольку для создания достаточно точной таблицы 100 000 точек + может потребоваться несколько минут.

1 Ответ

4 голосов
/ 02 июля 2010

Я не верю, что что-либо существует в библиотеках классов .NET напрямую. Что-то может существовать в сторонней библиотеке (, например, C5, возможно ).

Создание универсальной версии функции, которая может принимать диапазоны, немного сложно в C #, так как нет унифицирующего типа или интерфейса, который предоставляет арифметические операторы. Однако, с некоторой креативностью, возможно создать что-то:

// generic linear lookup class, supports any comparable type T
public class LinearLookup<T>  where T : IComparable<T>
{
    private readonly List<T> m_DomainValues = new List<T>();

    public LinearLookup( Func<T,T> domainFunc, Func<T,T> rangeFunc, 
          T lowerBound, T upperBound )
    {
        m_DomainValues = Range( domainFunc, rangeFunc, 
                                lowerBound, upperBound )
                           .ToList();
    }

    public T Lookup( T rangeValue )
    {
        // this could be improved for numeric types
        var index = m_DomainValues.BinarySearch( rangeValue );
        if( index < 0 )
            index = (-index)-1;
        return m_DomainValues[index];
    }

    private static IEnumerable<T> Range( Func<T,T> domainFunc, 
         Func<T,T> rangeFunc, T lower, T upper )
    {
        var rangeVal = lower;
        do
        {
            yield return domainFunc( rangeVal );

            rangeVal = rangeFunc( rangeVal );

        } while( rangeVal.CompareTo( upper ) < 0 );
    }
}

Этот класс будет предварительно вычислять набор значений домена для функции domainFunc в диапазоне [нижний, верхний>. Для поиска используется двоичный поиск - компромисс, который позволяет использовать любой сопоставимый тип, а не только встроенные числовые типы. Функция rangeFunc позволяет управлять приращением внешним кодом. Итак, вот линейный поиск для Math.Sin в диапазоне [0, PI / 2> с шагом 0,01:

var sinLookup = new LinearLookup( Math.Sin, x => x + 0.01d, 0, Math.PI/2 );
var lookupPI4 = sinLookup[Math.PI/4]; // fetch the value sin(π/4)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...