package graphmatcher.matcher;
import graphmatcher.graph.Edge;
import graphmatcher.graph.Graph;
import graphmatcher.helper.EstimatedTransformationContainer;
import graphmatcher.helper.TransformationEstimator;
import graphmatcher.matcher.komatcher.EdgeRater;
import graphmatcher.matcher.shapecontext.RatingsMatrix;
import java.awt.geom.AffineTransform;
import java.text.NumberFormat;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Vector;
public class MatchingResult implements Comparable<MatchingResult> {
private Graph pattern, deformedPattern, template;
private double medianOfLenghtsOfMatchingEdges;
private double percentageOfMatchedVertices;
private double quality = -1;
private int[] matching, edgeMatching;
private byte matchingType;
private AffineTransform affineTransform; // gesch�tzte Transformation
private RatingsMatrix matrix;
private long matchingTime;
private boolean dummy = false;
public MatchingResult(Graph pattern, Graph template) {
this.pattern = pattern;
this.template = template;
medianOfLenghtsOfMatchingEdges = Double.POSITIVE_INFINITY;
percentageOfMatchedVertices = 0;
}
public RatingsMatrix getMatrix() {
return matrix;
}
public void setMatrix(RatingsMatrix matrix) {
this.matrix = matrix;
}
public double getMedianOfLenghtsOfMatchingEdges() {
return medianOfLenghtsOfMatchingEdges;
}
public void setMedianOfLenghtsOfMatchingEdges(double value) {
this.medianOfLenghtsOfMatchingEdges = value;
}
public int[] getMatching() {
return matching;
}
public void setMatching(int[] matching) {
this.matching = matching;
try {
EstimatedTransformationContainer container = TransformationEstimator.lmsEstimator(pattern,
template, matching);
AffineTransform detransform = container.affineTransform;
this.affineTransform = detransform;
deformedPattern = pattern;
int counterForNonMatchedVertices = 0;
for (int i = 0; i < matching.length; i++) {
if (matching[i] == -1) {
counterForNonMatchedVertices++;
}
}
setPercentageOfMatchedVertices((double) (matching.length - counterForNonMatchedVertices)
/ (double) pattern.getNumberOfVertices());
/**
* wof�r war das gut?
*/
// if (detransform != null) {
// deformedPattern = GraphTools.transformGraph(pattern,
// detransform);
// // deformedPattern = pattern;
// for (int i = 0; i < matching.length; i++) {
// if (matching[i] == -1) {
// continue;
// }
// Point dp = deformedPattern.vertices()[i].toPoint();
// Point t = template.vertices()[matching[i]].toPoint();
// double distance = DistanceHelper.getDistance(dp, t);
// if (distance > template.getMaximumVertexDistanceToCenter() / 2) {
// matching[i] = -1;
// }
// }
// }
} catch (IllegalArgumentException iae) {
// System.out.println(iae.getMessage());
// nix
}
}
public void setEdgeMatching(int[] edgeMatching) {
this.edgeMatching = edgeMatching;
}
@Override
public int compareTo(MatchingResult o) {
if (this.getQuality() < o.getQuality()) {
return -1;
}
if (this.getQuality() == o.getQuality()) {
return 0;
}
return 1;
}
public Graph getPattern() {
return pattern;
}
public Graph getDeformedPattern() {
return deformedPattern;
}
public Graph getTemplate() {
return template;
}
public long getMatchingTime() {
return matchingTime;
}
public void setMatchingTime(long matchingTime) {
this.matchingTime = matchingTime;
}
public static MatchingResult getDummyMatchingResult() {
MatchingResult matchingResult = new MatchingResult(null, null);
matchingResult.dummy = true;
return matchingResult;
}
public double getPercentageOfMatchedVertices() {
return percentageOfMatchedVertices;
}
public void setPercentageOfMatchedVertices(double percentageOfMatchedEdges) {
this.percentageOfMatchedVertices = percentageOfMatchedEdges;
}
// public double getTransformationScaleDiff() {
// double shearX = affineTransform.getShearX();
// double shearY = affineTransform.getShearY();
// System.out.println(shearX);
// System.out.println(shearY);
//
// return Math.max(shearX, shearY)-Math.min(shearX, shearY);
// }
public double getPercentageOfEdgeOnEdgeMatches() {
Edge[] patternEdges = pattern.edges();
Edge[] templateVirtualEdges = template.virtualEdges();
int numberOfMatchedEdges = 0;
int numberOfEdgeOnEdgeMatches = 0;
boolean matched;
for (int i = 0; i < patternEdges.length; i++) {
Edge patternEdge = patternEdges[i];
if (matching[patternEdge.vertex1] < 0 || matching[patternEdge.vertex2] < 0) {
continue;
}
numberOfMatchedEdges++;
matched = false;
for (int j = 0; j < templateVirtualEdges.length; j++) {
Edge templateVirtualEdge = templateVirtualEdges[j];
if (matched(patternEdge, templateVirtualEdge)) {
matched = true;
numberOfEdgeOnEdgeMatches++;
break;
}
}
// if (!matched) {
// System.out.println(patternEdge+" konnte nicht gematchet werden");
// }
}
double percentage = (double) numberOfEdgeOnEdgeMatches / (double) numberOfMatchedEdges;
return percentage;
}
private boolean matched(Edge patternEdge, Edge templateEdge) {
int pv1MatchedTo = matching[patternEdge.vertex1];
int pv2MatchedTo = matching[patternEdge.vertex2];
if (pv1MatchedTo == templateEdge.vertex1 && pv2MatchedTo == templateEdge.vertex2) {
return true;
}
if (pv1MatchedTo == templateEdge.vertex2 && pv2MatchedTo == templateEdge.vertex1) {
return true;
}
return false;
}
public String toString() {
NumberFormat format = NumberFormat.getNumberInstance();
format.setMinimumFractionDigits(2);
format.setMaximumFractionDigits(2);
String result = "";
result += " Quality: " + format.format(getQuality());
return result;
}
public double getPercentageOfBiggestSubGraph() {
if (matchingType == AbstractMatcher.VERTEX_MATCHING) {
Vector<LinkedHashMap<Integer, Integer>> submatchings = new Vector<LinkedHashMap<Integer, Integer>>();
// boolean[][] match1on1 =
// EdgeRater.getMatch1On1Array(deformedPattern, template);
boolean[][] match1on1 = EdgeRater.getMatch1On1Array(pattern, template);
int edgeOnEdgeCounter = 0;
for (int currentPatternEdgeID = 0; currentPatternEdgeID < pattern.virtualEdges().length; currentPatternEdgeID++) {
Edge patternEdge = pattern.virtualEdges()[currentPatternEdgeID];
int templateVertex1 = matching[patternEdge.vertex1];
int templateVertex2 = matching[patternEdge.vertex2];
if (templateVertex1 == -1 || templateVertex2 == -1) {
// Kante wurde nicht gematcht
continue;
}
int currentTemplateEdgeID = template.getEdgeID(templateVertex1, templateVertex2);
if (currentTemplateEdgeID == -1) {
// Kante existiert nicht im Template
continue;
}
edgeOnEdgeCounter++;
boolean foundSubmatching = false;
for (LinkedHashMap<Integer, Integer> map : submatchings) {
Iterator<Integer> patternEdges = map.keySet().iterator();
while (patternEdges.hasNext()) {
int patternEdgeID = patternEdges.next();
int templateEdgeID = map.get(patternEdgeID);
// double rating =
// EdgeRater.rateMatchingPair(deformedPattern, template,
// currentPatternEdgeID, currentTemplateEdgeID,
// patternEdgeID, templateEdgeID,
// match1on1);
double rating = EdgeRater.rateMatchingPair(pattern, template, currentPatternEdgeID,
currentTemplateEdgeID, patternEdgeID, templateEdgeID, match1on1);
if (rating > 0.6) {
map.put(currentPatternEdgeID, currentTemplateEdgeID);
foundSubmatching = true;
break;
}
}
if (foundSubmatching) {
break;
}
}
if (!foundSubmatching) {
LinkedHashMap<Integer, Integer> newSubmatching = new LinkedHashMap<Integer, Integer>();
newSubmatching.put(currentPatternEdgeID, currentTemplateEdgeID);
submatchings.add(newSubmatching);
}
}
int maxSubmatchingSize = -1;
LinkedHashMap<Integer, Integer> bestSubmatching = null;
for (LinkedHashMap<Integer, Integer> submatching : submatchings) {
if (submatching.size() > maxSubmatchingSize) {
maxSubmatchingSize = submatching.size();
{
bestSubmatching = submatching;
}
}
}
if (submatchings.size() == 0) {
return 0;
}
/*
* L�nge der Kanten des besten Submatchings berechnen
*/
Collection<Integer> matchedPatternEdges = bestSubmatching.keySet();
Collection<Integer> matchedTemplateEdges = bestSubmatching.values();
double patternRatio = pattern.getPercentageOfSpanningSubGraph(matchedPatternEdges);
double templateRatio = template.getPercentageOfSpanningSubGraph(matchedTemplateEdges);
double result = Math.min(patternRatio, templateRatio);
return result;
} else {
// EDGE_MATCHING_TYPE
if (edgeMatching == null) {
return 0;
}
Collection<Integer> matchedPatternEdges = new Vector<Integer>();
Collection<Integer> matchedTemplateEdges = new Vector<Integer>();
for (int i = 0; i < edgeMatching.length; i++) {
if (edgeMatching[i] != -1) {
matchedPatternEdges.add(new Integer(i));
matchedTemplateEdges.add(new Integer(edgeMatching[i]));
// Edge pEdge = pattern.virtualEdges()[i];
// Edge tEdge = template.virtualEdges()[edgeMatching[i]];
// System.out.println(pEdge + " -> " + tEdge);
}
}
double patternRatio = pattern.getPercentageOfSpanningSubGraph(matchedPatternEdges);
double templateRatio = template.getPercentageOfSpanningSubGraph(matchedTemplateEdges);
double result = Math.min(patternRatio, templateRatio);
return result;
}
}
public double getQuality() {
if (dummy) {
return Double.NEGATIVE_INFINITY;
}
if (quality > -1) {
return quality;
}
quality = getPercentageOfBiggestSubGraph();
return quality;
}
public void setMatchingType(byte matchingType) {
this.matchingType = matchingType;
}
public byte getMatchingType() {
return matchingType;
}
}