Esempio n. 1
0
 /// <summary>
 /// Graph consists of only one part
 /// </summary>
 /// <param name="dynamic"></param>
 /// <param name="graph"></param>
 private static void SolveSinglePart(ResultPair[] dynamic, int[] graph)
 {
     int last = graph.Length - 1;
     bool wasReverted = false;
     List<bool> labeling = new List<bool>();
     int count = 0;
     if (graph[0] == 2 && graph[last] == 2)
     {//only egos 2
         int i = 0;
         ChooseEverySecondTwo(graph, labeling, ref count, ref i, 0);
         if (labeling.Count != graph.Length)
         {
             labeling.Add(true);
             count++;
         }
         dynamic[last] = new ResultPair
         {
             Optimum = count,
             Labeling = labeling,
             Ending = Ending.DoubleTwo,
         };
         return;
     }
     if (graph[last] == 2)
     {//two only at the end => reverse and so two at the beginning
         graph = graph.Reverse().ToArray();
         wasReverted = true;
     }
     if (graph[0] == 2)
     {//2 at the beginning, maybe reversed
         int i = 0;
         ChooseEverySecondTwo(graph, labeling, ref count, ref i, 0);
         if (graph.Length - labeling.Count > 1)
             labeling.Add(!labeling.Last());
         //choose last one
         if (labeling.LastOrDefault())
             labeling.Add(false);
         else
         {
             labeling.Add(true);
             count++;
         }
         if (wasReverted)
         {
             graph = graph.Reverse().ToArray();
             labeling.Reverse();
         }
         dynamic[last] = new ResultPair
         {
             Optimum = count,
             Labeling = labeling,
             Ending = Ending.SingleTwo,
         };
         return;
     }
     //start and ends with ego 1
     //length of the graph is odd => starter 12 at the beginning (e.g.)
     if (graph.Length % 2 == 1)
     {
         labeling.Add(true);
         labeling.Add(true);
         count = 2;
         int i = 2;
         ChooseEverySecondTwo(graph, labeling, ref count, ref i, 1);
         //choose last one
         if (labeling.LastOrDefault())
             labeling.Add(false);
         else
         {
             labeling.Add(true);
             count++;
         }
         dynamic[last] = new ResultPair
         {
             Optimum = count,
             Labeling = labeling,
             Ending = Ending.SingleTwo,
         };
         return;
     }
     //legth of the graph is even => starter first 22, legth is at least 4 (or 11 => not possible)
     labeling.Add(false);
     labeling.Add(true);
     labeling.Add(true);
     count = 2;
     int j = 3;
     ChooseEverySecondTwo(graph, labeling, ref count, ref j, 0);//choose last one
     if (labeling.LastOrDefault())
         labeling.Add(false);
     else
     {
         labeling.Add(true);
         count++;
     }
     dynamic[last] = new ResultPair
     {
         Optimum = count,
         Labeling = labeling,
         Ending = Ending.SingleTwo,
     };
 }
