IPB
ЛогинПароль:

> Внимание!

1. Пользуйтесь тегами кода. - [code] ... [/code]
2. Точно указывайте язык, название и версию компилятора (интерпретатора).
3. Название темы должно быть информативным.
В описании темы указываем язык!!!

Наладить общение поможет, если вы подпишитесь по почте на новые темы в этом форуме.

> Иерархическая кластеризация., Немного DataMining на С++
сообщение
Сообщение #1


Бывалый
***

Группа: Пользователи
Сообщений: 222
Пол: Мужской
Реальное имя: Andrew

Репутация: -  0  +


Вершины – объекты
минимального остовного дерева группируются в кластеры.
Выбираются два объекта, которым соответствует минимальное ребро minjdj,
где j=1, n-1. Далее эти объекты стягиваются в один кластер (класс, таксон, страту) и
процедура шага 2 повторяется до тех пор, пока на n-1 этапе группирования не будет
сформирован один кластер, объединяющий все объекты. STOP.

Прикрепленное изображение

На рис. представлена последовательность группировки объектов в
кластеры для заданного на рис.1 примера минимального остовного дерева.
Порядок объединения объектов в кластеры отображён на рёбрах, которые
связывают объединяемые объекты .Таким образом, первыми
объединяются объекты X4 и Х5,которые в МОД связывает минимальное ребро d4
с весом 2. Вторыми объединяются объекты X2и X3, связанные ребром d2
с весом 3 , и так далее, пока на шестом этапе группирования ранее связанные объекты (X1,X2,X3,X4,X5,X6)
не будут объединены с объектом X7 ребром с весом 7.

И так , перейдем к описанию алгоритма кластеризации на примере :
Ребра МОД :
Цитата
(ИЗ--ВЕС-->В);
1. Е--2328-->Ом
2. В--2732-->И
3. Е--4667-->П
4. Л--5161-->Ом
5. О--6588-->И
7. П--14946-->В
И образуемые кластера :
(Шаг. №кластера)
1. 1.Е + ОМ значение кластера 2328
2. 1.
2. В + И 2732
3. 1. кластер поглощает вершину П, новый кластер Е+Ом+П 4667
2.
4. 1. поглощает вершину Л, новый кластер Е+Ом+П+Л 5161
2.
5. 1.
2. поглощает вершину О, новый кластер В + И + О 6588
6. 1 поглошает 2 и получается Л+Е+О+П+В+И+Ом 14946


Надеюсь понятно..вот как я понял этот алгоритм вербально :
Цикл от i=0 до n-1
Цикл от j=0 до n-1
Если множество вершин ребра/кластераi при пересечении с множеством вершин ребра/кластераj образует не пустое множество
если значение ребра/кластераj >=значению ребра/кластераi
ТОГДА образуется кластер соединением множества вершин ребра/кластераj и множества вершин ребра/кластераi
ИНАЧЕ наше ребро и есть кластер.

Правильно ли я понял алгоритм?
Вот так его можно описать в коде..
//ribs это объект класса реализующего :
// QSet<int> - множество вершин ребра/кластера, возвращается путем вызова метода items()
// свойство value, которое возвращает вес ребра/кластера
//считать, что операции &, &= - пересечение
// += - слияние.
for(int i=0;i<ribs.size();++i)
for(int j=0;j<ribs.size();++j)
if (ribs.at(j)!=ribs.at(i))//не сравниваем сами с собой..
if ( (!(ribs.at(i)->items() & ribs.at(j)->items()).empty()))
//если пересечение не образует пустое множество
if (ribs.at(j)->value() >= ribs.at(i)->value())
//если значение j ребра/кластера меньше i
{
ribs.at(j)->items()+=ribs.at(i)->items();//соединяем j и i ребро/кластера
}
else
{
// ребро и есть кластер
}
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
 
 Ответить  Открыть новую тему 
Ответов
сообщение
Сообщение #2


Бывалый
***

Группа: Пользователи
Сообщений: 222
Пол: Мужской
Реальное имя: Andrew

Репутация: -  0  +


