/** * Copyright (C) 2010-2017 Gordon Fraser, Andrea Arcuri and EvoSuite * contributors * * This file is part of EvoSuite. * * EvoSuite is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3.0 of the License, or * (at your option) any later version. * * EvoSuite is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with EvoSuite. If not, see <http://www.gnu.org/licenses/>. */ package org.evosuite.eclipse.replace; import java.util.HashMap; public class NWAlgo { private final HashMap originalString; private final HashMap newString; private final HashMap originalType; private final HashMap newType; private final double[][] f; static int gap = -1; public static boolean finished; private String orgAlignment = ""; private String newAlignment = ""; int s = Integer.MIN_VALUE;//.NEGATIVE_INFINITY; public static void main(String[] args) { String originalString = "trate"; String newString = "translation"; //new NWAlgo(originalString, newString); }//main //construct the matrix public NWAlgo(HashMap originalString, HashMap newString, HashMap originalType, HashMap newType) { //forward, compute f matrix finished = false; this.originalString = originalString; this.newString = newString; this.originalType = originalType; this.newType = newType; f = new double[originalString.size() + 1][newString.size() + 1]; double[][] GA = new double[originalString.size() + 1][newString.size() + 1]; double[][] GB = new double[originalString.size() + 1][newString.size() + 1]; double delete; double insert; double upLeft; int g = -5; //gap opening penalty int h = -3; //gap extension penalty for (int i = 1; i <= originalString.size(); i++) f[i][0] = g + h * (i - 1); //gap*i; for (int j = 1; j <= newString.size(); j++) f[0][j] = g + h * (j - 1); //gap*j; f[0][0] = 0; GB[0][0] = Integer.MIN_VALUE; for (int i = 1; i <= originalString.size(); i++) { GB[i][0] = g + h * (i - 1); GA[i][0] = Integer.MIN_VALUE; } GA[0][0] = Integer.MIN_VALUE; for (int j = 1; j <= newString.size(); j++) { GA[0][j] = g + h * (j - 1); GB[0][j] = Integer.MIN_VALUE; } for (int i = 1; i <= originalString.size(); i++) { for (int j = 1; j <= newString.size(); j++) { //System.out.print(originalString.charAt(i-1)+ ","+ newString.charAt(j-1)); /* //ga GA[i][j]= Math.max(GA[i-1][j]+h, f[i-1][j]+g+h); GB[i][j]= Math.max(GB[i][j-1]+h, f[i][j-1]+g+h); //GC[i][j]= //f upLeft= f[i-1][j-1] ; //+getSimilarity(i-1, j-1); delete= GA[i-1][j-1]; //f[i-1][j] + gap; insert= GB[i-1][j-1]; //f[i][j-1] + gap; f[i][j]= Math.max(upLeft, Math.max(delete, insert)) +getSimilarity(i-1, j-1); */ GA[i][j] = Math.max(GA[i - 1][j] + h, f[i - 1][j] + g + h); GB[i][j] = Math.max(GB[i][j - 1] + h, f[i][j - 1] + g + h); upLeft = f[i - 1][j - 1] + getSimilarity(i - 1, j - 1); delete = GA[i][j]; //f[i-1][j] + gap; insert = GB[i][j]; //f[i][j-1] + gap; f[i][j] = Math.max(upLeft, Math.max(delete, insert)); } } //illustrate matrix /* for(int i=0; i<=originalString.size(); i++){ for(int j=0; j<=newString.size(); j++){ String val= f[i][j]+""; int k=val.length(); while(k<3){ val=" "+val; k++; } System.out.print(val); } System.out.println(); } */ //backtrack to get the alignment int i = originalString.size(); int j = newString.size(); double score; double diagScore; double upScore; double leftScore; while (i > 0 && j > 0) { score = f[i][j]; diagScore = f[i - 1][j - 1]; upScore = f[i][j - 1]; leftScore = f[i - 1][j]; if (score == diagScore + getSimilarity(i - 1, j - 1)) { orgAlignment = originalString.get(i - 1) + " " + orgAlignment; newAlignment = newString.get(j - 1) + " " + newAlignment; i -= 1; j -= 1; } else if (score == GA[i][j]) {//GA[i-1][j-1]+getSimilarity(i-1, j-1)){ //(leftScore+ gap)){ orgAlignment = originalString.get(i - 1) + " " + orgAlignment; newAlignment = "-" + " " + newAlignment; i -= 1; } else if (score == GB[i][j]) { //GB[i-1][j-1]+getSimilarity(i-1, j-1)){ //(upScore+gap)){ orgAlignment = "-" + " " + orgAlignment; newAlignment = newString.get(j - 1) + " " + newAlignment; j -= 1; } else { System.out.println("*error"); System.err.println(); } } while (i > 0) { orgAlignment = originalString.get(i - 1) + " " + orgAlignment; newAlignment = "-" + " " + newAlignment; i -= 1; } while (j > 0) { orgAlignment = "-" + " " + orgAlignment; newAlignment = newString.get(j - 1) + " " + newAlignment; j -= 1; } finished = true; // System.out.println(orgAlignment+"\n"+newAlignment); // System.out.println("nw distance: " +f[originalString.size()][newString.size()]); } public double getDistance() { return f[originalString.size()][newString.size()]; } public String getOrgAlignment() { return orgAlignment; } public String getNewAlignment() { return newAlignment; } public double getSimilarity(int n1, int n2) { //System.out.println(new TypeMatcher().RewardChooser(originalType[n1], newType[n2])); //int typeReward= new TypeMatcher().RewardChooser((String) originalType.get(n1), (String) newType.get(n2)); //calculate difference double stringRepresentation = 0; stringRepresentation = calDifference(n1, n2); return stringRepresentation; } private static double normalize(double value) { return value / (value + 1.0); } public double calDifference(int n1, int n2) { String oType = (String) originalType.get(n1); String nType = (String) newType.get(n2); double difference = 0; if (!oType.equals(nType)) { //if((oType.equals("literal") && nType.equals("var")) || //(oType.equals("var") && nType.equals("literal"))) //difference= new LevenshteinAlgo().getLevenshteinDistance((String) originalString.get(n1), (String) newString.get(n2))*(-1); //difference=-3; //else difference = -2;//-3 } else { if (oType.equals("literal")) difference = normalize(new LevenshteinAlgo().getLevenshteinDistance((String) originalString.get(n1), (String) newString.get(n2))) * (-1); if (oType.equals("var")) //if((new LevenshteinAlgo().getLevenshteinDistance((String) originalString.get(n1), (String) newString.get(n2)) )==0) //difference=3; //else difference = normalize(new LevenshteinAlgo().getLevenshteinDistance((String) originalString.get(n1), (String) newString.get(n2))) * (-1); if (oType.equals("class")) { //if((new LevenshteinAlgo().getLevenshteinDistance((String) originalString.get(n1), (String) newString.get(n2)) )==0) //difference=2;//2 //else difference = normalize(new LevenshteinAlgo().getLevenshteinDistance((String) originalString.get(n1), (String) newString.get(n2))) * (-1); } if (oType.equals("spChar")) { //if((new LevenshteinAlgo().getLevenshteinDistance((String) originalString.get(n1), (String) newString.get(n2)) )==0) //difference=2;//2 /*else difference=-1;//1 */ difference = normalize(new LevenshteinAlgo().getLevenshteinDistance((String) originalString.get(n1), (String) newString.get(n2))) * (-2); } if (oType.equals("keyword")) { difference = normalize(new LevenshteinAlgo().getLevenshteinDistance((String) originalString.get(n1), (String) newString.get(n2))) * (-1); } } return difference; } }