Esempio n. 2
0
        /// <summary>
        /// Solve a middle part (start and ends with one, part before exists and is solved)
        /// </summary>
        /// <param name="dynamic"></param>
        /// <param name="graph"></param>
        /// <param name="l"></param>
        private static void SolveMiddlePart(ResultPair[] dynamic, int[] graph, int l)
        {
            ResultPair lastEnd = dynamic[l];
            if (lastEnd.Ending == Ending.TwoOne)
            {//last chosen is 1
                //starter 12, 1 is already chosen
                List<bool> labeling = new List<bool>();
                int count = 0;
                int i = l + 1;
                ChooseEverySecondTwo(graph, labeling, ref count, ref i, 1);
                SetDynamic(dynamic, i, l, count, labeling, i == l + 1 ? Ending.TwoOneTwo : Ending.SingleTwo);

                //starter 22
                i = l + 1;
                while (graph[i] == 2 && graph[i + 1] == 2)
                {
                    labeling = new List<bool>();
                    labeling.Add(true);
                    labeling.Add(true);
                    count = 2;
                    ChooseEverySecondTwoDown(labeling, ref count, i -1,l,2-i);
                    int j = i + 2;
                    ChooseEverySecondTwo(graph, labeling, ref count, ref j, 1 - i);
                    SetDynamic(dynamic, j, l, count, labeling,j == i + 1 ? Ending.DoubleTwo : Ending.SingleTwo);
                    i++;
                }
                //starter 21
                i = l + 1;
                while (graph[i] != 2 || graph[i + 1] != 1)
                {
                    i++;
                }
                labeling = new List<bool>();
                labeling.Add(true);
                labeling.Add(true);
                count = 2;
                ChooseEverySecondTwoDown(labeling, ref count, i - 1, l + 1, 2 - i);
                SetDynamic(dynamic, i + 1, l, count, labeling, Ending.TwoOne);
            }//Ending.TwoOne
            else
            {
                //starter 12
                int i = l + 1;
                List<bool> labeling = new List<bool>();
                int count = 1;
                if (graph[i] == 2)
                {
                    i++;
                    labeling.Add(false);
                }
                //nyní graph[i] == 1
                labeling.Add(true);
                int onePosition = i;
                i++;
                ChooseEverySecondTwo(graph, labeling, ref count, ref i, 1 - onePosition);
                SetDynamic(dynamic, i,l,count,labeling,i == onePosition + 1
                            ? (onePosition == l + 1 ? Ending.TwoOneTwo : Ending.OneTwo)
                            : Ending.SingleTwo);
                //starter 22
                i = l + 1;
                bool twoBeforeOne = false;
                if (graph[i] == 2)
                {
                    twoBeforeOne = true;
                    i++;
                }
                i++;
                bool makeGap = false;
                if (lastEnd.Ending == Ending.DoubleTwo ||
                        lastEnd.Ending == Ending.TwoOneTwo)
                {//make a gap 21 if it is possible
                    makeGap = true;
                }
                while (graph[i] == 2 && graph[i + 1] == 2)
                {
                    labeling = new List<bool>();
                    labeling.Add(true);
                    labeling.Add(true);
                    count = 2;
                    ChooseEverySecondTwoDown(labeling, ref count, i - 1, onePosition + 1, 2 - i);
                    labeling.Reverse();
                    //ćonnect to the previous part
                    if (twoBeforeOne)
                    {
                        if (!makeGap)
                        {
                            labeling.Add(true);
                            count++;
                            labeling.Add(false);
                        }
                        else
                        {
                            if (!labeling.Last())
                            {
                                labeling[labeling.Count - 1] = true;
                                count++;
                            }
                            labeling.Add(false);
                            labeling.Add(false);
                        }
                    }
                    else
                    {
                        if (i == onePosition + 2)
                        {
                            labeling.Add(false);
                        }
                        else
                        {
                            if (!labeling.Last())
                            {
                                labeling[labeling.Count - 1] = true;
                                count++;
                            }
                            labeling.Add(false);
                        }
                    }
                    labeling.Reverse();
                    int j = i + 2;
                    ChooseEverySecondTwo(graph, labeling, ref count, ref j, 1 - i);
                    SetDynamic(dynamic, j, l, count, labeling, j == i + 1 ? Ending.DoubleTwo : Ending.SingleTwo);
                    i++;
                }

                //starter 21
                i = l + 1;
                if (twoBeforeOne)
                    i++;
                i++;
                while (graph[i] != 2 || graph[i + 1] != 1)
                {
                    i++;
                }
                labeling = new List<bool>();
                labeling.Add(true);
                labeling.Add(true);
                count = 2;
                ChooseEverySecondTwoDown(labeling, ref count, i - 1, onePosition + 1, 2 - i);
                labeling.Reverse();
                //connect to the previous part
                if (twoBeforeOne)
                {
                    if (!makeGap)
                    {
                        labeling.Add(true);
                        count++;
                        labeling.Add(false);
                    }
                    else
                    {
                        if (!labeling.Last())
                        {
                            labeling[labeling.Count - 1] = true;
                            count++;
                        }
                        labeling.Add(false);
                        labeling.Add(false);
                    }
                }
                else
                {
                    if (i == onePosition + 2)
                    {//want to make a gap 12, so must create 212 and solve the next part
                        if (i + 2 < graph.Length)
                        {
                            bool[] helpLabeling = new bool[labeling.Count];
                            labeling.CopyTo(helpLabeling);
                            List<bool> innerLabeling = helpLabeling.ToList();
                            innerLabeling.Add(false);
                            innerLabeling.Reverse();
                            innerLabeling.Add(true);
                            int innerCount = count + 1;
                            int m = i + 3;
                            ChooseEverySecondTwo(graph, innerLabeling, ref innerCount, ref m, i + 2);
                            SetDynamic(dynamic, m, l, innerCount, innerLabeling,
                                m == i + 2 ? Ending.TwoOneTwo : Ending.SingleTwo);
                        }
                    }
                    //try also not prolonged version
                    if (!labeling.Last())
                    {
                        labeling[labeling.Count - 1] = true;
                        count++;
                    }
                    labeling.Add(false);
                }
                labeling.Reverse();
                SetDynamic(dynamic, i + 1, l, count, labeling, Ending.TwoOne);

            }
        }
