Выборка из mysql и сравнение значений PHP

iqmaker
На сайте с 17.04.2012
Offline
309
#11
Ilekor:
Друзья, в значении хранится текстовый код изображения, вот эти коды и сравниваются на похожесть кодов, вот так
сначала получаем и сравниваем sig1 и sig2, mysql такого сравнения не сделает, это функция библиотеки php


$r_sig = puzzle_vector_normalized_distance($value1['sig'], $value2['sig']);
echo $r_sig


и так до тех пор пока sig1 не пройдет все значения
после чего sig2 начинает также проходить по все проверкам и так пока не закончится

Тогда если правильно понимаю мое предыдущее решение должно работать, нужно выбрать все элементы, отсортировать их по расстоянию, которое выдает функция: puzzle_vector_normalized_distance, дальше все как написал выше, делаем один проход, получится сложность: (сложность сортировки + N) * время расчета расстояния

---------- Добавлено 06.01.2015 в 02:58 ----------

Видимо не дождусь я вашего сообщения, надо спать, но опять погадаю, вероятно вам понадобится функция php: http://php.net/manual/en/function.uksort.php, в которую вы скормите ваш компаратор, таким образом получите отсортированное множество, по которому уже пробежите аналогично коду на python.

ДП
На сайте с 23.11.2009
Offline
203
#12
Ilekor:


$r_sig = puzzle_vector_normalized_distance($value1['sig'], $value2['sig']);
echo $r_sig


и так до тех пор пока sig1 не пройдет все значения
после чего sig2 начинает также проходить по все проверкам и так пока не закончится

Вам как минимум можно не сравнивать одни и те же значения, ведь если изображение 1 похоже на изображени 2, то и обратное верно? Получится проверок в два раза меньше.

vandamme
На сайте с 30.11.2008
Offline
672
#13
Дикий пионер:
проверок в два раза меньше

скорее прогрессия, а не два раза.

Mad_Man
На сайте с 10.11.2008
Offline
162
#14
Ilekor:
Я пытался сделать это через AJAX, но мои познаний в JS очень минимальные и поэтому не смог представить как это реализовать.

Это вообще без комментариев.

iqmaker:
задача найти группы разность между элементами которых не более 10

У топикстартера речь была о неких мифических 10% между каждым значением, но в связи с полным нежеланием решить собственную проблему из-за фатальной лени - забыл указать самое главное:


puzzle_vector_normalized_distance - compute comparable signatures of bitmap images.


Comparing Vectors

In order to check whether two pictures are similar, you need to compare their PuzzleCvec signatures, using puzzle_vector_normalized_distance()

That function returns a distance, between 0.0 and 1.0. The lesser, the nearer.

Ни структуры таблиц, ни примера данных для теста. Нихрена нету.

На текущий момент юмор заключается в том, что логика работы у ТС построена на запихивании в БД изображений с полной выгрузкой всей этой дряни оттуда каждый раз и в довесок идёт попарное постоянное сравнивание всех значений через внешнюю либу. Сложность вычислений близка к N^2 и упростить не выйдет, по крайней мере пока юзается блэкбокс в виде puzzle_vector_normalized_distance() всего на одно сравнение за раз. По теории алгоритмов попарное сравнение быстрее N * ln(N) и вовсе быть не может, читайте матчасть.

iqmaker:
получится сложность: (сложность сортировки + N) * время расчета расстояния

При оценке сложности алгоритма играет роль только количество атомарных итераций над элементами. Реальное время выполнения всего этого месива считается отдельно.

Дикий пионер:
Вам как минимум можно не сравнивать одни и те же значения, ведь если изображение 1 похоже на изображени 2, то и обратное верно? Получится проверок в два раза меньше.

Дорогой мой, а давно (N - 1)^2 = N^2 / 2?

ДП
На сайте с 23.11.2009
Offline
203
#15
Mad_Man:

На текущий момент юмор заключается в том, что логика работы у ТС построена на запихивании в БД изображений с полной выгрузкой всей этой дряни оттуда каждый раз

ТС в БД хранит PuzzleCvec signatures, насколько я понимаю.

Mad_Man:

Дорогой мой, а давно (N - 1)^2 = N^2 / 2?

Почему вы придумали какую-то формулу и спрашиваете меня, верна ли она?

