/// <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="S"> /// </param> /// <param name="D"> /// </param> private void russel(double[] S, double[] D) { int i, j, found, minI = 0, minJ = 0; int lastCurU, lastCurV; double deltaMin, oldVal, diff; var delta = new double[n1][]; for (var i2 = 0; i2 < n1; i2++) { delta[i2] = new double[n2]; } Node1Content[] ur, vr; Node1Content n1c, prevU, prevV, curU, curV, headU = new Node1Content(), headV = new Node1Content(), remember = null, prevUMinI = null, prevVMinJ = null; ur = new Node1Content[MAX_SIG_SIZE1]; for (i = 0; i < ur.Length; i++) { ur[i] = new Node1Content(); ur[i].Pos = i; } headU.setNext(ur[0]); curU = ur[0]; for (i = 0; i < n1; i++) { curU.I = i; curU.Val = - INFINITY; curU.setNext(ur[curU.Pos + 1]); curU = ur[curU.Pos + 1]; } curU.LastNode = true; vr = new Node1Content[MAX_SIG_SIZE1]; for (i = 0; i < vr.Length; i++) { vr[i] = new Node1Content(); vr[i].Pos = i; } headV.setNext(vr[0]); curV = vr[0]; for (j = 0; j < n2; j++) { curV.I = j; curV.Val = - INFINITY; curV.setNext(vr[curV.Pos + 1]); curV = vr[curV.Pos + 1]; } curV.LastNode = true; for (i = 0; i < n1; i++) { for (j = 0; j < n2; j++) { float v; v = costMatrix[i][j]; if (ur[i].Val <= v) ur[i].Val = v; if (vr[j].Val <= v) vr[j].Val = v; } } // vr[n2].setLastNode(true); // ur[n1].setLastNode(true); for (i = 0; i < n1; i++) { for (j = 0; j < n2; j++) { delta[i][j] = costMatrix[i][j] - ur[i].Val - vr[j].Val; } } do { found = 0; deltaMin = INFINITY; prevU = headU; for (curU = headU.getNext(); curU.IsLast != true; curU = curU.getNext()) { int u; u = curU.I; prevV = headV; for (curV = headV.getNext(); curV.IsLast != true; curV = curV.getNext()) { var v = curV.I; if (deltaMin > delta[u][v]) { deltaMin = delta[u][v]; minI = u; minJ = v; prevUMinI = prevU; prevVMinJ = prevV; found = 1; } prevV = curV; } prevU = curU; } if (found == 0) { break; } remember = prevUMinI.getNext(); addBasicVariable(minI, minJ, s, d, prevUMinI, prevVMinJ, headU); if (remember.Equals(prevUMinI.getNext())) { for (curV = headV.getNext(); curV.IsLast == false; curV = curV.getNext()) { var v = curV.I; if (curV.Val == costMatrix[minI][v]) { oldVal = curV.Val; curV.Val = - INFINITY; for (curU = headU.getNext(); curU.IsLast == false; curU = curU.getNext()) { var u = curU.I; if (curV.Val <= costMatrix[u][v]) { curU.Val = costMatrix[u][v]; } } diff = oldVal - curV.Val; if (System.Math.Abs(diff) < EPSILON * maxC) { for (curU = headU.getNext(); curU.IsLast; curU = curU.getNext()) { delta[curU.I][v] = delta[curU.I][v] + diff; } } } } } else { for (curU = headU.getNext(); curU.IsLast == false; curU = curU.getNext()) { var u = curU.I; if (curU.Val == costMatrix[u][minJ]) { oldVal = curU.Val; curU.Val = - INFINITY; for (curV = headV.getNext(); curV.IsLast == false; curV = curV.getNext()) { var v = curV.I; if (curU.Val <= costMatrix[u][v]) { curU.Val = costMatrix[u][v]; } } diff = oldVal - curU.Val; if (System.Math.Abs(diff) < EPSILON * maxC) { for (curV = headV.getNext(); curV.IsLast == false; curV = curV.getNext()) { delta[u][curV.I] = delta[u][curV.I] + diff; } } } } } } while (headU.getNext().IsLast == false || headV.getNext().IsLast == false); // System.out.println("###############"); // for (int st1=0;st1<n1;st1++){ // for (int st2=0;st2<n2;st2++){ // System.out.print(isX[st1][st2]); // System.out.print(" ");} // System.out.println();} }
/// <param name="U"> /// </param> /// <param name="V"> /// </param> /// <throws> FindBasicVariablesException </throws> private void findBasicVariables(Node1Content[] U, Node1Content[] V) { int i, j, found; int uFoundNum, vFoundNum; Node1Content nodenull, prevU, prevV, curU, curV, u1head, v1head = new Node1Content(), u0head = new Node1Content(), v0head = new Node1Content(); // // System.out.println("###############"); // for (int st1=0;st1<n1;st1++){ // for (int st2=0;st2<n2;st2++){ // System.out.print(isX[st1][st2]); // System.out.print(" ");} // System.out.println();} u0head.setNext(U[0]); curU = U[0]; for (i = 0; i < n1; i++) { curU.I = i; curU.setNext(U[curU.Pos + 1]); curU = U[curU.Pos + 1]; } curU.LastNode = true; nodenull = new Node1Content(); nodenull.LastNode = true; u1head = new Node1Content(); u1head.setNext(nodenull); curV = V[1]; v0head.setNext(n2 > 1?V[1]:nodenull); for (j = 1; j < n2; j++) { curV.I = j; curV.setNext(V[curV.Pos + 1]); curV = V[curV.Pos + 1]; } curV.LastNode = true; v1head.setNext(nodenull); V[0].I = 0; V[0].Val = 0; v1head.setNext(V[0]); v1head.getNext().setNext(nodenull); uFoundNum = 0; vFoundNum = 0; while (uFoundNum < n1 || vFoundNum < n2) { found = 0; if (vFoundNum < n2) { prevV = v1head; for (curV = v1head.getNext(); curV.IsLast != true; curV = curV.getNext()) { j = curV.I; prevU = u0head; for (curU = u0head.getNext(); curU.IsLast != true; curU = curU.getNext()) { i = curU.I; if (isX[i][j] == 1) { curU.Val = costMatrix[i][j] - curV.Val; prevU.setNext(curU.getNext()); curU.setNext(u1head.getNext().IsLast != true?u1head.getNext():nodenull); u1head.setNext(curU); curU = prevU; } else { prevU = curU; } } prevV.setNext(curV.getNext()); vFoundNum = vFoundNum + 1; found = 1; } } if (uFoundNum < n1) { prevU = u1head; for (curU = u1head.getNext(); curU.IsLast != true; curU = curU.getNext()) { i = curU.I; prevV = v0head; for (curV = v0head.getNext(); curV.IsLast != true; curV = curV.getNext()) { j = curV.I; if (isX[i][j] == 1) { curV.Val = costMatrix[i][j] - curU.Val; prevV.setNext(curV.getNext()); curV.setNext(v1head.getNext().IsLast != true?v1head.getNext():nodenull); v1head.setNext(curV); curV = prevV; } else { prevV = curV; } } prevU.setNext(curU.getNext()); uFoundNum = uFoundNum + 1; found = 1; } } if (found == 0) { throw new FindBasicVariablesException(); } } }
/// <param name="s1"> /// </param> /// <param name="s2"> /// </param> /// <returns> /// </returns> /// <throws> SignatureSizeException </throws> /// <throws> FindBasicVariablesException </throws> /// <throws> IsOptimalException </throws> /// <throws> FindLoopException </throws> public virtual float Emd(Signature signature1, Signature signature2, double[][] costMatrix, Flow flow, int flowSize, List<Flow> flowList) { #region Pre-Execution checks if (signature1.N != costMatrix.Length || signature2.N != costMatrix[0].Length) { throw new ArgumentException("The costMatrix is not compatible with the two signature!"); } #endregion int itr; double totalCost; double w; Node2Content xp; Flow[] flowP; Flow flowp; Node1Content[] U, V; // var flowList= new List<flow_t>(); U = new Node1Content[MAX_SIG_SIZE1]; for (var i = 0; i < U.Length; i++) { U[i] = new Node1Content(); U[i].Pos = i; } V = new Node1Content[MAX_SIG_SIZE1]; for (var i = 0; i < V.Length; i++) { V[i] = new Node1Content(); V[i].Pos = i; } flowP = new Flow[MAX_SIG_SIZE1]; for (var i = 0; i < flowP.Length; i++) { flowP[i] = new Flow(); flowP[i].Pos = i; } w = init(signature1, signature2, costMatrix); if (n1 > 1 && n2 > 1) /* IF _n1 = 1 OR _n2 = 1 THEN WE ARE DONE */ { for (itr = 1; itr < MAX_ITERATIONS; itr++) { // System.out.println("EMD"); /* FIND BASIC VARIABLES */ findBasicVariables(U, V); // /* CHECK FOR OPTIMALITY */ if (isOptimal(U, V)) break; // // /* IMPROVE SOLUTION */ newSol(); } } totalCost = 0; if (flow != null) { flowP[0] = flow; } flowp = flowP[0]; for (xp = X[0]; xp.Pos < endx.Pos; xp = X[xp.Pos + 1]) { if (xp.Equals(enterX)) { continue; } if (xp.I == signature1.N || xp.J == signature2.N) { continue; } if (xp.Val == 0) { continue; } totalCost = totalCost + xp.Val * costMatrix[xp.I][xp.J]; if (flow != null) { // my code var flowTemp = new Flow(); flowTemp.From = xp.I; flowTemp.To = xp.J; flowTemp.Amount = xp.Val; flowTemp = flowP[flowp.Pos + 1]; flowList.Add(flowTemp); // end of my code flowp.From = xp.I; flowp.To = xp.J; flowp.Amount = xp.Val; flowp = flowP[flowp.Pos + 1]; } } // if(flow != null){ // flowSize=flowp.getPos() - flow.getPos(); // } //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'" return (float) (totalCost / w); }
/// <param name="u"> /// </param> /// <param name="v"> /// </param> /// <returns> /// </returns> /// <throws> IsOptimalException </throws> private bool isOptimal(Node1Content[] u, Node1Content[] v) { double delta, deltaMin; int i, j, minI = 0, minJ = 0; deltaMin = INFINITY; for (i = 0; i < n1; i++) { for (j = 0; j < n2; j++) { if (isX[i][j] == 0) { delta = costMatrix[i][j] - u[i].Val - v[j].Val; if (deltaMin > delta) { deltaMin = delta; minI = i; minJ = j; } } } } if (deltaMin == INFINITY) { throw new IsOptimalException(); } enterX.I = minI; enterX.J = minJ; return (deltaMin >= (- EPSILON) * maxC); }