Esempio n. 3
0
 /// <summary>
 /// Solve one part, it is not single or first part
 /// </summary>
 /// <param name="dynamic"></param>
 /// <param name="graph"></param>
 /// <param name="l"></param>
 private static void SolveOnePart(ResultPair[] dynamic, int[] graph, int l)
 {
     if (IsEnd(dynamic[l].Ending, graph, l))
         SolveEndPart(dynamic, graph, l);
     else
         SolveMiddlePart(dynamic, graph, l);
 }
Esempio n. 4
0
        private static void SolveFirstPart(int[] graph, ResultPair[] dynamic)
        {
            int i = 0;
            if (graph[0] == 2)
            {
                int count = 0;
                List<bool> labeling = new List<bool>();
                ChooseEverySecondTwo(graph, labeling, ref count, ref i, 0);

                dynamic[i] = new ResultPair
                {
                    Optimum = count,
                    Labeling = labeling,
                    Ending = i == 0 ? Ending.DoubleTwo : Ending.SingleTwo
                };
            }
            else
            {//unchosen one at the beginning
                //starter 12
                int count = 2;
                i = 2;
                List<bool> labeling = new List<bool>();
                labeling.Add(true);
                labeling.Add(true);
                ChooseEverySecondTwo(graph, labeling, ref count, ref i, 1);

                if (dynamic[i] == null || dynamic[i].Optimum > count)
                    dynamic[i] = new ResultPair
                    {
                        Optimum = count,
                        Labeling = labeling,
                        Ending = i == 1 ? Ending.OneTwo : Ending.SingleTwo,
                    };
                //starters 22
                i = 1;
                while (i < graph.Length && graph[i] == 2 && graph[i + 1] == 2)
                {
                    labeling = new List<bool>();
                    count = 2;
                    labeling.Add(true);
                    labeling.Add(true);
                    ChooseEverySecondTwoDown(labeling, ref count, i - 1, 0, 2 - i);
                    int j = i + 2;
                    ChooseEverySecondTwo(graph, labeling, ref count, ref j, 1 - i);

                    if (dynamic[j] == null || dynamic[j].Optimum > count)
                        dynamic[j] = new ResultPair
                        {
                            Optimum = count,
                            Labeling = labeling,
                            Ending = j == i + 1 ? Ending.DoubleTwo : Ending.SingleTwo,
                        };
                    i++;
                }

                //starter 21
                i = 1;
                while (graph[i] != 2 || graph[i + 1] != 1)
                {
                    i++;
                }
                labeling = new List<bool>();
                labeling.Add(true);
                labeling.Add(true);
                count = 2;
                ChooseEverySecondTwoDown(labeling, ref count, i - 1, 0, 2 - i);
                if (dynamic[i + 1] == null || dynamic[i + 1].Optimum > count)
                    dynamic[i + 1] = new ResultPair
                    {
                        Optimum = count,
                        Labeling = labeling,
                        Ending = Ending.TwoOne,
                    };
            }
        }
