Commit c8fb4e63 authored by Caelan Reese Wong's avatar Caelan Reese Wong
Browse files

implemented mostSimilar function

parent 1ca5b4ba
Loading
Loading
Loading
Loading
+9 −1
Original line number Diff line number Diff line
@@ -53,11 +53,19 @@ public class Main {
            case "--findMolecule":
                Molecule molecule = moleculeDb.findMolecule(new Molecule(moleculePath));
                if (molecule == null) {
                    System.out.println("NOT FOUND");
                    System.out.println("NO EXACT MATCH FOUND");
                    molecule= moleculeDb.similarMolecule(new Molecule(moleculePath));
                    if(molecule!=null)
                    {
                        System.out.println(molecule.moleculeName + " is the most similar");
                    }
                } else {
                    printVerbose("FOUND");
                }
                break;
//            case "--similarMolecule":
//                Molecule molecule2= moleculeDb.similarMolecule(new Molecule(moleculePath));
//                printVerbose("FOUND! "+molecule2.moleculeName+" is the most similar molecule");
            default:
                printVerbose("unrecognized command: " + cmd);
                break;
+30 −0
Original line number Diff line number Diff line
@@ -7,6 +7,7 @@ import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

/**
 * A class represents the molecule database
@@ -81,6 +82,35 @@ public class MoleculeDatabase {
        return null; // Return null if molecule not found
    }


    /**
     * Find the most similar Molecule from the database
     */
    public Molecule similarMolecule(Molecule molecule) {

        // If an exact match is not found then find the most similar
        int maxResult=0;
        Molecule similar=null;
        for (Map.Entry<Integer, ArrayList<Molecule>> entry : db.entrySet()) {
            // Access the key and value of each entry
            Integer numberAtoms = entry.getKey();

            //only check for similarity if they have similar number of atoms within tolerance of 100
            if( (molecule.getNumAtoms()-100)<numberAtoms && numberAtoms<(molecule.getNumAtoms()+100) )
            {
                for (Molecule dbMolecule : db.get(numberAtoms)) {
                    int res = dbMolecule.mostSimilar(molecule);
                    if (res > maxResult) {
                        similar = dbMolecule; // save the similar molecule
                        maxResult = res;
                    }
                }
            }
        }

        return similar;
    }

    /**
     * Save database to file system
     */
+6 −2
Original line number Diff line number Diff line
@@ -10,6 +10,7 @@ public class Atom implements Serializable {
        atomName = name;
        degree = 0;
        connected = new HashMap<>();
        connectedMarked= new ArrayList<>();
        elementType = elem;
        marked = false;
    }
@@ -18,8 +19,10 @@ public class Atom implements Serializable {
        if(connected.containsKey(i.getName())) {
            connected.put(i.getName(),new ElemOrderPair(i.elementType,connected.get(i.getName()).bondOrder+1));
        }
        else
        else {
            connected.put(i.getName(), new ElemOrderPair(i.elementType, 1));
            connectedMarked.add(false);
        }
    }
    public String getName() {
        return this.atomName;
@@ -28,6 +31,7 @@ public class Atom implements Serializable {
    public int elementType;
    public int degree;
    public Map<String,ElemOrderPair> connected;
    public ArrayList<Boolean> connectedMarked;
    public boolean marked;


+88 −0
Original line number Diff line number Diff line
@@ -123,6 +123,94 @@ public class Molecule implements Serializable {
        return this;
    }


    /**
     * Finds the Most Similar Molecule
     */
    public int mostSimilar(Molecule otherMolecule) {

        int similarity=0; //counts similarity points

        // Points for an intersection of elements between this and otherMolecule
        for(int i=0;i<this.numElements.length;i++)
        {
            similarity+= Math.min( this.numElements[i], otherMolecule.numElements[i]);
        }

        //Points for same number of atoms
        if(this.numAtoms==otherMolecule.numAtoms)
        {
            similarity++;
        }

        //Points for same number of edges
        if(this.numEdges==otherMolecule.numEdges)
        {
            similarity++;
        }


        // Clean the otherMolecule atom list of any marked atoms
        for(Atom cleanAtom : otherMolecule.atomArrayList)
        {
            cleanAtom.marked = false;

            //clean the connected arraylist
            for(int i=0;i<cleanAtom.connectedMarked.size();i++)
            {
                cleanAtom.connectedMarked.set(i,false);
            }
        }
        // Clean the dbMolecule atom list of any marked atoms

        // Compare the atom lists
        for(Atom dbAtom : this.atomArrayList) {
            boolean matchingEdge=false;

            for (Atom newAtom : otherMolecule.atomArrayList) {

                if (newAtom.elementType == dbAtom.elementType) { //Check if elements are the same
                    boolean [] edgeMarked = new boolean[newAtom.connected.size()];
                    // Compare connected of each atom
                    //for each connected atom in dbAtom
                    for (Atom.ElemOrderPair dbValues : dbAtom.connected.values()) {
                        int marker=0;

                        for (Atom.ElemOrderPair newAtomValues : newAtom.connected.values()) {
                            //if its a match
                            //if first 2 yes, add points for min of bondOrder between the 2
                            if (!newAtom.connectedMarked.get(marker) && !edgeMarked[marker] && dbValues.eType == newAtomValues.eType )
                            {
                                if( dbValues.bondOrder == newAtomValues.bondOrder)
                                {
                                    //mark the newAtom edge as already found
                                    newAtom.connectedMarked.set(marker,true);
                                    matchingEdge=true;
                                    edgeMarked[marker]=true;
                                    similarity++; //add a point for each edge that is the same
                                    break;
                                }

                            }
                            marker++;

                        }
                    }

                }

                if(matchingEdge)
                {
                    break;
                }
            }

        }

        // If all comparisons passed, the molecules are equal
        return similarity;
    }

    /**
     * Return number of atoms of the molecule
     */