public EMD() { X = new Node2Content[MAX_SIG_SIZE]; for (var i = 0; i < X.Length; i++) { X[i] = new Node2Content(); X[i].Pos = i; } rowsX = new Node2Content[MAX_SIG_SIZE]; for (var i = 0; i < rowsX.Length; i++) { rowsX[i] = new Node2Content(); rowsX[i].Pos = i; rowsX[i].LastNode = true; } colsX = new Node2Content[MAX_SIG_SIZE]; for (var i = 0; i < colsX.Length; i++) { colsX[i] = new Node2Content(); colsX[i].Pos = i; colsX[i].LastNode = true; } }
/// <param name="minI"> /// </param> /// <param name="minJ"> /// </param> /// <param name="prevUMinI"> /// </param> /// <param name="prevVMinJ"> /// </param> /// <param name="headU"> /// </param> private void addBasicVariable(int minI, int minJ, double[] s, double[] d, Node1Content prevUMinI, Node1Content prevVMinJ, Node1Content headU) { // TODO Auto-generated method stub double t; //passaggi per associare i nuovi valori agli array s e d if (System.Math.Abs(s[minI] - d[minJ]) <= EPSILON * maxW) { t = s[minI]; s[minI] = 0; d[minJ] = d[minJ] - t; } else { if (s[minI] < d[minJ]) { t = s[minI]; s[minI] = 0; d[minJ] = d[minJ] - t; } else { t = d[minJ]; d[minJ] = 0; s[minI] = s[minI] - t; } } isX[minI][minJ] = 1; endx.Val = t; endx.I = minI; endx.J = minJ; endx.NC = rowsX[minI]; endx.NR = colsX[minJ]; rowsX[minI] = endx; colsX[minJ] = endx; endx = X[endx.Pos + 1]; if ((s[minI] == 0) && (headU.getNext().getNext().IsLast != true)) { prevUMinI.setNext(prevUMinI.getNext().getNext()); } else { prevVMinJ.setNext(prevVMinJ.getNext().getNext()); } }
/// <param name="s1"> /// </param> /// <param name="s2"> /// </param> /// <returns> /// </returns> /// <throws> SignatureSizeException </throws> private double init(Signature s1, Signature s2, double[][] Dist) { int i, j; double sSum, dSum, diff; //n1 e n2 prendono la dimensione delle signature ( numero di cluster) n1 = s1.N; n2 = s2.N; isX = new int[MAX_SIG_SIZE1][]; for (var i2 = 0; i2 < MAX_SIG_SIZE1; i2++) { isX[i2] = new int[MAX_SIG_SIZE1]; } //creo una matrice n1xn2 per contenere i costi costMatrix = new float[MAX_SIG_SIZE1][]; for (var i3 = 0; i3 < MAX_SIG_SIZE1; i3++) { costMatrix[i3] = new float[MAX_SIG_SIZE1]; } //creo due array s = new double[MAX_SIG_SIZE1]; d = new double[MAX_SIG_SIZE1]; //se il numero dei cluster delle signature � maggiore di MAX_SIG_SIZE1 //lancio un'eccezione if ((n1 > MAX_SIG_SIZE1) || (n2 > MAX_SIG_SIZE1)) { throw new SignatureSizeException(); } maxC = 0.0f; //per ogni i (da 0 a n1-1) ovvero per il numero di cluster della prima signature for (i = 0; i < n1; i++) { //per ogni j (da 0 a n2-1) ovvero per il numero di cluster della seconda signature for (j = 0; j < n2; j++) { //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'" costMatrix[i][j] = (float) Dist[i][j]; //assegno a maxC il valore piu' grande della costMatrix if (costMatrix[i][j] > maxC) { maxC = costMatrix[i][j]; } } } var nodenull = new Node2Content(); nodenull.LastNode = true; //Inizializzo a 0.0f sSum sSum = 0.0f; //per ogni cluster della signature 1 assegno ad s[i] il peso associato al cluster i-esimo // e sSum prende la somma di tutti i pesi; for (i = 0; i < n1; i++) { s[i] = s1.getWeight(i); sSum = sSum + s[i]; // rowsX[i] = null; } //Inizializzo a 0.0f dSum dSum = 0.0f; //per ogni cluster della signature 2 assegno ad d[j] il peso associato al cluster j-esimo // e dSum prende la somma di tutti i pesi; for (j = 0; j < n2; j++) { d[j] = s2.getWeight(j); dSum = dSum + d[j]; // colsX[j]=null; } // la variabile diff prende la differenza delle somme dei pesi (tot) della signature1 e signature2 diff = sSum - dSum; if ((System.Math.Abs(diff)) >= (EPSILON * sSum)) { if (diff < 0.0f) { //per ogni cluster della signature2 costMatrix n1-j prende 0 for (j = 0; j < n2; j++) { costMatrix[n1][j] = 0; } s[n1] = - diff; rowsX[n1] = nodenull; n1++; } else { //per ogni cluster della signature1 costMatrix n2-j prende 0 for (i = 0; i < n1; i++) { costMatrix[i][n2] = 0; } d[n2] = diff; colsX[n2] = nodenull; n2 = n2 + 1; } } //Inizializzo a 0 tutto l'array bidimensionale n1xn2 isX for (i = 0; i < n1; i++) { for (j = 0; j < n2; j++) { isX[i][j] = 0; } } endx = X[0]; //assegno a maxW il maggiore tra il totale dei pesi tra la signature1 e signature2 maxW = sSum > dSum?sSum:dSum; //chiamo la funzione russel russel(s, d); // _EnterX = _EndX++; /* AN EMPTY SLOT (ONLY _n1+_n2-1 BASIC VARIABLES) */ enterX = X[endx.Pos]; endx = X[endx.Pos + 1]; //ritorno il minimo tra le somme dei pesi tra la signature1 e signature2 return sSum > dSum?dSum:sSum; }
/// <param name="loop"> /// </param> /// <returns> /// </returns> /// <throws> FindLoopException </throws> private int findLoop(Node2Content[] loop) { int i, steps; Node2Content newX; Node2Content curX; int[] isUsed; var pos = 0; isUsed = new int[2 * MAX_SIG_SIZE1]; for (i = 0; i < n1 + n2; i++) { isUsed[i] = 0; } curX = loop[0] = enterX; // curX=enterX; newX = curX; isUsed[enterX.Pos] = 1; steps = 1; do { // printArray(loop,steps); if (steps % 2 == 1) { newX = rowsX[newX.I]; // newX.setPos(pos); while ((newX.IsLast != true) && (isUsed[newX.Pos] != 0)) { newX = newX.NC; } } else { newX = colsX[newX.J]; // newX.setPos(pos); while ((newX.IsLast != true) && (isUsed[newX.Pos] != 0) && (!(newX.Equals(enterX)))) { newX = newX.NR; } if (newX.Equals(enterX)) { break; } } if (!newX.IsLast) { loop[pos + 1] = newX; curX = loop[pos + 1]; pos++; isUsed[newX.Pos] = 1; steps = steps + 1; } else { do { newX = curX; do { if (steps % 2 == 1) { newX = newX.NR; } else { newX = newX.NC; } } while ((newX.IsLast != true) && (isUsed[newX.Pos] != 0)); if (newX.IsLast == true) { isUsed[curX.Pos] = 0; curX = loop[pos - 1]; pos--; steps = steps - 1; } } while ((newX.IsLast == true) && (pos >= 0)); isUsed[curX.Pos] = 0; curX = loop[pos] = newX; isUsed[newX.Pos] = 1; } } while (pos >= 0); if (pos == 0) { throw new FindLoopException(); } return steps; }
private void printArray(Node2Content[] loop, int steps) { System.Console.Out.Write("Loop= {"); for (var i = 0; i < steps; i++) { System.Console.Out.Write("( "); System.Console.Out.Write(loop[i].I); System.Console.Out.Write(" "); System.Console.Out.Write(loop[i].J); System.Console.Out.Write(" "); System.Console.Out.Write(loop[i].Val); System.Console.Out.Write(" )"); } System.Console.Out.WriteLine("}"); }
/// <throws> FindLoopException </throws> /// <summary> /// </summary> private void newSol() { int i, j, k; double xMin; int steps; Node2Content[] Loop; Node2Content curX, leaveX = null; i = enterX.I; j = enterX.J; isX[i][j] = 1; enterX.NC = rowsX[i]; enterX.NR = colsX[j]; enterX.Val = 0; rowsX[i] = enterX; colsX[j] = enterX; Loop = new Node2Content[MAX_SIG_SIZE1]; for (i = 0; i < n1 + n2; i++) { Loop[i] = new Node2Content(); Loop[i].Pos = i; } steps = findLoop(Loop); xMin = INFINITY; for (k = 1; k < steps; k = k + 2) { if (Loop[k].Val < xMin) { leaveX = Loop[k]; xMin = Loop[k].Val; } } for (k = 0; k < steps; k = k + 2) { Loop[k].Val = Loop[k].Val + xMin; Loop[k + 1].Val = Loop[k + 1].Val - xMin; } i = leaveX.I; j = leaveX.J; isX[i][j] = 0; if (rowsX[i].Equals(leaveX)) { rowsX[i] = leaveX.NC; } else { for (curX = rowsX[i]; curX.IsLast != true; curX = curX.NC) { if (curX.NC.Equals(leaveX)) { curX.NC = curX.NC.NC; break; } } } if (colsX[j].Equals(leaveX)) { colsX[j] = leaveX.NR; } else { for (curX = colsX[j]; curX.IsLast != true; curX = curX.NR) { if (curX.NR.Equals(leaveX)) { curX.NR = curX.NR.NR; break; } } } enterX = leaveX; }