Что-то ты нагромоздил кода, хотя просто я использую QtStl в своем проекте, там попроще с векторами и множествами, да и для представления ребер/кластеров я реализовал отдельный класс( просто выкладывать его сюда мало смысла - всеравно без Qt не получиться скомпилировать)
А твой ответ не совсем ясен( честно скажу, в код не вникал).
У него на Срезе 15 обременяются вершины Инская и лянгасово, т.к между ними мин. ребро
на срезе 156 к этому ребру/кластеру добовляется вершина Орехово, т.к она связана с одной из вершин в предыдущем кластере(а именно - Инская) следующим мин. ребром с весом в 156..По тому же принципу и Егоршино на срезе 176 добавляется в тот же кластер, далее Омск на срезе 226, Пермь на срезе 239 (т.к все они имею связи через ребра МОД). На 334 срезе связывается Войновка и Екатеринбург, т.к они имею следующее мин. ребро из не использованных, и ни одна из этим вершин не имеется в предыдущих кластерах, поэтому они стают особняком на этом срезе, а после чего у них соединение на Перьми появляется и они объединяются в кластер..

А твои результаты я не понял. Может я плохо объясняю? Пожалуйста, спроси, что именно не понятно - я постараюсь объяснить более человеческим языком. Если надо, скину свои исходники.

Приведу всетаки полный код, может что яснее странет..
Сначала класс кластер/ребро :
интерфейс :
#ifndef CLUSTER_H
#define CLUSTER_H
#include <QSet>// Qt'вые множества
#include <QString>

class Cluster
{
private :
int value_;
QSet<int> items_;
public :
Cluster();
Cluster(Cluster & other);//конструктор копироавния
Cluster(int item1 ,int item2, int nValue);//для ребра конструктор
Cluster(int item1, int nValue);//для одной вершины
const int& value()const {return value_; }//возвращает вес кластера/ребра
void setValue(const int &newValue){value_=newValue;};//устанавливает вес
QSet<int> &items();//возврашает вершины в кластере/ребре
void append(Cluster * nClust);//"поглотить" другое ребро/кластер
QString toString(QStringList * lst);//перевести номера вершин в их строковой эквивалент
};

#endif // CLUSTER_H


Реализация ... :
#include "cluster.h"

Cluster::Cluster()
{
}

Cluster::Cluster(Cluster &other)
{
items_=other.items();
value_=other.value();
centerPos_=other.centerPos();
isPainted_=other.isPainted();
}

Cluster::Cluster(int item1 , int item2, int nValue)
{
value_=nValue;
items_.insert(item1);
items_.insert(item2);
}

Cluster::Cluster(int item1 , int nValue)
{
value_=nValue;
items_.insert(item1);
}

void Cluster::append(Cluster * nClust)
{
QSetIterator <int> it (nClust->items());
while (it.hasNext())//Java-style итератор, очень удобно. Пока есть элементы в контейнере
items_ << it.next();//забираем их из другого кластера.
}

QSet<int>& Cluster::items()
{
return items_;
}

QString Cluster::toString(QStringList * lst)
{
QString str;
QStringList * list = lst;
QSetIterator <int> it (items_);
str.append("|");
while(it.hasNext())
str.append(list->at(it.next())+" ");
str.append("|");
return str;
}




А вот алгоритм кластеризации :
void Model::calculateNewClustersModel(QStandardItemModel * spanningMatrixModel)
{
clusters.clear();//очищаем вектор срезов. Представляет из себя QVector <QMap < int, QVector <Cluster* > >
static bool *isNum = new bool;
int rc = spanningMatrixModel->rowCount();//размер МОД
int sM[rc][rc];//цисленный массив
QVector <Cluster *> ribs;//вектор ребер..
for (int i=0;i<rc;++i)
for (int j=0;j<rc;++j)
sM[i][j]=spanningMatrixModel->item(i,j)->text().toInt(isNum,10);
//перегоняет модель таблицы в численный массив
for (int i=0;i<rc;++i)
for (int j=i+1;j<rc;++j)
if (sM[i][j]!=0)
ribs.push_back(new Cluster(i,j,sM[i][j]));//собираем ребра
qSort(ribs.begin(),ribs.end(),cmp);//сортируем их по возрастанию веса.

for(int i=0;i<ribs.size();++i)
for(int j=0;j<ribs.size();++j)
if (ribs.at(j)!=ribs.at(i))//не сравниваем сами с собой
if ( (!(ribs.at(i)->items() & ribs.at(j)->items()).empty()))
//если на пересечении не пустое множество
if (ribs.at(j)->value() >= ribs.at(i)->value())
//и если ребро j имеет значение более ребра i
{
ribs.at(j)->items()+=ribs.at(i)->items();//поглатить ребро i
qDebug() << "appended" <<ribs.at(j)->toString(&vHeaderData) << ribs.at(j)->value();
//Вывод информации о том, какой кластер поглатился и кем
}
else
{
qDebug() <<"single" <<ribs.at(i)->toString(&vHeaderData) << ribs.at(i)->value();
//Вывод информации о том, какое ребро является уже кластером
}
for(int i=0;i<ribs.size();++i)
qDebug() << "2 " <<ribs.at(i)->toString(&vHeaderData) << ribs.at(i)->value() <<
" SIZE " << ribs.at(i)->items().size();
}


