private int FS(List <Edge> edgesList, FMVertex vertex, List <FMVertex> vertexlist)//дивижущая сила
        {
            int count = 0;

            //проходимось по усім ребрам
            foreach (var element_edge in edgesList)
            {
                //якщо вершина належить розрізаному ребру
                if (((vertex.number == element_edge.first_vertex.number) || (vertex.number == element_edge.second_vertex.number)) && element_edge.partitioned == true)
                {
                    int edge_count = 0;

                    //пройдемося по усім вершинам переданого списку
                    foreach (var element_vertex in vertexlist)
                    {
                        if ((element_vertex.number == element_edge.first_vertex.number) || (element_vertex.number == element_edge.second_vertex.number))
                        {
                            edge_count++;
                        }
                    }

                    //якщо  розрізаному ребру належать вершини, що знаходяться в різних компонентах то "дивижущая сила" збільшується на 1
                    if (edge_count == 1)
                    {
                        count += element_edge.weight;
                    }
                }
            }

            return(count);
        }
        private int TE(List <Edge> edgesList, FMVertex vertex)//сила противодействия
        {
            int count = 0;

            foreach (var element in edgesList)
            {
                if (((element.first_vertex.number == vertex.number) || (element.second_vertex.number == vertex.number)) && element.partitioned == false)
                {
                    count += element.weight;
                }
            }

            return(count);
        }
        private void Transfer(List <FMVertex> firstList, List <FMVertex> secondList, FMVertex vertex)//перенос вершины в противоположную компоненту
        {
            List <FMVertex> copyFirstList  = new List <FMVertex>(firstList.Clone());
            List <FMVertex> copySecondList = new List <FMVertex>(secondList.Clone());

            foreach (var item in copyFirstList)
            {
                if (item.number == vertex.number)
                {
                    firstList.RemoveAll(e => e.number == item.number);
                    secondList.Add(vertex);
                }
            }
            foreach (var item in copySecondList)
            {
                if (item.number == vertex.number)
                {
                    secondList.RemoveAll(e => e.number == item.number);
                    firstList.Add(vertex);
                }
            }
        }
        public List <Edge> Partitioning(Graph graph)//РОЗБИТТЯ за алгоритмом ФМ
        {
            List <Edge>     Edges     = new List <Edge>();
            int             sumGrowth = 1;
            int             endGrowth = 0;
            int             sum_area  = graph.vertices.Count;
            List <FMVertex> gainsList = new List <FMVertex>();
            List <FMVertex> InVerticesA; //1-я компонента на внутринней итерации
            List <FMVertex> InVerticesB; //2-я компонента на внутренней итерации

            diagramData.Clear();
            OutVerticesA.Clear();
            OutVerticesB.Clear();

            StarterRandomPartitioning(graph);

            //bf = BalanceFactor();

            foreach (var item in graph.edges)
            {
                Edges.Add(new Edge(item.first_vertex, item.second_vertex, item.weight, false));
            }


            Partitioned(Edges, OutVerticesA, OutVerticesB);
            //OutputGraph(Edges);
            while (sumGrowth > 0)
            {
                gainsList.Clear();

                InVerticesA = new List <FMVertex>(OutVerticesA.Clone());

                InVerticesB = new List <FMVertex>(OutVerticesB.Clone());

                Gains(Edges, InVerticesA, InVerticesB);

                Unfixing(InVerticesA, InVerticesB);

                FMVertex baseVertex = new FMVertex(-1, 1, 0, false);
                bool     allFixed   = false;
                int      step       = 1;
                while (!allFixed)
                {
                    var max = MaxGains(InVerticesA, InVerticesB, (sum_area), IncedentVertices(Edges, InVerticesA, InVerticesB), step);
                    if (max != null)
                    {
                        Transfer(InVerticesA, InVerticesB, max);
                        max.fix    = true;
                        baseVertex = max;
                        gainsList.Add(new FMVertex(max.number, max.area, max.growth, max.fix));
                        Partitioned(Edges, InVerticesA, InVerticesB);

                        allFixed = Fixed(IncedentVertices(Edges, InVerticesA, InVerticesB));
                        Gains(Edges, InVerticesA, InVerticesB);
                        step++;
                    }
                    else
                    {
                        break;
                    }
                }

                for (int i = 1; i < gainsList.Count; i++)
                {
                    gainsList[i].growth += gainsList[i - 1].growth;
                }


                var max2 = gainsList.OrderByDescending(e => e.growth).Select(e => e).FirstOrDefault();

                if (max2 == null || max2.growth <= 0)
                {
                    sumGrowth = 0;
                    break;
                }
                else
                {
                    sumGrowth  = max2.growth;
                    endGrowth += max2.growth;
                    int i = 0;
                    do
                    {
                        Transfer(OutVerticesA, OutVerticesB, gainsList[i]);
                        i++;
                    } while (gainsList[i - 1].number != max2.number);
                }
                Partitioned(Edges, OutVerticesA, OutVerticesB);
                diagramData.Add(SumCut(Edges));
            }
            Partitioned(Edges, OutVerticesA, OutVerticesB);

            return(Edges);
            //OutputGraph(Edges);
            //Console.WriteLine("CutWeight"+ SumCut(Edges));
            //Console.WriteLine("SumGrows: " + endGrowth);
        }