/// <summary> /// Randomly chooses four atoms and alters the bonding /// pattern between them according to rules described /// in "Faulon, JCICS 1996, 36, 731". /// </summary> public virtual void Mutate(IAtomContainer ac) { Debug.WriteLine("RandomGenerator->Mutate() Start"); int nrOfAtoms = ac.Atoms.Count; int x1 = 0, x2 = 0, y1 = 0, y2 = 0; double a11 = 0, a12 = 0, a22 = 0, a21 = 0; double b11 = 0, lowerborder = 0, upperborder = 0; IAtom ax1 = null, ax2 = null, ay1 = null, ay2 = null; IBond b1 = null, b2 = null, b3 = null, b4 = null; int[] choices = new int[3]; int choiceCounter = 0; /* We need at least two non-zero bonds in order to be successful */ int nonZeroBondsCounter = 0; do { do { nonZeroBondsCounter = 0; /* Randomly choose four distinct atoms */ do { // this yields numbers between 0 and (nrOfAtoms - 1) x1 = (int)(random.NextDouble() * nrOfAtoms); x2 = (int)(random.NextDouble() * nrOfAtoms); y1 = (int)(random.NextDouble() * nrOfAtoms); y2 = (int)(random.NextDouble() * nrOfAtoms); Debug.WriteLine($"RandomGenerator->Mutate(): x1, x2, y1, y2: {x1}, {x2}, {y1}, {y2}"); } while (!(x1 != x2 && x1 != y1 && x1 != y2 && x2 != y1 && x2 != y2 && y1 != y2)); ax1 = ac.Atoms[x1]; ay1 = ac.Atoms[y1]; ax2 = ac.Atoms[x2]; ay2 = ac.Atoms[y2]; /* Get four bonds for these four atoms */ b1 = ac.GetBond(ax1, ay1); if (b1 != null) { a11 = BondManipulator.DestroyBondOrder(b1.Order); nonZeroBondsCounter++; } else { a11 = 0; } b2 = ac.GetBond(ax1, ay2); if (b2 != null) { a12 = BondManipulator.DestroyBondOrder(b2.Order); nonZeroBondsCounter++; } else { a12 = 0; } b3 = ac.GetBond(ax2, ay1); if (b3 != null) { a21 = BondManipulator.DestroyBondOrder(b3.Order); nonZeroBondsCounter++; } else { a21 = 0; } b4 = ac.GetBond(ax2, ay2); if (b4 != null) { a22 = BondManipulator.DestroyBondOrder(b4.Order); nonZeroBondsCounter++; } else { a22 = 0; } Debug.WriteLine($"RandomGenerator->Mutate()->The old bond orders: a11, a12, a21, a22: {a11}, {a12}, {a21}, {a22}"); } while (nonZeroBondsCounter < 2); /* Compute the range for b11 (see Faulons formulae for details) */ double[] cmax = { 0, a11 - a22, a11 + a12 - 3, a11 + a21 - 3 }; double[] cmin = { 3, a11 + a12, a11 + a21, a11 - a22 + 3 }; lowerborder = MathTools.Max(cmax); upperborder = MathTools.Min(cmin); /* Randomly choose b11 != a11 in the range max > r > min */ Debug.WriteLine("*** New Try ***"); Debug.WriteLine($"a11 = {a11}"); Debug.WriteLine($"upperborder = {upperborder}"); Debug.WriteLine($"lowerborder = {lowerborder}"); choiceCounter = 0; for (double f = lowerborder; f <= upperborder; f++) { if (f != a11) { choices[choiceCounter] = (int)f; choiceCounter++; } } if (choiceCounter > 0) { b11 = choices[(int)(random.NextDouble() * choiceCounter)]; } Debug.WriteLine($"b11 = {b11}"); } while (!(b11 != a11 && (b11 >= lowerborder && b11 <= upperborder))); var b12 = a11 + a12 - b11; var b21 = a11 + a21 - b11; var b22 = a22 - a11 + b11; if (b11 > 0) { if (b1 == null) { b1 = ac.Builder.NewBond(ax1, ay1, BondManipulator.CreateBondOrder(b11)); ac.Bonds.Add(b1); } else { b1.Order = BondManipulator.CreateBondOrder(b11); } } else if (b1 != null) { ac.Bonds.Remove(b1); } if (b12 > 0) { if (b2 == null) { b2 = ac.Builder.NewBond(ax1, ay2, BondManipulator.CreateBondOrder(b12)); ac.Bonds.Add(b2); } else { b2.Order = BondManipulator.CreateBondOrder(b12); } } else if (b2 != null) { ac.Bonds.Remove(b2); } if (b21 > 0) { if (b3 == null) { b3 = ac.Builder.NewBond(ax2, ay1, BondManipulator.CreateBondOrder(b21)); ac.Bonds.Add(b3); } else { b3.Order = BondManipulator.CreateBondOrder(b21); } } else if (b3 != null) { ac.Bonds.Remove(b3); } if (b22 > 0) { if (b4 == null) { b4 = ac.Builder.NewBond(ax2, ay2, BondManipulator.CreateBondOrder(b22)); ac.Bonds.Add(b4); } else { b4.Order = BondManipulator.CreateBondOrder(b22); } } else if (b4 != null) { ac.Bonds.Remove(b4); } Debug.WriteLine($"a11 a12 a21 a22: {a11} {a12} {a21} {a22}"); Debug.WriteLine($"b11 b12 b21 b22: {b11} {b12} {b21} {b22}"); }
/// <summary> /// Choose any possible quadruple of the set of atoms /// in ac and establish all of the possible bonding schemes according to /// Faulon's equations. /// </summary> public static IEnumerable <IAtomContainer> Sample(IAtomContainer ac) { Debug.WriteLine("RandomGenerator->Mutate() Start"); int nrOfAtoms = ac.Atoms.Count; double a11 = 0, a12 = 0, a22 = 0, a21 = 0; double b11 = 0, lowerborder = 0, upperborder = 0; double b12 = 0; double b21 = 0; double b22 = 0; double[] cmax = new double[4]; double[] cmin = new double[4]; IAtomContainer newAc = null; IAtom ax1 = null, ax2 = null, ay1 = null, ay2 = null; IBond b1 = null, b2 = null, b3 = null, b4 = null; //int[] choices = new int[3]; /* We need at least two non-zero bonds in order to be successful */ int nonZeroBondsCounter = 0; for (int x1 = 0; x1 < nrOfAtoms; x1++) { for (int x2 = x1 + 1; x2 < nrOfAtoms; x2++) { for (int y1 = x2 + 1; y1 < nrOfAtoms; y1++) { for (int y2 = y1 + 1; y2 < nrOfAtoms; y2++) { nonZeroBondsCounter = 0; ax1 = ac.Atoms[x1]; ay1 = ac.Atoms[y1]; ax2 = ac.Atoms[x2]; ay2 = ac.Atoms[y2]; /* Get four bonds for these four atoms */ b1 = ac.GetBond(ax1, ay1); if (b1 != null) { a11 = BondManipulator.DestroyBondOrder(b1.Order); nonZeroBondsCounter++; } else { a11 = 0; } b2 = ac.GetBond(ax1, ay2); if (b2 != null) { a12 = BondManipulator.DestroyBondOrder(b2.Order); nonZeroBondsCounter++; } else { a12 = 0; } b3 = ac.GetBond(ax2, ay1); if (b3 != null) { a21 = BondManipulator.DestroyBondOrder(b3.Order); nonZeroBondsCounter++; } else { a21 = 0; } b4 = ac.GetBond(ax2, ay2); if (b4 != null) { a22 = BondManipulator.DestroyBondOrder(b4.Order); nonZeroBondsCounter++; } else { a22 = 0; } if (nonZeroBondsCounter > 1) { // Compute the range for b11 (see Faulons formulae for details) cmax[0] = 0; cmax[1] = a11 - a22; cmax[2] = a11 + a12 - 3; cmax[3] = a11 + a21 - 3; cmin[0] = 3; cmin[1] = a11 + a12; cmin[2] = a11 + a21; cmin[3] = a11 - a22 + 3; lowerborder = MathTools.Max(cmax); upperborder = MathTools.Min(cmin); for (b11 = lowerborder; b11 <= upperborder; b11++) { if (b11 != a11) { b12 = a11 + a12 - b11; b21 = a11 + a21 - b11; b22 = a22 - a11 + b11; Debug.WriteLine("Trying atom combination : " + x1 + ":" + x2 + ":" + y1 + ":" + y2); newAc = (IAtomContainer)ac.Clone(); Change(newAc, x1, y1, x2, y2, b11, b12, b21, b22); if (ConnectivityChecker.IsConnected(newAc)) { yield return(newAc); } else { Debug.WriteLine("not connected"); } } } } } } } } yield break; }
public void TestIsOdd_int() { Assert.IsTrue(MathTools.IsOdd(1)); Assert.IsTrue(MathTools.IsOdd(3)); Assert.IsTrue(MathTools.IsOdd(209)); }
public void TestIsEven_int() { Assert.IsTrue(MathTools.IsEven(2)); Assert.IsTrue(MathTools.IsEven(208)); }
public void TestMin_arrayint() { int[] ints = { 1, 2, 3, 4, 5 }; Assert.AreEqual(1, MathTools.Min(ints)); }
public void TestMax_arrayint() { int[] ints = { 1, 2, 3, 4, 5 }; Assert.AreEqual(5, MathTools.Max(ints)); }
public void TestMin_arrayDouble() { double[] doubles = { 2.0, 1.0, 3.0, 5.0, 4.0 }; Assert.AreEqual(1.0, MathTools.Min(doubles), 0.001); }