Самый простой способ определить сложность времени из времени выполнения - PullRequest
1 голос
/ 14 октября 2010

Предположим, я пытаюсь проанализировать алгоритм, и все, что я могу сделать, это запустить его с разными входами.Я могу построить набор точек (x, y) как (размер выборки, время выполнения).Я хотел бы динамически разделить алгоритм на класс сложности (линейный, квадратичный, экспоненциальный, логарифмический и т. Д.). В идеале я мог бы дать уравнение, которое более или менее приближает поведение.Я просто не уверен, что лучший способ сделать это.

Для любого полинома степени я могу создать кривые регрессии и придумать некоторую степень пригодности, но на самом деле я не знаю, как бы я это сделал для любой неполиномиальной функции.Это сложнее, так как у меня нет никаких предварительных знаний о том, какую форму я должен пытаться подогнать.

Это может быть скорее математический вопрос, чем вопрос программирования, но он мне очень интересен.Я не математик, так что может быть более простой метод для получения разумной функции из набора точек, о которых я просто не знаю.У кого-нибудь есть идеи для решения такой проблемы?Есть ли числовая библиотека для C #, которая могла бы помочь мне подсчитать числа?

Ответы [ 2 ]

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

Ну, есть не так много классов сложности, которые вас действительно волнуют, так что скажем: линейный, квадратичный, полиномиальный (степень> 2), экспоненциальный и логарифмический.

Для каждого из них вы можете использоватьнаибольшая (x, y) пара для решения неизвестной переменной.Пусть y = f (x) обозначает время выполнения вашего алгоритма как функцию размера выборки.Давайте предположим, что f (1) = 0, и если этого не произойдет, мы всегда сможем вычесть это значение y (1) из каждого из y, это просто исключит константы в f (x).Пусть y (end) обозначает последнее (и наибольшее) значение y в вашем (x, y) наборе данных.

На данный момент мы можем найти для неизвестного в каждой канонической форме:

f(x) = c*x
f(x) = c*x^2
f(x) = x^c
f(x) = c^x
f(x) = log(x)/log(c)

Поскольку в каждом уравнении есть только один неизвестный, мы можем вам в любой момент найти для него точку.Рассмотрим следующие данные, полученные из полинома случайной степени> 2:

x = [ 1 2 3 4 5 6 7 8 9 10 ];
y = [ 0 6 19 44 81 135 206 297 411 550 ];

Если мы используем последнюю точку для решения для c для каждой возможности (предполагая, что это будет наименьшая оценка шума)

550 = c*10    -> c = 55
550 = c*10^2  -> c = 5.5
550 = 10^c    -> c = log(550)/log(10) ~= 2.74
550 = c^10    -> c = 550^(1/10) ~= 1.88
550 = log(x)/log(c) -> c = 10^(1/550) ~= 1.0042

Теперь мы можем сравнить, насколько хорошо каждая из этих функций соответствует оставшимся данным, вот график:

Я новичок и не могу публиковать изображения, поэтому посмотрите на график здесь: http://i.stack.imgur.com/UH6T8.png

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

1 голос
/ 14 октября 2010

Подгонка кривых раньше была искусством, но теперь как-то декадентской :) (Это шутка для окружающих физиков)

Был достигнут большой прогресс, который позволяет простым смертным угадывать (некоторые) нетривиальные функциональные зависимости.

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

Eureqa (произносится «эврика») - это программный инструмент для обнаружения уравнений и скрытых математических связей в ваших данных. Его цель состоит в том, чтобы определить простейшие математические формулы, которые могли бы описать механизмы, лежащие в основе данных. Eureqa можно загрузить и использовать бесплатно. Ищите программу загрузки, видеоурок, форум пользователей и другие и справочные материалы.

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

НТН!

Post Scriptum:

К сожалению, программное обеспечение больше не является бесплатным: (

...