package com.aptima.netstorm.algorithms.aptima.bp.sampling; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map.Entry; import java.util.TreeSet; public class Sample { private HashMap<Integer, Integer> modelNodeToDataNode; private HashMap<Integer, Integer> dataNodeToModelNode;; private HashMap<String, Integer> dataIDToDataNodeID; private double mismatch; private HashMap<String, RelationshipForSample> relationshipIDs; private HashMap<String, ArrayList<String>> additionalRelationshipIDs; private int mnmrReference; private boolean mnmrSet = false; private boolean hasAdditionalIDs = false; private int additionalIDCount = 0; private int ID = -1; public Sample() { } /** * Create sample for a single-node model network */ public Sample(int modelNodeId, int dataNodeId, String dataId, double mismatch) { this.modelNodeToDataNode = new HashMap<Integer, Integer>(1); this.dataNodeToModelNode = new HashMap<Integer, Integer>(1); this.dataIDToDataNodeID = new HashMap<String, Integer>(1); this.modelNodeToDataNode.put(modelNodeId, dataNodeId); this.dataNodeToModelNode.put(dataNodeId, modelNodeId); this.dataIDToDataNodeID.put(dataId, dataNodeId); this.mismatch = mismatch; this.relationshipIDs = new HashMap<String, RelationshipForSample>(); this.additionalRelationshipIDs = new HashMap<String, ArrayList<String>>(); } /** * * @param modelNodeToDataNode * @param mismatch * @throws IllegalArgumentException * if all of the data nodes in the sample are not unique. */ public Sample(HashMap<Integer, Integer> modelNodeToDataNode, HashMap<String, Integer> dataIDToDataNodeID, double mismatch, HashMap<String, RelationshipForSample> relationshipIDs) { this.dataIDToDataNodeID = new HashMap<String, Integer>(dataIDToDataNodeID.size()); if (dataIDToDataNodeID != null) for (Entry<String, Integer> e : dataIDToDataNodeID.entrySet()) { this.dataIDToDataNodeID.put(new String(e.getKey()), new Integer(e.getValue())); } this.modelNodeToDataNode = new HashMap<Integer, Integer>(modelNodeToDataNode.size()); this.dataNodeToModelNode = new HashMap<Integer, Integer>(modelNodeToDataNode.size()); // Performing deep copy just in case for (Entry<Integer, Integer> e : modelNodeToDataNode.entrySet()) { this.modelNodeToDataNode.put(new Integer(e.getKey()), new Integer(e.getValue())); this.dataNodeToModelNode.put(new Integer(e.getValue()), new Integer(e.getKey())); } HashSet<Integer> dataNodes = new HashSet<Integer>(this.modelNodeToDataNode.values()); if (dataNodes.size() != this.modelNodeToDataNode.size()) throw new IllegalArgumentException("Sample contains multiple instances of the same data node."); this.relationshipIDs = new HashMap<String, RelationshipForSample>(); for (Entry<String, RelationshipForSample> e : relationshipIDs.entrySet()) { this.relationshipIDs.put(e.getKey(), e.getValue()); } this.additionalRelationshipIDs = new HashMap<String, ArrayList<String>>(); this.mismatch = mismatch; } public Sample copy(boolean copyAdditionalIDs) { Sample newSample = new Sample(); newSample.modelNodeToDataNode = new HashMap<Integer, Integer>(); newSample.dataNodeToModelNode = new HashMap<Integer, Integer>(); newSample.dataIDToDataNodeID = new HashMap<String, Integer>(); newSample.relationshipIDs = new HashMap<String, RelationshipForSample>(); newSample.mismatch = this.mismatch; newSample.mnmrReference = this.mnmrReference; newSample.mnmrSet = this.mnmrSet; newSample.additionalRelationshipIDs = new HashMap<String, ArrayList<String>>(); newSample.ID = this.ID; if (copyAdditionalIDs) { newSample.hasAdditionalIDs = this.hasAdditionalIDs; newSample.additionalIDCount = this.additionalIDCount; copyHashMap(this.additionalRelationshipIDs, newSample.additionalRelationshipIDs); } copyHashMap(this.dataIDToDataNodeID, newSample.dataIDToDataNodeID); copyHashMap(this.dataNodeToModelNode, newSample.dataNodeToModelNode); copyHashMap(this.relationshipIDs, newSample.relationshipIDs); copyHashMap(this.modelNodeToDataNode, newSample.modelNodeToDataNode); return newSample; } public int getID() { return ID; } public void setID(int ID) { this.ID = ID; } public <T1, T2> void copyHashMap(HashMap<T1, T2> source, HashMap<T1, T2> target) { for (T1 t1 : source.keySet()) { target.put(t1, source.get(t1)); } } public int getMNMRReference() { return mnmrReference; } public void setMNMRReference(int mnmrReference) { if (mnmrReference == -1) { // special case to mark sample invalid this.mnmrReference = mnmrReference; } else { if (!mnmrSet) { this.mnmrReference = mnmrReference; mnmrSet = true; } } } public HashMap<String, RelationshipForSample> getRelationshipIDs() { return relationshipIDs; } public boolean hasAdditionalIDs() { return this.hasAdditionalIDs; } public HashMap<String, ArrayList<String>> getAdditionalRelationshipIDs() { return additionalRelationshipIDs; } public void addAdditionalRelationshipID(String modelFromBarTo, String arID) { if (!additionalRelationshipIDs.containsKey(modelFromBarTo)) { additionalRelationshipIDs.put(modelFromBarTo, new ArrayList<String>()); hasAdditionalIDs = true; } additionalRelationshipIDs.get(modelFromBarTo).add(arID); additionalIDCount++; } public int relationshipsSize() { return this.relationshipIDs.keySet().size() + additionalIDCount; } public void setRelationshipIDs(HashMap<String, RelationshipForSample> newRelationshipIDs) { this.relationshipIDs.clear(); for (Entry<String, RelationshipForSample> e : newRelationshipIDs.entrySet()) { relationshipIDs.put(e.getKey(), e.getValue()); } } public HashMap<Integer, Integer> getModelNodeToDataNode() { return modelNodeToDataNode; } public HashMap<Integer, Integer> getDataNodeToModelNode() { return dataNodeToModelNode; } public void addModelNodeToDataNode(int modelNode, int dataNode) { this.modelNodeToDataNode.put(modelNode, dataNode); this.dataNodeToModelNode.put(dataNode, modelNode); } public void setModelNodeToDataNode(HashMap<Integer, Integer> newModelNodeToDataNode) { this.modelNodeToDataNode.clear(); this.dataNodeToModelNode.clear(); for (Entry<Integer, Integer> e : newModelNodeToDataNode.entrySet()) { this.modelNodeToDataNode.put(new Integer(e.getKey()), new Integer(e.getValue())); this.dataNodeToModelNode.put(new Integer(e.getValue()), new Integer(e.getKey())); } } public int getNextHighestDataNode() { int highest = 0; for (int dataNode : dataNodeToModelNode.keySet()) { if (dataNode >= highest) { highest = dataNode; } } return ++highest; } public HashMap<String, Integer> getDataIDToDataNodeID() { return dataIDToDataNodeID; } public String getIDWithDataNodeID(int dataNode) { for (String idKey : dataIDToDataNodeID.keySet()) { if (dataIDToDataNodeID.get(idKey) == dataNode) { return idKey; } } return null; } public TreeSet<String> getIDs() { return new TreeSet<String>(this.dataIDToDataNodeID.keySet()); } public TreeSet<String> getRelationships() { TreeSet<String> relationships = new TreeSet<String>(); for (RelationshipForSample rfs : this.relationshipIDs.values()) { relationships.add(rfs.relationshipID); } return relationships; } public HashSet<String> getRelationshipsHash() { HashSet<String> relationships = new HashSet<String>(); for (RelationshipForSample rfs : this.relationshipIDs.values()) { relationships.add(rfs.relationshipID); } return relationships; } public int getMatchingModelNode(int dataNode) { if (dataNodeToModelNode.containsKey(dataNode)) { return this.dataNodeToModelNode.get(dataNode); } return -1; } public double getMismatch() { return mismatch; } public void setMismatch(double mismatch) { this.mismatch = mismatch; } // /////////////////////////////////////////// // overwriting methods that compare objects of this type // ---equals @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Sample otherSample = (Sample) obj; if (modelNodeToDataNode == null && otherSample.modelNodeToDataNode == null) return true; TreeSet<String> dn1 = this.getIDs(); double mismatch1 = this.getMismatch(); TreeSet<String> rel1 = this.getRelationships(); TreeSet<String> dn2 = otherSample.getIDs(); double mismatch2 = otherSample.getMismatch(); TreeSet<String> rel2 = otherSample.getRelationships(); // System.out.println(mismatch1); // System.out.println(mismatch1); // printSet(dn1); // printSet(dn2); // printSet(rel1); // printSet(rel2); if (mismatch1 == mismatch2 && dn1.equals(dn2) && rel1.equals(rel2)) { // System.out.println("equal"); return true; } // System.out.println("not equal"); return false; } // private <T> void printSet(TreeSet<T> set) { // for (T t : set) { // System.out.println(t); // } // } // ---to string @Override public String toString() { StringBuilder result = new StringBuilder(); if (modelNodeToDataNode == null) return ""; List<Integer> keyList = new ArrayList<Integer>(modelNodeToDataNode.keySet()); Collections.sort(keyList); for (Integer key : keyList) { result.append(key + "_" + modelNodeToDataNode.get(key) + "|"); } return result.toString(); } // ---hashcode @Override public int hashCode() { if (ID != -1) { return ID; } else { String str = toString(); return (str.isEmpty() ? 0 : str.hashCode()); } } }