//============================================================================ // Name : Clastering1.cpp // Author : Kozlov // Version : // Copyright : Your copyright notice // Description : //============================================================================ #include using namespace std; #include #include //Maximum 94eek na ploskosti const long int g_MAX_PADS=500000; //Maximum klasterov const long int g_MAX_CENTERS=50000; //Maximum sosedei dl9 odnoi 94eiki const int g_MAX_NEIGHBORS=20; //Minimal'na9 zna4asha9 amplituda const float g_MIN_AMPLITUDE=0; //Informatsi9 o kazjdoi 94eike s amlitudoi > Amin struct PadTable{ float x1, y1, x2, y2, xc, yc; int N, Ns[g_MAX_NEIGHBORS], Nsmax; bool active; }; PadTable PT[g_MAX_PADS]; //Amplitudi 94eek, A[i] > Amin float g_AmplitudesArray[g_MAX_PADS]; //Dopolnitel'nie nomera 94eek A > Amin int g_ClustersArray[g_MAX_PADS]; //4islo 94eek v zagryjennoi strukture int g_MaxPads; //4islo 94eek s A[i] > Amin int g_MaxWorkingPads; //PT[i] -> A[i] -> K[i] //--------------- Poly4enie strukturi 94eek iz txt //PROVERENO---------- void NetCreate() { FILE* fNet; fNet = fopen("/home/kozlov/workspace/Clastering1/src/test1.txt", "r"); int Cl = 1; float a1, a2, a3, a4; //Poly4enie informacii iz faila, zapis' v PadTable do{ fscanf(fNet, "%f %f %f %f\n", &a1, &a2, &a3, &a4); PT[Cl].x1 = a1; PT[Cl].y1 = a2; PT[Cl].x2 = a3; PT[Cl].y2 = a4; PT[Cl].xc = (a1 + a3) / 2; PT[Cl].yc = (a2 + a4) / 2; PT[Cl].N = Cl; PT[Cl].active = true; PT[Cl].Nsmax = 0; Cl++; }while(!feof(fNet)); g_MaxPads = Cl - 1; Cl = 0; fclose(fNet); //Postroenie spiskov sosedei v PadTable for(int i = 1; i <= g_MaxPads; i++) { Cl = 1; for(int j = 1; j <= g_MaxPads; j++) { // if(((((PT[i].x1 == PT[j].x2) || (PT[i].x2==PT[j].x1)) && (PT[j].y1 <= PT[i].y2) && (PT[j].y2 >= PT[i].y1)) || (((PT[i].y1 == PT[j].y2) || (PT[i].y2 == PT[j].y1)) && (PT[j].x1 <= PT[i].x2) && (PT[j].x2 >= PT[i].x1))) && (i != j)) { PT[i].Ns[Cl] = j; PT[i].Nsmax++; Cl++; } } } } //------------------------------------------------------------- //-------------------Zagruzka amplitud iz txt //PROVERENO------------------ void StateCreate() { FILE *fNet; fNet = fopen("/home/kozlov/workspace/Clastering1/src/testData1.txt", "r"); float a1, a2, a3; int Cl = 1; int nom_Cluster; bool neighborIsFound = false; bool padsOverload = false; do{ //Proverka zadryzki stryktyri if(g_MaxPads == 0) { cout<<"Pad data is not loaded!"; break; } fscanf(fNet, "%f %f %f\n", &a1, &a2, &a3); neighborIsFound = false; nom_Cluster = 1; do{ //Zapis' v 94eiky po koordinatam if((a1 > PT[nom_Cluster].x1) && (a1 < PT[nom_Cluster].x2) && (a2 > PT[nom_Cluster].y1) && (a2 < PT[nom_Cluster].y2)) { //Proverka amplitydi 94eiki if(a3 > g_MIN_AMPLITUDE) { g_ClustersArray[nom_Cluster] = Cl; g_AmplitudesArray[nom_Cluster] = a3; Cl++; g_MaxWorkingPads++; } neighborIsFound=true; } //Proverka na previshenie maximuma 94eek if(nom_Cluster > g_MaxPads) { padsOverload = true; break; } nom_Cluster++; if(padsOverload)break; }while(!neighborIsFound); if(padsOverload)break; }while(!feof(fNet)); fclose(fNet); } //----------------------------------------------------------- //-----------O4istka strukturi 94eek //PROVERENO-------------- void NetCleare() { for(int i = 0; i < g_MAX_PADS; i++) { PT[i].x1 = 0; PT[i].x2 = 0; PT[i].y1 = 0; PT[i].y2 = 0; PT[i].yc = 0; PT[i].yc = 0; PT[i].N = 0; PT[i].Nsmax = 0; for(int j = 0; j < g_MAX_NEIGHBORS; j++) { PT[i].Ns[j] = 0; } PT[i].active = false; } g_MaxPads = 0; } //--------------------------------------------------------- //----------O4istka amplitud //PROVERENO-------------------- void StateCleare() { g_MaxWorkingPads = 0; for(int i = 0; i < g_MAX_PADS; i++) { g_ClustersArray[i] = 0; g_AmplitudesArray[i] = 0; } } //-------------------------------------------------------- //---Realizatsi9 moego metoda clasterizacii //PROVERENO--------------- class NewMethod { private: //Rabo4ie massivi amplitud v metode int A1[g_MAX_PADS]; int A2[g_MAX_PADS]; //Massiv aktivnosti 94eek; S[i]=1 esli g_AplitudesArray[i] > g_MIN_AMPLITUDE bool S[g_MAX_PADS]; public: //Rabo4ii massiv nomerov 94eek v metode int numbersOfPads[g_MAX_PADS]; //Koordinati centrov klasterov float xc[g_MAX_CENTERS], yc[g_MAX_CENTERS]; //Amplitudi klasterov float clusterAmlitudes[g_MAX_CENTERS]; //Koli4estvo naidennih klasterov int klastersInMethod; //Nomera klasterov int numbersOfClusters[g_MAX_CENTERS]; NewMethod() { for(int i = 0; i < g_MAX_PADS; i++) { A1[i] = 0; A2[i] = 0; numbersOfPads[i] = 0; S[i] = 0; } for(int i = 0; i < g_MAX_CENTERS; i++) { xc[i] = 0; yc[i] = 0; clusterAmlitudes[i] = 0; numbersOfClusters[i] = 0; } } //---Polu4enie dannih iz globalnih massivov--- void NewMethodCreateData() { for(int i = 0; i < g_MAX_PADS; i++) { A1[i] = g_AmplitudesArray[i]; A2[i] = g_AmplitudesArray[i]; numbersOfPads[i] = g_ClustersArray[i]; if(g_AmplitudesArray[i] > 0)S[i] = 1; } klastersInMethod = 0; for(int i = 0; i < g_MAX_CENTERS; i++) { xc[i] = 0; yc[i] = 0; clusterAmlitudes[i]=0; numbersOfClusters[i]=0; } } //------------------------ //---TEST---//VREMENNO--- void TEST() { /*cout< g_MIN_AMPLITUDE) && (numbersOfPads[n] > 0)) { //Prisvoenie 94eikoi sebe nomera lokal'nogo maximuma numberOfLocalMaximum = n; //Opredelenie novogo lokal'nogo maximuma sredi sosedei for(int j = 1; j <= PT[n].Nsmax; j++) { if(A1[PT[n].Ns[j]] > A1[numberOfLocalMaximum]) { numberOfLocalMaximum = PT[n].Ns[j]; } } k = A2[n]; //Perestroenie matritsi amplitud A2[numberOfLocalMaximum] += A1[n]; //Ymen'shenie 4isla klasterov if(n != numberOfLocalMaximum) { A2[n] = k; klastersInMethod--; //Ob'edinenie klasterov k = numbersOfPads[n]; for(int j = 1; j <= g_MaxPads; j++) { if(numbersOfPads[j] == k) { numbersOfPads[j] = numbersOfPads[numberOfLocalMaximum]; } } } } /* Perestroika matritsi amplitud vo vrem9 raboti algoritma * TRUE - mnogo prisoedinenii uvili4ivayt klaster * FALSE - bol'shoi tsentr mass uvili4ivart klaster */ if(version == true) { for(int i = 1; i <= g_MaxPads; i++) { A1[i] = A2[i]; } } } //Vistraivanie klasterov po por9dku /* Nomera 94eek iz massiva numbersOfPads sootvetstvuyt * nomeru klastera iz numbersOfClusters */ int NomCl = 0; int Replase = 0; for(int i = 1; i <= g_MaxPads; i++) { if((A1[i] != 0) && (S[i] == 1)) { Replase = numbersOfPads[i]; NomCl++; for(int j = 1; j <= g_MaxPads; j++) { if((numbersOfPads[j] == Replase) && (g_AmplitudesArray[j] > 0) && (S[j] == 1)) { //Renumerovka klastera i ego 94eek numbersOfPads[j] = NomCl; S[j] = 0; numbersOfClusters[NomCl] = NomCl; //Vichislenie koordinat tsentra klastera Ch1 xc[NomCl] += (PT[j].xc * g_AmplitudesArray[j]); yc[NomCl] += (PT[j].yc * g_AmplitudesArray[j]); clusterAmlitudes[NomCl] += g_AmplitudesArray[j]; } } } } //Vichislenie koordinat tsentra klastera Ch2 for(int i = 1; i <= NomCl; i++) { //-!!!DELENIE!!!- if(clusterAmlitudes[i] == 0) { cout<<"DELENIE NA NULL"; break; } xc[i] = xc[i] / clusterAmlitudes[i]; yc[i] = yc[i] / clusterAmlitudes[i]; } klastersInMethod = NomCl; } //-------------------------- //---Vivod rezultatov //PROSTOY void ResultText() { FILE* fNet; fNet = fopen("/home/kozlov/workspace/Clastering1/src/resultMy.txt", "w"); for(int i = 1; i <= klastersInMethod; i++) { fprintf(fNet, "%d %.3f %.3f\n", numbersOfClusters[i], xc[i], yc[i]); } fclose(fNet); } //------------ }; //--------------------------------------------------------------- //---Realization of Single Linkage method //PROVERENO------------ class SingleLinkageMethod { private: //Rabo4ii massiv amplitud v metode int A1[g_MAX_PADS]; //Massiv aktivnosti 94eek; S[i]=1 esli g_AplitudesArray[i] > g_MIN_AMPLITUDE bool S[g_MAX_PADS]; //Rabi4ii massiv nomerov 94eek v metode int numbersOfPads[g_MAX_PADS]; //Informatsi9 o klasterah float xc[g_MAX_CENTERS], yc[g_MAX_CENTERS], clusterAmlitudes[g_MAX_CENTERS]; int clustersInMethod; //Nomera klasterov int numbersOfClusters[g_MAX_CENTERS]; public: //Konstructor klassa SingleLinkageMethod() { for(int i = 0; i < g_MAX_PADS; i++) { A1[i] = 0; numbersOfPads[i] = 0; S[i] = 0; } for(int i = 0; i < g_MAX_CENTERS; i++) { xc[i] = 0; yc[i] = 0; clusterAmlitudes[i] = 0; numbersOfClusters[i] = 0; } } //Zagruzka dannih v klass void SingleLinkageCreate() { for(int i = 0; i < g_MAX_PADS; i++) { A1[i] = g_AmplitudesArray[i]; numbersOfPads[i] = g_ClustersArray[i]; if(g_AmplitudesArray[i] > 0) { S[i] = 1; } } clustersInMethod = 0; for(int i = 0; i < g_MAX_CENTERS; i++) { xc[i] = 0; yc[i] = 0; clusterAmlitudes[i] = 0; numbersOfClusters[i] = 0; } } //---TEST---//VREMENNO--- void TEST() { cout< 0) && (S[i] == 1)) { SLRec(PT[i].N); } } //Povtorna9 aktivizatsi9 94eek for(int i = 1; i <= g_MaxPads; i++) { if(g_AmplitudesArray[i] > 0) { S[i] = 1; } } //Vistraivanie klasterov po por9dku /* Nomera 94eek iz massiva numbersOfPads sootvetstvuyt * nomeru klastera iz numbersOfClusters */ int NomCl = 0; int Replase = 0; for(int i = 1; i <= g_MaxPads; i++) { if((g_AmplitudesArray[i] != 0) && (S[i] == 1)) { Replase = numbersOfPads[i]; NomCl++; for(int j = 1; j <= g_MaxPads; j++) { if((numbersOfPads[j] == Replase) && (g_AmplitudesArray[j] > 0) && (S[j] == 1)) { //Renumerovka klastera i ego 94eek numbersOfPads[j] = NomCl; S[j] = 0; numbersOfClusters[NomCl]=NomCl; //Vichislenie koordinat tsentra klastera Ch1 xc[NomCl] += (PT[j].xc * g_AmplitudesArray[j]); yc[NomCl] += (PT[j].yc * g_AmplitudesArray[j]); clusterAmlitudes[NomCl] += g_AmplitudesArray[j]; } } } } for(int i = 1; i <= NomCl; i++) { //-!!!DELENIE!!!- if(clusterAmlitudes[i] == 0) { cout<<"DELENIE NA NULL"; break; } xc[i] = xc[i] / clusterAmlitudes[i]; yc[i] = yc[i] / clusterAmlitudes[i]; } clustersInMethod = NomCl; } //---Vivod rezultatov //PROSTOY void ResultText() { FILE *fNet; fNet=fopen("/home/kozlov/workspace/Clastering1/src/resultSL.txt", "w"); for(int i = 1; i <= clustersInMethod; i++) { fprintf(fNet, "%d %.3f %.3f\n", numbersOfPads[i], xc[i], yc[i]); } fclose(fNet); } //------------ }; //------------------------------------------------------ //---Reaalization of Ward's method const int g_ward_MAX_NEIGHBORS=50; const int g_ward_MAX_CENTERS=10000; class WardMethod { private: struct Cluster { //Nomera sisedei klastera int numbersOfNeighbors[g_ward_MAX_NEIGHBORS]; //Koli4estvo sosedei klastera int maxNumberOfNeighbors; //Koli4estvo klasterov int numberOfCluster; //Amplituda klastera float A; //Koordinati tsentra klastera float xc, yc; //Rassto9ni9 mejdu klasterami float W[g_ward_MAX_NEIGHBORS]; bool S[g_ward_MAX_NEIGHBORS]; //Nomera 94eek v klastere int numbersOfPadsInCluster[g_ward_MAX_NEIGHBORS]; //Koli4estvo 94eek v klastere int padsInCluster; }; Cluster Clusters[g_ward_MAX_CENTERS]; int clustersInMethod; int clustersInMethod_2; //Massiv neobrabotannih 94eek bool wardActivePads[g_MAX_PADS]; //Pervii element bloka obrabativaemih dannih int firstBlockElement; public: //Ronstruktor klassa WardMethod() { for(int i = 0; i < g_ward_MAX_CENTERS; i++) { Clusters[i].maxNumberOfNeighbors = 0; Clusters[i].padsInCluster = 0; Clusters[i].xc = 0; Clusters[i].yc = 0; Clusters[i].A = 0; Clusters[i].numberOfCluster = 0; for(int j = 0; j < g_ward_MAX_NEIGHBORS; j++) { Clusters[i].numbersOfNeighbors[j] = 0; Clusters[i].W[j] = 0; Clusters[i].S[j] = 0; Clusters[i].numbersOfPadsInCluster[j] = 0; } } clustersInMethod = 0; clustersInMethod_2 = 0; firstBlockElement = 0; //Novii blok na4inaets9 so sleduushego elementa for(int i = 0; i < g_MAX_PADS; i++) { if(g_AmplitudesArray[i] > g_MIN_AMPLITUDE) { wardActivePads[i] = true; } else { wardActivePads[i] = false; } } } //------------------------------------------------------ //Ras4et rassto9ni9 mejdu klasterami float WardDistance(int n1, int n2) { return (((Clusters[n1].A * Clusters[n2].A) * ((Clusters[n1].xc - Clusters[n2].xc) * (Clusters[n1].xc - Clusters[n2].xc) + (Clusters[n1].yc - Clusters[n2].yc) * (Clusters[n1].yc - Clusters[n2].yc))) / (Clusters[n1].A + Clusters[n2].A)); } //------------------------------------------------------ //------------------------------------------------------ //Zagruzka dannih v klass (odino4na9) void WardCreate() { int clusterNumber = 0; for(int i = 1; i < g_MAX_PADS; i++) { //Initsiatsi9 aktivnih 94eek if(g_AmplitudesArray[i] > 0) { clusterNumber++; Clusters[clusterNumber].maxNumberOfNeighbors = PT[i].Nsmax; Clusters[clusterNumber].padsInCluster = 1; Clusters[clusterNumber].numbersOfPadsInCluster[1] = i; Clusters[clusterNumber].numberOfCluster = i; Clusters[clusterNumber].A = g_AmplitudesArray[i]; Clusters[clusterNumber].xc = PT[i].xc; Clusters[clusterNumber].yc = PT[i].yc; } } clustersInMethod = clusterNumber; clustersInMethod_2 = clustersInMethod; //Opredelenie sosedei dl9 vseh 94eek-klasterov //Vipoln9ets9 posle opredeleni9 vseh nomerov klasterov v klasse int neighbor = 0; for(int i = 1; i <= clustersInMethod; i++) { neighbor = 0; for(int j = 1; j <= clustersInMethod; j++) { for(int k = 1; k <= Clusters[i].maxNumberOfNeighbors; k++) { if(PT[Clusters[i].numberOfCluster].Ns[k] == Clusters[j].numberOfCluster) { neighbor++; Clusters[i].numbersOfNeighbors[neighbor] = j; } } } } //Vi4islenie rassto9nii mejdu sosed9mi for(int i = 1; i <= clustersInMethod; i++) { for(int j = 1; j <= Clusters[i].maxNumberOfNeighbors; j++) { Clusters[i].W[j] = WardDistance(i, Clusters[i].numbersOfNeighbors[j]); //Aktivizatsi9 rassto9niz mejdu sosed9mi Clusters[i].S[j] = 1; } } } //-----Poblo4na9 zagruzka dannih----- //Recursive function int WardBlockCreateStep(int wardStep, int wardStepRec, int AddedPad) { //Proverka previsheni9 limita obrabotki za 1 shag if(wardStepRec >= g_ward_MAX_CENTERS) { return 0; } int tempPad = AddedPad; if(PT[AddedPad].Nsmax > 0) { for(int i = 1; i <= PT[AddedPad].Nsmax; i++) { wardStepRec = WardBlockCreateStep(wardStep, wardStepRec, PT[AddedPad].Ns[i]); //Proverka previsheni9 limita obrabotki dl9 rekursii if(wardStepRec == 0) { return 0; } } } //Proverka previsheni9 limita obrabotki za 1 shag if(wardStepRec >= g_ward_MAX_CENTERS) { return 0; } //Esli nabor 94eek mojet bit' dobavlen v spisok obrabotki wardStep++; wardStepRec = wardStep; //Dobavlenie 94eiki v spisok obrabotki clustersInMethod = wardStep; clustersInMethod_2 = clustersInMethod; Clusters[wardStep].maxNumberOfNeighbors = PT[tempPad].Nsmax; Clusters[wardStep].padsInCluster = 1; Clusters[wardStep].numbersOfPadsInCluster[1] = tempPad; Clusters[wardStep].numberOfCluster = tempPad; Clusters[wardStep].A = g_AmplitudesArray[tempPad]; Clusters[wardStep].xc = PT[tempPad].xc; Clusters[wardStep].yc = PT[tempPad].yc; //Yda4noe zavershenie rekursivnoi funktsii return wardStepRec; } //Main function int WardBlockCreate(int wardStepStart) { //Flag zaversheni9 postroeni9 spiska obrabotki bool workListFinished = false; //Poslednii element spiska 94eek, vnesennii v spisok obrabotki ---!!!--- int wardStepFinish = 0; //Nomer dobavl9emoi 94eiki int nomActivePad = 0; //Nomer poslednei dobavlennoi v spisok obrabotki 94eiki int lastActivePad = firstBlockElement; //do{ do{ lastActivePad++; if(wardActivePads[lastActivePad] > g_MIN_AMPLITUDE) { nomActivePad = lastActivePad; } }while((nomActivePad == 0)&&(lastActivePad < g_MAX_PADS)); //}while(!workListFinished); return wardStepFinish; //--!!!--- vozmojno vozvrashat' ne nado } //---------------------------------------------------- //---------------------------------------------------- void DeleteCluaster(int clusterNumber) { //Ydalenie klastera iz spiskov sosedei bool clusterWasDeleted = false; for(int i = 1; i <= Clusters[clusterNumber].maxNumberOfNeighbors; i++) { clusterWasDeleted = false; for(int j = 1; j <= Clusters[Clusters[clusterNumber].numbersOfNeighbors[i]].maxNumberOfNeighbors; j++) { //Sjatie spiskov sosedei klastera s zamesheniem ydal9emogo klastera if(clusterWasDeleted == true) { //Podn9t' nomer soseda v spiske Clusters[Clusters[clusterNumber].numbersOfNeighbors[i]].numbersOfNeighbors[j - 1] = Clusters[Clusters[clusterNumber].numbersOfNeighbors[i]].numbersOfNeighbors[j]; //Opustit' NULL v spiske Clusters[Clusters[clusterNumber].numbersOfNeighbors[i]].numbersOfNeighbors[j] = 0; //Podn9t' rassto9nie v spiske Clusters[Clusters[clusterNumber].numbersOfNeighbors[i]].W[j - 1] = Clusters[Clusters[clusterNumber].numbersOfNeighbors[i]].W[j]; //Opustit' NULL v spiske Clusters[Clusters[clusterNumber].numbersOfNeighbors[i]].W[j] = 0; //Podn9t' flag aktivnosti rassto9ni9 v spiske Clusters[Clusters[clusterNumber].numbersOfNeighbors[i]].S[j - 1] = Clusters[Clusters[clusterNumber].numbersOfNeighbors[i]].S[j]; //Opustit' NULL v spiske Clusters[Clusters[clusterNumber].numbersOfNeighbors[i]].S[j] = 0; } //Dostignut udal9emii klaster v spiske sosedei if(Clusters[Clusters[clusterNumber].numbersOfNeighbors[i]].numbersOfNeighbors[j] == clusterNumber) { clusterWasDeleted = true; } } //Ymen'shenie koli4estva sosedei dlz sosedei ydal9emogo klastera Clusters[Clusters[clusterNumber].numbersOfNeighbors[i]].maxNumberOfNeighbors--; } //O4istka spiska sosedei ydal9emogo klastera for(int i = 1; i <= Clusters[clusterNumber].maxNumberOfNeighbors; i++) { Clusters[clusterNumber].numbersOfNeighbors[i] = 0; Clusters[clusterNumber].W[i] = 0; Clusters[clusterNumber].S[i] = 0; } //Ydalenie klastera for(int i = 1; i <= Clusters[clusterNumber].padsInCluster; i++) { Clusters[clusterNumber].numbersOfPadsInCluster[i] = 0; } Clusters[clusterNumber].padsInCluster = 0; Clusters[clusterNumber].maxNumberOfNeighbors = 0; Clusters[clusterNumber].numberOfCluster = 0; Clusters[clusterNumber].A = 0; Clusters[clusterNumber].xc = 0; Clusters[clusterNumber].yc = 0; } //--------------------------------------------------- //--------------------------------------------------- void WardDistanceRecalculation(int clusterNumber) { float newDistance; //Ydalenie klastera iz sobstvennogo spiska sosedei for(int i = 1; i <= Clusters[clusterNumber].maxNumberOfNeighbors; i++) { if(Clusters[clusterNumber].numbersOfNeighbors[i] == clusterNumber) { for(int j = i; j < Clusters[clusterNumber].maxNumberOfNeighbors; j++) { Clusters[clusterNumber].numbersOfNeighbors[j] = Clusters[clusterNumber].numbersOfNeighbors[j+1]; Clusters[clusterNumber].S[j] = Clusters[clusterNumber].S[j+1]; } //Yni4tojenie poslednego soseda posle sdviga massiva Clusters[clusterNumber].numbersOfNeighbors[Clusters[clusterNumber].maxNumberOfNeighbors] = 0; Clusters[clusterNumber].S[Clusters[clusterNumber].maxNumberOfNeighbors] = 0; Clusters[clusterNumber].maxNumberOfNeighbors--; } } //Ras4et novih rassto9nii dl9 vseh sosedei for(int i = 1; i <= Clusters[clusterNumber].maxNumberOfNeighbors; i++) { newDistance = WardDistance(clusterNumber, Clusters[clusterNumber].numbersOfNeighbors[i]); Clusters[clusterNumber].W[i] = newDistance; //Ystanovka rassto9nii sosed9m for(int j = 1; j <= Clusters[Clusters[clusterNumber].numbersOfNeighbors[i]].maxNumberOfNeighbors; j++) { if(Clusters[Clusters[clusterNumber].numbersOfNeighbors[i]].numbersOfNeighbors[j] == clusterNumber) { Clusters[Clusters[clusterNumber].numbersOfNeighbors[i]].W[j] = newDistance; } } } } //---------------------------------------------------- float XCenterRecalculation(int cl1, int cl2) { return (Clusters[cl1].xc * Clusters[cl1].A + Clusters[cl2].xc * Clusters[cl2].A) / (Clusters[cl1].A + Clusters[cl2].A); } float YCenterRecalculation(int cl1, int cl2) { return (Clusters[cl1].yc * Clusters[cl1].A + Clusters[cl2].yc * Clusters[cl2].A) / (Clusters[cl1].A + Clusters[cl2].A); } //---------------------------------------------------- void WardProcessingData(int maxDistance) { float minimalDistance = maxDistance; int cluster1 = 0, cluster2 = 0; do{ minimalDistance = maxDistance + 1; //Proverka nali4i9 ob'edin9emih klasterov if(clustersInMethod == 1) { break; } //Nahojdenie minimal'nogo Wardovskogo rassto9ni9 for(int i = 1; i <= clustersInMethod; i++) { for(int j = 1; j <= Clusters[i].maxNumberOfNeighbors; j++) { /* Inogda popadauts9 W == 0 * Nedo4et v rabote metodov udaleni9 i peres4eta * Ne vli9et na itogovii rezultat */ if((Clusters[i].W[j] < minimalDistance) && (Clusters[i].W[j] > 0)) { minimalDistance = Clusters[i].W[j]; cluster1 = i; cluster2 = Clusters[i].numbersOfNeighbors[j]; } } } //Prekreshenie raboti po predel'nomu rassto9niu if(minimalDistance >= maxDistance)break; //Vibor glavnogo klastera pri ob'edinenii if(cluster1 > cluster2) { int k = cluster1; cluster1 = cluster2; cluster2 = k; } //Sbros aktivnosti prisoedin9emogo klastera, //Esli oni dubliryut sv9zi glavnogo klastera for(int i = 1; i <= Clusters[cluster1].maxNumberOfNeighbors; i++) { for(int j = 1; j <= Clusters[cluster2].maxNumberOfNeighbors; j++) { if(Clusters[cluster1].numbersOfNeighbors[i] == Clusters[cluster2].numbersOfNeighbors[j]) { Clusters[cluster2].S[j] = 0; } } } //Pereda4a sosedei s aktivnimi sv9z9mi glavnomy klasteru for(int i = 1; i <= Clusters[cluster2].maxNumberOfNeighbors; i++) { if(Clusters[cluster2].S[i] == 1) { Clusters[cluster1].maxNumberOfNeighbors++; Clusters[cluster1].numbersOfNeighbors[Clusters[cluster1].maxNumberOfNeighbors] = Clusters[cluster2].numbersOfNeighbors[i]; Clusters[cluster1].S[Clusters[cluster1].maxNumberOfNeighbors] = 1; } } //Pereda4a 94eek glavnomu klasteru for(int i = 1; i <= Clusters[cluster2].padsInCluster; i++) { Clusters[cluster1].padsInCluster++; Clusters[cluster1].numbersOfPadsInCluster[Clusters[cluster1].padsInCluster] = Clusters[cluster2].numbersOfPadsInCluster[i]; } //Vi4islenie stentra novogo klastera Clusters[cluster1].xc = XCenterRecalculation(cluster1, cluster2); Clusters[cluster1].yc = YCenterRecalculation(cluster1, cluster2); //Zamena prisoedin9emogo klastera na novii v spiskah sosedei drugih klasterov bool thereIsNewCluaster; for(int i = 1; i <= Clusters[cluster2].maxNumberOfNeighbors; i++) { thereIsNewCluaster = false; for(int j = 1; j <= Clusters[Clusters[cluster2].numbersOfNeighbors[i]].maxNumberOfNeighbors; j++) { //Esli v spiskah sosedei yje est' novii klaster if(Clusters[Clusters[cluster2].numbersOfNeighbors[i]].numbersOfNeighbors[j] == cluster1) { thereIsNewCluaster = true; } } //Dobavlenie novogo klastera v spiski sosedei sosedei prisoedin9emogo klastera if(thereIsNewCluaster == false) { Clusters[Clusters[cluster2].numbersOfNeighbors[i]].maxNumberOfNeighbors++; Clusters[Clusters[cluster2].numbersOfNeighbors[i]].numbersOfNeighbors[Clusters[Clusters[cluster2].numbersOfNeighbors[i]].maxNumberOfNeighbors] = cluster1; } } //Vi4islenie amplitudi novogo klastera Clusters[cluster1].A = Clusters[cluster1].A+Clusters[cluster2].A; //Ydalenie prisoedinennogo klastera DeleteCluaster(cluster2); //Peres4et rassto9nii dl9 novogo klastera WardDistanceRecalculation(cluster1); clustersInMethod--; }while(minimalDistance < maxDistance); //Yplotnenie massiva klasterov for(int i = 1; i < clustersInMethod_2; i++) { if(Clusters[i].A == 0) { for(int j = i; j < clustersInMethod_2; j++) { Clusters[j].A = Clusters[j + 1].A; Clusters[j].padsInCluster = Clusters[j + 1].padsInCluster; Clusters[j].numberOfCluster = Clusters[j + 1].numberOfCluster; Clusters[j].maxNumberOfNeighbors = Clusters[j + 1].maxNumberOfNeighbors; Clusters[j].xc = Clusters[j + 1].xc; Clusters[j].yc = Clusters[j + 1].yc; //Perenos nomerov sosedei for(int k = 1; k <= Clusters[j + 1].maxNumberOfNeighbors; k++) { Clusters[j].numbersOfNeighbors[k] = Clusters[j + 1].numbersOfNeighbors[k]; Clusters[j].W[k] = Clusters[j + 1].W[k]; } //Perenos nomerov 94eek v klastere for(int k = 1; k <= Clusters[j + 1].padsInCluster; k++) { Clusters[j].numbersOfPadsInCluster[k] = Clusters[j+1].numbersOfPadsInCluster[k]; } } } } /* Dopolnitel'noe obnulenie udalennih elementov * massiva klasterov ne vipoln9los', poskol'ky * oni doljni bit' obnuleni pri udalenii * prisoedin9emih klasterov */ } //---------------------------------------------------- //---TEST--- void TEST() { cout<<"nClw="<0){ Cl[iter].nomCl=g_ClustersArray[i]; Cl[iter].A=g_AmplitudesArray[i]; Cl[iter].xc=PT[i].xc; Cl[iter].yc=PT[i].yc; //cout<<"\nNmet="<0)) { for(int i=1; i<=PT[toOriginalNCl[i1]].Nsmax; i++){ if((S_in[OriginalNCl[PT[toOriginalNCl[i1]].Ns[i]]]==0)&& (S_out[OriginalNCl[PT[toOriginalNCl[i1]].Ns[i]]]==1)){ Dist=Distance(i1, OriginalNCl[PT[toOriginalNCl[i1]].Ns[i]]); if(Dist0)) { S_out[i]=1; } } } //-------Recursive function END--------------------- //-------Building clasters from links--------------- void ClusterBuildStep(int i1, int i2, int nC) { //S_in[i2]=0; //Cl[i2].nomCl=nC; g_ClustersArray[i2]=nC; for(int i=1; i0) { if((Links[i].n1==i2)||(Links[i].n2==i2)) { if((S_in[Links[i].n1]==1)||(S_in[Links[i].n2]==1)) { S_in[i1]=0; S_in[i2]=0; Cl[i2].nomCl=0; if(i1!=i2) { Cl[i1].A+=Cl[i2].A; Cl[i2].A=0; } Cl[i1].xc=(Cl[i1].xc+Cl[i2].xc)/2; Cl[i1].yc=(Cl[i1].yc+Cl[i2].yc)/2; Cl[i2].xc=0; Cl[i2].yc=0; if(Links[i].n1==i2) { ClusterBuildStep(i1, Links[i].n2, nC); } else { ClusterBuildStep(i1, Links[i].n1, nC); } } } } } Cl[i1].nomCl=nC; S_in[i1]=0; } void ClusterBuild() { int nCm=nomCl_max; for(int i=1; i<=g_MaxWorkingPads; i++) { if(Cl[i].A>0) { S_in[i]=1; } } int nomClust=1; for(int i=1; i<=g_MaxWorkingPads; i++) { if(S_in[i]==1) { Cl[i].nomCl=nomClust; ClusterBuildStep(i, i, nomClust); nomClust++; } } nomCl_max=nomClust-1; for(int i=1; i<=nCm; i++) { if(Cl[i].nomCl==0) { for(int j=i; j<=nCm; j++) { Cl[j].A=Cl[j+1].A; Cl[j].nomCl=Cl[j+1].nomCl; Cl[j].xc=Cl[j+1].xc; Cl[j].yc=Cl[j+1].yc; Cl[j+1].A=0; Cl[j+1].nomCl=0; Cl[j+1].xc=0; Cl[j+1].yc=0; } if(Cl[i].nomCl==0) { i--; } nCm--; } } } //-------Building clasters from links END----------- //-------Link creation with recursion--------------- void MinDendroLinking() { int it=0; do{ it++; }while(S_in[it]!=1); LinkingStep(it, 0); for(int i=1; iMaxDist) { Links[i].R=0; Links[i].n1=0; Links[i].n2=0; link_iter--; } } RecalcLinks(li); ClusterBuild(); } //-------MinDendro main method END------------------ //---FULL LINKED--- //-------Recursive function------------------------- void FullLinkedStep(int i1, float MaxDist) { float Dist; //S_in[i1]=0; for(int i=1; i<=PT[toOriginalNCl[i1]].Nsmax; i++) { if(S_in[OriginalNCl[PT[toOriginalNCl[i1]].Ns[i]]]==1) { Dist=Distance(i1, OriginalNCl[PT[toOriginalNCl[i1]].Ns[i]]); if(Dist0){ for(int i=1; i<=PT[toOriginalNCl[i1]].Nsmax; i++) { Dist+=Distance(i1, OriginalNCl[PT[toOriginalNCl[i1]].Ns[i]]); O++; }}} Dist=Dist/O; int D1=(int)Dist; for(int i=1; i "<