private List <Tangle> getTanglesWithNCrossings(int n) { if (n <= 0) { throw new ArgumentException("The number must be between 1 and the number of crossings."); } List <Tangle> tangles = new List <Tangle>(); List <int> crossings = Enumerable.Range(1, NumberOfCrossings).ToList(); //generate all n choose k combinations of crosses (avoid negative) IEnumerable <List <int> > combinations = Extensions.Tools.Choose <int>(crossings, n); foreach (List <int> list in combinations) { Tangle t = new Tangle(list.ToArray()); if (IsValidTangle(t)) { tangles.Add(t); } } //return all valid combinations return(tangles); }
private int[] GetTangleEnds(Tangle t) { List <int> indexes = new List <int>(); foreach (int c in t.Crosses) { indexes.Add(this.GaussCode.IndexOf(c)); indexes.Add(this.GaussCode.IndexOf(-c)); } indexes.Sort(); int a = Tools.Mod(indexes.First() - 1, this.GaussCode.Count); int b = Tools.Mod(indexes.Last() + 1, this.GaussCode.Count); if (this.IsContiguousTangle(t)) { return(new int[] { a, b }); } else { int m = 0, n = 0; for (int i = 0; i < indexes.Count - 1; i++) { m = Tools.Mod(indexes[i] + 1, this.GaussCode.Count); n = indexes[i + 1]; if (m != n) { n--; break; } } return(new int[] { a, m, n, b }); } }
public override bool Equals(object obj) { if (obj is Tangle) { Tangle other = (Tangle)obj; if (this.nCrosses == other.nCrosses) { bool equals = true; for (int i = 0; i < this.nCrosses; i++) { equals &= this.Crosses[i] == other.Crosses[i]; } return(equals); } } return(false); }
private bool IsContiguousTangle(Tangle t) { List <int> fullTangle = new List <int>(); fullTangle.Add(t.Crosses[0]); int indexFirst = this.GaussCode.IndexOf(t.Crosses[0]); bool expandSx = true; bool expandDx = true; int expand = 1; int index = 0; while (expandSx || expandDx) { if (expandSx) { index = Tools.Mod((indexFirst - expand), this.GaussCode.Count); if (t.Crosses.Contains(Math.Abs(this.GaussCode[index])) && !fullTangle.Contains(this.GaussCode[index])) { fullTangle.Insert(0, this.GaussCode[index]); } else { expandSx = false; } } if (expandDx) { index = Tools.Mod((indexFirst + expand), this.GaussCode.Count); if (t.Crosses.Contains(Math.Abs(this.GaussCode[index])) && !fullTangle.Contains(this.GaussCode[index])) { fullTangle.Add(this.GaussCode[index]); } else { expandDx = false; } } expand++; } return(fullTangle.Count == (t.nCrosses * 2)); }
private bool IsValidTangle(Tangle t) { MovableCircularList <int> crosses = new MovableCircularList <int>(); foreach (int c in t.Crosses) { crosses.Add(this.GaussCode.IndexOf(c)); crosses.Add(this.GaussCode.IndexOf(-c)); } crosses.Sort(); int leaps = 0; for (int i = 0; i < crosses.Count - 1; i++) { if (Tools.Mod(crosses[i] + 1, this.GaussCode.Count) != crosses[i + 1]) { leaps++; } } return(leaps < 2); }
private bool IsValidTangleOld(Tangle t) { int t_hash = t.Hash(); List <int> firstSet = new List <int>(); int indexFirst = this.GaussCode.IndexOf(t.Crosses[0]); firstSet.Add(this.GaussCode[indexFirst]); bool expandSx = true; bool expandDx = true; int expand = 1; int index = 0; while (expandSx || expandDx) { if (expandSx) { index = Tools.Mod((indexFirst - expand), this.GaussCode.Count); if (t.Crosses.Contains(Math.Abs(this.GaussCode[index])) && !firstSet.Contains(Math.Abs(this.GaussCode[index]))) { firstSet.Add(this.GaussCode[index]); } else { expandSx = false; } } if (expandDx) { index = Tools.Mod((indexFirst + expand), this.GaussCode.Count); if (t.Crosses.Contains(Math.Abs(this.GaussCode[index])) && !firstSet.Contains(Math.Abs(this.GaussCode[index]))) { firstSet.Add(this.GaussCode[index]); } else { expandDx = false; } } expand++; } Tangle firstT = new Tangle(firstSet.ToArray()); int firstT_hash = firstT.Hash(); int sizeSecondSet = t.nCrosses * 2 - firstSet.Count; int[] secondSet = new int[sizeSecondSet]; for (int i = 0; i < this.GaussCode.Count; i++) { for (int j = 0; j < sizeSecondSet; j++) { secondSet[j] = this.GaussCode[Tools.Mod(i + j, this.GaussCode.Count)]; } Tangle secondT = new Tangle(secondSet); int secondT_hash = secondT.Hash(); if (firstT != secondT && firstT_hash == secondT_hash) { bool contain = true; foreach (int n in secondSet) { contain &= t.Crosses.Contains(Math.Abs(n)); } if (contain) { return(true); } } } return(false); }
private void PerformTranslationMove1(int cross, int insertIndex1, int insertIndex2, Tangle t) { for (int i = 0; i < this.GaussCode.Count; i++) { if (t.Crosses.Contains(Math.Abs(this.GaussCode[i]))) { this.GaussCode[i] = -this.GaussCode[i]; } } int posIndex = this.GaussCode.IndexOf(cross); int negIndex = this.GaussCode.IndexOf(-cross); this.GaussCode.Move(posIndex, insertIndex1); this.GaussCode.Move(negIndex, insertIndex2); }
private int[] getPositionsForReductionMove2() { int sign(int a) { if (a >= 0) { return(1); } return(-1); } List <int[]> adj = new List <int[]>(); List <int> temp = new List <int>(); for (int i = 0; i < this.GaussCode.Count; i++) { temp = new List <int>(); for (int j = i; j < this.GaussCode.Count; j++) { if (sign(this.GaussCode[j]) == sign(this.GaussCode[j + 1])) { temp.Add(this.GaussCode[j]); temp.Add(this.GaussCode[j + 1]); int[] add = temp.Distinct().ToArray(); adj.Add(add); } else { break; } } } adj = adj.OrderByDescending(a => a.Length).ToList(); foreach (int[] t in adj) { Tangle test = new Tangle(t); int firstIndex = this.GaussCode.IndexOf(-t[0]); int tempFirst = firstIndex; int[] found = new int[t.Length]; bool dx = true; for (int i = 0; i < t.Length; i++) { if (dx) { if (t.Contains(-this.GaussCode[firstIndex])) { found[i] = -this.GaussCode[firstIndex]; firstIndex++; } else { dx = false; i--; } } else { firstIndex = tempFirst - 1; if (t.Contains(-this.GaussCode[firstIndex])) { found[i] = -this.GaussCode[firstIndex]; firstIndex--; } } } Tangle TFound = new Tangle(found); if (test.Hash() == TFound.Hash()) { return(t); } } return(null); }