И вот вывод моего кода для "Вагонооборот" при 19 строках :
Цитата
"|Курган Инская |" 152 SIZE 2
"|Войновка Бердяуш |" 416 SIZE 2
"|Алтайская Орехово |" 428 SIZE 2
"|Пермь Нижний Новгород |" 461 SIZE 2
"|Екатеринбург Челябинск |" 576 SIZE 2
"|Войновка Бердяуш Богданович |" 593 SIZE 3
"|Смычка Агрыз |" 799 SIZE 2
"|Алтайская Орехово Каменск-Уральский |" 1264 SIZE 3
"|Пермь Екатеринбург Нижний Новгород Челябинск |" 1305 SIZE 4
"|Алтайская Орехово Смычка Агрыз Каменск-Уральский |" 1453 SIZE 5
"|Курган Инская Юдино |" 2296 SIZE 3
"|Егоршино Пермь Екатеринбург Нижний Новгород Челябинск |" 2325 SIZE 5
"|Егоршино Пермь Омск Екатеринбург Нижний Новгород Челябинск |" 2328 SIZE 6
"|Курган Войновка Инская Бердяуш Юдино Богданович |" 2732 SIZE 6
"|Курган Алтайская Орехово Войновка Инская Бердяуш Смычка Агрыз Юдино Богданович Каменск-Уральский |" 2876 SIZE 11
"|Лянгасово Егоршино Пермь Омск Екатеринбург Нижний Новгород Челябинск |" 5161 SIZE 7
"|Курган Алтайская Орехово Войновка Инская Бердяуш Смычка Чусовская Агрыз Юдино Богданович Каменск-Уральский |" 5953 SIZE 12
"|Лянгасово Егоршино Орехово Пермь Войновка Инская Омск Екатеринбург Бердяуш Смычка Чусовская Агрыз Нижний Новгород Юдино Челябинск Богданович Каменск-Уральский Курган Алтайская |" 7984 SIZE 19

Что это значит?а вот что : SIZE - размер сформированного кластера, чилос перед SIZE - срез, на котором кластер сформирован, ну и соответственно его состав.
Мой вопрос в том, что можно это как-либо оптимизировать?Допустим, что бы не проходил вершины, которые уже посчитал как еденичный кластер и т.д. Просто для параметра "Количество сортировочных путей" у меня считает не правильно кластера т.к там одинаковые ребра по весу..
Да к тому же , эта оптимизация мне нужная для того, что бы нормально отрисовывать дендрограмму ( как на сайте снизу), т.к я буду использовать "события" Qt(сигналы/слоты) что, кого поглотило и отрисовывать их по-порядку, а не после нахождения...

Сообщение отредактировано: volvo -
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 

