예제 #1
0
        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);
        }
예제 #2
0
        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 });
            }
        }
예제 #3
0
 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);
 }
예제 #4
0
        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));
        }
예제 #5
0
        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);
        }
예제 #6
0
        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);
        }
예제 #7
0
        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);
        }
예제 #8
0
        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);
        }