Esempio n. 5
0
        private static void SolveEndPart(ResultPair[] dynamic, int[] graph, int l)
        {
            if (l == graph.Length - 1)
                return;
            ResultPair lastEnd = dynamic[l];
            int i = 0;
            int count = 0;
            List<bool> labeling = new List<bool>();
            if (graph[graph.Length - 1] == 2)
            {
                if (lastEnd.Ending == Ending.TwoOne)
                {
                    i = graph.Length - 1;
                    labeling = new List<bool>();
                    labeling.Add(true);
                    count = 1;
                    ChooseEverySecondTwoDown(labeling, ref count, i - 1, l + 1, 2 - i);
                    SetDynamic(dynamic, i, l, count, labeling, Ending.SingleTwo);
                    i++;

                }

                //starter last 2
                count = 1;
                labeling = new List<bool>();
                labeling.Add(true);
                bool twoBeforeOne = false;
                i = l + 1;
                if (graph[i] == 2)
                {
                    twoBeforeOne = true;
                    i++;
                }
                int onePosition = i;
                i = graph.Length - 1;
                bool makeGap = false;
                if (lastEnd.Ending == Ending.DoubleTwo ||
                        lastEnd.Ending == Ending.TwoOneTwo)
                {//make a gap 21 if it is possible
                    makeGap = true;
                }
                ChooseEverySecondTwoDown(labeling, ref count, i - 1, onePosition + 1, 2 - i);
                labeling.Reverse();
                //connect to the previous part
                //maybe make a gap 21
                if (twoBeforeOne)
                {
                    if (!makeGap)
                    {
                        labeling.Add(true);
                        count++;
                        labeling.Add(false);
                    }
                    else
                    {
                        if (!labeling.Last())
                        {
                            labeling[labeling.Count - 1] = true;
                            count++;
                        }
                        labeling.Add(false);
                        labeling.Add(false);
                    }
                }
                else
                {
                    if (i == onePosition + 2)
                    {
                        labeling.Add(false);
                    }
                    else
                    {
                        if (!labeling.Last())
                        {
                            labeling[labeling.Count - 1] = true;
                            count++;
                        }
                        labeling.Add(false);
                    }
                }
                labeling.Reverse();
                SetDynamic(dynamic, i, l, count, labeling, Ending.DoubleTwo);
                return;
            }

            SolveMiddlePart(dynamic, graph, l);
            //if there is 1 at the end, it is solved by standart method and finished here
            if (graph[graph.Length - 3] == 1)
            {//the last part ..121, already started
                if (dynamic[graph.Length - 1] == null || dynamic[graph.Length - 1].Optimum > dynamic[graph.Length - 2].Optimum)
                {//if the starter is 12 => last 1 is not chosen, propagate value only
                    labeling = new List<bool>();
                    labeling.Add(false);
                    dynamic[graph.Length - 1] = new ResultPair
                    {
                        Optimum = dynamic[graph.Length - 2].Optimum,
                        Labeling = dynamic[graph.Length - 2].Labeling.Concat(labeling).ToList(),
                        Ending = Ending.SingleTwo,//nonsens - technical only
                    };
                }
                return;
            }
            // last part, at least two 2 (..221)
            if (dynamic[graph.Length - 3] != null)
            {
                if (dynamic[graph.Length - 1] == null || dynamic[graph.Length - 1].Optimum > dynamic[graph.Length - 3].Optimum + 1)
                {
                    labeling = new List<bool>();
                    labeling.Add(false);
                    labeling.Add(true);
                    dynamic[graph.Length - 1] = new ResultPair
                    {
                        Optimum = dynamic[graph.Length - 3].Optimum + 1,
                        Labeling = dynamic[graph.Length - 3].Labeling.Concat(labeling).ToList(),
                        Ending = Ending.SingleTwo,//nonsens - technical only
                    };
                }
            }
            if (dynamic[graph.Length - 2] != null)
            {
                if (dynamic[graph.Length - 1] == null || dynamic[graph.Length - 1].Optimum > dynamic[graph.Length - 2].Optimum)
                {
                    labeling = new List<bool>();
                    labeling.Add(false);
                    dynamic[graph.Length - 1] = new ResultPair
                    {
                        Optimum = dynamic[graph.Length - 3].Optimum,
                        Labeling = dynamic[graph.Length - 3].Labeling.Concat(labeling).ToList(),
                        Ending = Ending.SingleTwo,//nonsens - technical only
                    };
                }
            }
        }
Esempio n. 6
0
 private static void SetDynamic(ResultPair[] dynamic, int i, int l, int count, List<bool> labeling, Ending ending)
 {
     if (dynamic[i] == null || dynamic[i].Optimum > count + dynamic[l].Optimum ||
         (dynamic[i].Optimum == count + dynamic[l].Optimum && IsStrong(ending)))
         dynamic[i] = new ResultPair
         {
             Optimum = count + dynamic[l].Optimum,
             Labeling = dynamic[l].Labeling.Concat(labeling).ToList(),
             Ending = ending,
         };
 }
Esempio n. 7
0
 private static bool[] GetResultFromDynamic(ResultPair[] dynamic)
 {
     return dynamic[dynamic.Length - 1].Labeling.ToArray();
 }
Esempio n. 8
0
        /// <summary>
        /// Solve one graph with egos one or two, no consecutive ones
        /// </summary>
        /// <param name="graph"></param>
        /// <returns></returns>
        private static bool[] GetOptimalLabeling(int[] graph)
        {
            ResultPair[] dynamic = new ResultPair[graph.Length];
            if (IsEnd(Ending.TwoOne, graph, 0))
            {
                SolveSinglePart(dynamic, graph);
                return GetResultFromDynamic(dynamic);
            }

            SolveFirstPart(graph, dynamic);

            //main loop of dynamic programming
            for (int l = 0; l < dynamic.Length; l++)
            {
                if (dynamic[l] != null)
                {
                    SolveOnePart(dynamic, graph, l);
                    // for testing only
                    for (int j = l; j < dynamic.Length; j++)
                    {
                        if (dynamic[j] != null && dynamic[j].Labeling.Count != j + 1)
                        {
                            throw new InvalidOperationException("nesprávně dlouhé labeling");
                        }
                    }
                }
            }

            return GetResultFromDynamic(dynamic);
        }