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]; } }
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); }
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); } }
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()); }
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); }