Пытаюсь придумать алгоритм создания палитры цветов. Но для хитрой палитры. Палитра состоит из N базовых цветов + дополнительные оттенки, которые получаются полусуммой любых базовых цветов. К примеру, пусть у нас будет 4 базовых цвета A, B, C, D. Тогда общая палитра будет таковой:
A AB AC AD
B BC ВD
C CD
D
При этом выполняется равенство:
AB = (A + B)/2
AC = (A + C)/2
...
CD = (C + D)/2
Если бы не дополнительные оттенки – то проблем бы не было. Выбираем начальные точки медианным сечением, и дальше методом k-средних выводим наиболее оптимальные цифры.
Но для моей ситуации все чуть сложнее. Метод k-средних на каждой итерации смещает центры масс кластеров, что приводит к тому, что равенство перестает выполняться. И на каждой итерации мне нужно производить корректировку центров масс каждого кластера так, что бы исходное равенство снова стало верным.
Т.е. задача алгоритма – найти такие минимальные коэффициенты для каждого кластера, при умножении на которые (или при сложении с которыми?) исходное равенство снова становится верным. При этом каждый кластер имеет свой вес в виде количества цветов, относящихся к данному кластеру. Чем больше вес – тем меньше центр масс кластера должен смещаться.
Здравствуйте, Aniskin, Вы писали:
A>Пытаюсь придумать алгоритм создания палитры цветов. Но для хитрой палитры. Палитра состоит из N базовых цветов + дополнительные оттенки, которые получаются полусуммой любых базовых цветов. К примеру, пусть у нас будет 4 базовых цвета A, B, C, D. Тогда общая палитра будет таковой:
A>
A>A AB AC AD
A> B BC ВD
A> C CD
A> D
A>
A>При этом выполняется равенство:
A>AB = (A + B)/2 A>AC = (A + C)/2 A>... A>CD = (C + D)/2
A>Если бы не дополнительные оттенки – то проблем бы не было. Выбираем начальные точки медианным сечением, и дальше методом k-средних выводим наиболее оптимальные цифры.
A>Но для моей ситуации все чуть сложнее. Метод k-средних на каждой итерации смещает центры масс кластеров, что приводит к тому, что равенство перестает выполняться. И на каждой итерации мне нужно производить корректировку центров масс каждого кластера так, что бы исходное равенство снова стало верным.
A>Т.е. задача алгоритма – найти такие минимальные коэффициенты для каждого кластера, при умножении на которые (или при сложении с которыми?) исходное равенство снова становится верным. При этом каждый кластер имеет свой вес в виде количества цветов, относящихся к данному кластеру. Чем больше вес – тем меньше центр масс кластера должен смещаться.
A>Подскажите, в каком направлении двигаться.
Центры масс кластеров, в методе k-средних суть точки в пространстве, которые минимизируют потенциал . Т.е. переходя к механической аналогии каждая точка кластера тянет точку mu_i с силой пропорциональной отклонению от mu_i.
Если точки mu связаны дополнительными механическими связями, то можно переложить силы действующие на зависимые точки, на те точки, на которые они опираются.
Т.е.:
В процедуре расчетов центров масс кластеров, рассчитывал центры масс только для основных цветов.
Если точка принадлежит кластеру цвета AB, то учитывал ее (с весом 1/2) в кластерах A и B.
Сумма отклонений должна на каждой итерации уменьшаться, также как и в обычном алгоритме k-средних.
Здравствуйте, Aniskin, Вы писали:
A>Но для моей ситуации все чуть сложнее. Метод k-средних на каждой итерации смещает центры масс кластеров, что приводит к тому, что равенство перестает выполняться. И на каждой итерации мне нужно производить корректировку центров масс каждого кластера так, что бы исходное равенство снова стало верным.
Лень вникать в детали того, что ты хочешь, но если к-средних не подходит, то возьми EM для GMM, зафиксируй мат ожидания и оптимизируй только по вероятности и ковариациям.
Здравствуйте, Chorkov, Вы писали:
C>В процедуре расчетов центров масс кластеров, рассчитывал центры масс только для основных цветов. C>Если точка принадлежит кластеру цвета AB, то учитывал ее (с весом 1/2) в кластерах A и B.
Спасибо за идею. Но не могу сообразить, как ее применить на практике. Предположим, в какой-то момент образовались следующие кластеры:
A — состоит из одного цвета со значением 4, центр кластера 4.
AB — состоит из трех цветов со значениями 6, 7 и 8, центр кластера (6 + 7 + 8) / 3 = 7.
B — состоит из двух цветов со значениями 11 и 13, центр кластера (11 + 13) / 2 = 12.
Как посчитать правильные центры кластеров A и B для указанных значений?
Здравствуйте, Aniskin, Вы писали:
A>Здравствуйте, Chorkov, Вы писали:
C>>В процедуре расчетов центров масс кластеров, рассчитывал центры масс только для основных цветов. C>>Если точка принадлежит кластеру цвета AB, то учитывал ее (с весом 1/2) в кластерах A и B.
A>Спасибо за идею. Но не могу сообразить, как ее применить на практике. Предположим, в какой-то момент образовались следующие кластеры:
A>A — состоит из одного цвета со значением 4, центр кластера 4. A>AB — состоит из трех цветов со значениями 6, 7 и 8, центр кластера (6 + 7 + 8) / 3 = 7. A>B — состоит из двух цветов со значениями 11 и 13, центр кластера (11 + 13) / 2 = 12.
A>Как посчитать правильные центры кластеров A и B для указанных значений?
Можно ввести функцию ошибки и её минимизировать. Например так:
S(a,b)=(a-4)^2 + ((a+b)/2-6)^2 + ((a+b)/2-7)^2 + ((a+b)/2-8)^2 + (b-11)^2 + (b-13)^2
dS/da = 0
dS/db = 0
Получаешь простую линейную систему уравнений.
В твоём варианте примерно так A=3.3 B=11.6:
#!/usr/bin/lua
function AB(x)
local function sum(a) local s=0 for i=1,#a do s=s+a[i] end return s end
local n,s,a11,a22,a12,d,y
n={} s={} for i=1,3 do n[i]=#x[i] s[i]=sum(x[i]) end
a11=n[1]+n[2]/4
a22=n[3]+n[2]/4
a12=n[2]/4
d=a11*a22-a12*a12
y={ s[1]+s[2]/2, s[3]+s[2]/2 }
return (y[1]*a22-y[2]*a12)/d, (y[2]*a11-y[1]*a12)/d
end
print( AB{ {4}, {6,7,8}, {11,13} } )
Здравствуйте, kov_serg, Вы писали:
_>Здравствуйте, Aniskin, Вы писали:
A>>Здравствуйте, Chorkov, Вы писали:
C>>>В процедуре расчетов центров масс кластеров, рассчитывал центры масс только для основных цветов. C>>>Если точка принадлежит кластеру цвета AB, то учитывал ее (с весом 1/2) в кластерах A и B.
A>>Спасибо за идею. Но не могу сообразить, как ее применить на практике. Предположим, в какой-то момент образовались следующие кластеры:
A>>A — состоит из одного цвета со значением 4, центр кластера 4. A>>AB — состоит из трех цветов со значениями 6, 7 и 8, центр кластера (6 + 7 + 8) / 3 = 7. A>>B — состоит из двух цветов со значениями 11 и 13, центр кластера (11 + 13) / 2 = 12.
A>>Как посчитать правильные центры кластеров A и B для указанных значений? _>Можно ввести функцию ошибки и её минимизировать. Например так: _>S(a,b)=(a-4)^2 + ((a+b)/2-6)^2 + ((a+b)/2-7)^2 + ((a+b)/2-8)^2 + (b-11)^2 + (b-13)^2 _>dS/da = 0 _>dS/db = 0 _>Получаешь простую линейную систему уравнений.
В общем виде как-то так: https://ideone.com/KOBjX6
Здравствуйте, Aniskin, Вы писали:
_>>В общем виде как-то так: https://ideone.com/KOBjX6
A>Правильно ли я понимаю, что это код для произвольного кол-ва базовых цветов в палитре, а не только для двух?
Да
Здравствуйте, Aniskin, Вы писали:
A>Правильно ли я понимаю, что это код для произвольного кол-ва базовых цветов в палитре, а не только для двух?
ps: Еще хочу напомнить, что есть различные способы представления цвета (цветовые пространства)
И прям линейность в них никто не обещает. Так что экспериментируйте.
Здравствуйте, kov_serg, Вы писали:
_>Здравствуйте, Aniskin, Вы писали:
_>>>И прям линейность в них никто не обещает.
A>>Я работаю с линейными значениями sRGB.
_>Хреновый выбор.
Здравствуйте, Aniskin, Вы писали:
A>>>Я работаю с линейными значениями sRGB.
_>>Хреновый выбор.
A>Почему?
В HSL формате есть очень простые алгоритмы создания палитр с помощью фиксированных смещений Hue относительно базового тона, как это например делается в подобных генераторах: