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); }