예제 #1
0
 private static void IterateOnHashes(ParticleGraphProto gr, HangedGraph hg, uint[] newHashes)
 {
     for (int i = gr.atoms.Count - 1; i >= 0; i--)
     {
         var atom = gr.atoms[i];
         hg.Hang(atom);
         newHashes[i] = hg.GetHash(rHashes);
     }
     for (int i = gr.atoms.Count - 1; i >= 0; i--)
     {
         gr.atoms[i].protoHash = newHashes[i];
     }
 }
예제 #2
0
    public static uint GetStructureHash(List <Element> atoms, List <BondInfo> bonds, bool exact, AtomsReordering reordering = null)
    {
        if (atoms.Count == 0)
        {
            return(0);
        }
        var gr      = new ParticleGraphProto(atoms, bonds, exact, rHashes);
        int variant = reordering == null ? 0 : reordering.selectedReordering;
        int total;
        var hash = GetHashInner(gr, variant, out total);

        if (reordering != null)
        {
            reordering.totalReorderings = total;
            BuildReorderingArray(gr, reordering.reordering);
        }
        return(hash);
    }
예제 #3
0
    private static void BuildReorderingArray(ParticleGraphProto gr, List <int> reordering)
    {
        if (reordering == null)
        {
            return;
        }
        reordering.Clear();
        var atoms      = gr.atoms;
        int atomsCount = atoms.Count;

        if (reordering.Capacity < atomsCount)
        {
            reordering.Capacity = atomsCount;
        }
        for (int i = 0; i < atomsCount; i++)
        {
            reordering.Add(atoms[i].originalIndx);
        }
    }
예제 #4
0
    private static void Print(ParticleGraphProto gr, string prefix = "")
    {
        var sb = new StringBuilder(prefix);

        if (!string.IsNullOrEmpty(prefix))
        {
            sb.AppendLine();
        }
        for (int i = 0; i < gr.atoms.Count; i++)
        {
            var atom = gr.atoms[i];
            sb.AppendFormat("\tatom {0} @{2} [ {1:X} ]\tbonds: ", atom.type, atom.protoHash, atom.originalIndx);
            for (int j = 0; j < atom.bonds.Count; j++)
            {
                var bond = atom.bonds[j];
                sb.AppendFormat("\t<b>{1}</b>@{2}@{3}->{0:X}      ", bond.Other(atom).protoHash, bond.type - 127, bond.node1.originalIndx, bond.node2.originalIndx);
            }
            sb.AppendLine();
        }
        sb.AppendLine();
        Debug.Log(sb.ToString());
    }
예제 #5
0
    private static uint GetHashInner(ParticleGraphProto gr, int variant, out int totalVariants)
    {
        uint hash;

        totalVariants = 1;
        gr.PrepareSimpleHashes();
        gr.TrySortAndUpdateHash(out hash);
        gr.PrepareSimpleHashes();
        gr.TrySortAndUpdateHash(out hash);
        _hangedGraph.AttachTo(gr);
        if (!_hangedGraph.AllNodesConnected(gr.atoms[0]))
        {
            return(NOT_CONNECTED_HASH);
        }
        // try to get unique hash based only on hanged graphs on each atom
        var newHashes = new uint[gr.atoms.Count];

        for (int i = 0; i < gr.atoms.Count; i++)
        {
            IterateOnHashes(gr, _hangedGraph, newHashes);
            if (gr.TrySortAndUpdateHash(out hash))
            {
                return(hash);
            }
            // there are symmetrical atoms. lets introduce some assymetry by changing hash in one of them
            uint atomHash;
            int  variants = gr.CountSimilarVariants(out atomHash);
            totalVariants *= variants;
            int v = variant % variants;
            variant /= variants;
            gr.ModifySimilarHash(atomHash, v);
            gr.TrySortAndUpdateHash(out hash);
        }
        Debug.LogError("Last\n\t" + hash);
        return(hash);
    }