Моя логика такая при условии func(a,b)==func(b,a)

Для первого элемента делается N-1 сравнение, для последнего элемента сравнений нет. Для второго элемента - N-2 сравнений, для предпоследнего - одно. Получается, что для двух элементов в сумме N-1 сравнение. В среднем для каждого получается (N-1)/2. - вот и в два раза меньше.

Где я не прав?

iqmaker
На сайте с 17.04.2012
Offline
309
#16
Mad_Man:
У топикстартера речь была о неких мифических 10% между каждым значением

это понятно, но я предполагал если элементы отсортировать то они отсортируются по "похожести", таким образом "одинаковые" ( с минимальным расстоянием ) элементы окажутся рядом и их можно будет выделить в группы. Собственно сработает или нет зависит от того как будет работать функция определения расстояния между элементами, но ТС молчит.

Дикий пионер:
Где я не прав?

вы все правильно сказали

обход может быть таким:


for i in range(1, 11):
for x in range(i + 1, 11):
print i, x

а может таким:


for i in range(1, 11):
for x in range(1, 11):
print i, x
Mad_Man
На сайте с 10.11.2008
Offline
162
#17
Дикий пионер:
Почему вы придумали какую-то формулу и спрашиваете меня, верна ли она?
Моя логика такая при условии func(a,b)==func(b,a)
Для первого элемента делается N-1 сравнение, для последнего элемента сравнений нет. Для второго элемента - N-2 сравнений, для предпоследнего - одно. Получается, что для двух элементов в сумме N-1 сравнение. В среднем для каждого получается (N-1)/2. - вот и в два раза меньше.
Где я не прав?

Теперь понял о чём вы. Вы гасите квадратичный рост сложности вычислений пропуская самого себя и попарно проверенные элементы. К сожалению топикстарер вернётся к той же неоптимизированной сложности, от которой страдает в данный момент, уже через 40% элементов (140к сигнатур изображений).

Самый быстрый для последующей выборки вариант - кэш вычислений, который будет расти с каждым новым добавленным элементом, перекладывая постоянные затраты проца на хард, делая расчёты сходства только единожды - при добавлении изображения:

Шаг #1. Изображений в базе: 0, добавляем новое, считать пока нечего.

Шаг #2. Изображений в базе: 1, добавляем новое, считаем показатели схожести для нового и старого.

Шаг #3. Изображений в базе: 2, добавляем новое, считаем показатели схожести для нового и всех старых.

...

Шаг #N. Изображений в базе: N - 1, добавляем новое, считаем показатели схожести себя с предыдущими.

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

Ilekor
На сайте с 22.04.2009
Offline
138
#18

Mad_Man, в базе хранится буквеный код изображения, состоящий из 150 символов, который вычисляет библиотека libpuzzle, чем к примеру эти 150 символов отличаются от к примеру 150 символов описания товара?

Лучший дорген 21 века AgDor(http://agdor.info)
Mad_Man
На сайте с 10.11.2008
Offline
162
#19
Ilekor:
Mad_Man, в базе хранится буквеный код изображения, состоящий из 150 символов, который вычисляет библиотека libpuzzle, чем к примеру эти 150 символов отличаются от к примеру 150 символов описания товара?

И к чему вы это написали?

Ilekor
На сайте с 22.04.2009
Offline
138
#20
Mad_Man:
И к чему вы это написали?

К тому, Вы выше написали, что я храню в базе изображения.

Вот как делаю я! Но проц не выдерживает, вот я и ищу способ это оптимизировать.


$sql_select = "SELECT signature FROM images WHERE signature != ''";

$sql_result = $db->query( $sql_select );
while ( $row = $db->get_row( $sql_result ) ) {
$sig[] = $row;
}

$sig2 = $sig; // скопируем массив

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


foreach($sig as $value1) {
unset($$sig2[$value1['signature']]);

foreach($sig2 as $value2) {
# вычисление разности изображения по сигнатурам
$r_sig = puzzle_vector_normalized_distance($value1['sig'], $value2['sig']);
# округлим разность в проценты
$diff = round($r_sig * 100);
# Определим похожесть изображений
$img_true = ($r_sig <= 0.20) ? "Похожа" : "Не похожа";
echo $img_true;
}
}

Авторизуйтесь или зарегистрируйтесь, чтобы оставить комментарий