Сообщений в этой теме
Andrewshkovskii   Иерархическая кластеризация.   24.11.2009 21:59
volvo   Можно уточнить, в результате ты что хочешь получит…   24.11.2009 22:15
Andrewshkovskii   http://el-niko.ru/lab/1/ Вот тут пример , это прог…   24.11.2009 22:34
volvo   Шо-то мне не очень понятно, что там твой согруппни…   25.11.2009 0:46
Andrewshkovskii   Что-то ты нагромоздил кода, хотя просто я использу…   25.11.2009 3:48
volvo   У меня в принципе то же самое вот до этого момента…   25.11.2009 4:38
Andrewshkovskii   На 0 этапе добавил Лянгасово куда-то?Ну про код пр…   25.11.2009 4:52
volvo   Так... До Qt я вчера так и не добрался, сегодня ве…   25.11.2009 17:04
Andrewshkovskii   Да, результат более понятно,сейчас в коде по-разби…   25.11.2009 17:18
Andrewshkovskii   Вот такой вот результат,из-за одинковых значений…   25.11.2009 18:41
volvo   В общем, вот чего у меня получилось после полной п…   26.11.2009 5:44
Andrewshkovskii   Мда, мне далекова-то до твоих мозгов, Владимир..Сп…   26.11.2009 6:42
volvo   Это вряд ли... В Qt очень сокращенная версия STL-я…   26.11.2009 6:59
volvo   В первом приближении - вот так (тут очень многое д…   26.11.2009 22:41
Andrewshkovskii   Ох, только добрался до компа, весь день в институт…   27.11.2009 4:04
Andrewshkovskii   Ну в общем я попробовал разобраться, все в исходни…   27.11.2009 17:44
volvo   Ты точно нужный исходник присоединил? А то по-моем…   27.11.2009 17:53
Andrewshkovskii   Упс, исходник вот. Насчет длины вектора так и дума…   27.11.2009 17:55
volvo   Вот ответы: :) (я оставил твои комментарии, ниже д…   27.11.2009 18:55
Andrewshkovskii   Так, слегка проникся кодом, и даже что-то понял:) …   27.11.2009 21:10
volvo   Написал код для визуализации на VCL (Билдер). Вот …   29.11.2009 22:21
Andrewshkovskii   Привет!:)спасибо за огромную помощь..но я поше…   30.11.2009 5:26
volvo   Блин, у меня оказывается на скрине не было видно с…   30.11.2009 5:48
Andrewshkovskii   Ну я проект скину перед сном, если надо, посмотриш…   30.11.2009 5:50
Гость   В общем проблема такая...надо как-то зафиксировать…   1.12.2009 0:34
-Volvo-   Что значит "как нибудь"? Устанавливаешь …   1.12.2009 1:12
Andrewshkovskii   Там надо минимум в 0 устанавливать, таково требова…   1.12.2009 4:27
volvo   В таком случае у тебя нет другого варианта, кроме …   1.12.2009 6:04
Andrewshkovskii   Была такая мысль у меня о фиксации каждого кластер…   1.12.2009 6:19
Andrewshkovskii   Перечитал методичку..в общем-то можно и вовсе без …   1.12.2009 6:52
Andrewshkovskii   В общем вот что вышло у меня. осталась одна пробле…   1.12.2009 20:41
Andrewshkovskii   С этой проблема ещё связано с отрисовкой кластеров…   1.12.2009 21:42
Andrewshkovskii   outCanvas->MoveTo(visLabelWidth + 30 + cluste…   1.12.2009 22:08
Andrewshkovskii   Понятно..   1.12.2009 22:57
volvo   :blink: А расскажи мне (ты свою модель лучше знаеш…   2.12.2009 1:51
Andrewshkovskii   Изменяется она потому, что она при первичной отрис…   2.12.2009 2:38
volvo   Угу... Именно: // Это у тебя было ... …   2.12.2009 3:12
Andrewshkovskii   Ну макс. длина у меня вычисляется, это я предусмот…   2.12.2009 5:07
volvo   Ну, это вообще не проблема... Делаем в drawClamp(…   2.12.2009 5:58
Andrewshkovskii   хм..действительно.. Над не забыть только biggest_e…   2.12.2009 6:06
Andrewshkovskii   С 2ой проблемой разобрался, а вот что делать с 1ой…   2.12.2009 17:49
Andrewshkovskii   Ну в общем дописал..нашел правда один мемори лик, …   3.12.2009 4:14
finasteride 1 mg no prescription   Cytotec Pills Over The Counter   29.10.2021 23:10
gabriella   Your writings and news are really interesting to m…   12.04.2022 10:27
reznit   Доступа к определенному элементу (кроме первого) п…   9.06.2022 15:17
nishaknapp   Why not settling on games that is fun and at the s…   29.07.2022 16:56
gabriella   It is the intent to provide valuable information a…   1.08.2022 9:37


 Ответить  Открыть новую тему 
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 





- Текстовая версия 8.05.2024 10:12
500Gb HDD, 6Gb RAM, 2 Cores, 7 EUR в месяц — такие хостинги правда бывают
Связь с администрацией: bu_gen в домене octagram.name