/// <summary> /// Определение 3. Две простые цепи, соединяющие х1 и х2, называются непересекающимися (или /// вершинно-непересекающимися), если у них нет общих вершин, отличных от х1 и х2 (и, следовательно, нет общих ребер). /// </summary> /// <param name="path1"></param> /// <param name="path2"></param> /// <returns></returns> public static bool IsNonIntersected(Path path1, Path path2) { Debug.Assert(new StackListQueue <Vertex> { path1.First(), path1.Last(), path2.First(), path2.Last(), }.Distinct().Count() == 2); IEnumerable <Vertex> intersect = path1.GetRange(1, path1.Count - 2) .Intersect(path2.GetRange(1, path2.Count - 2)); return(!intersect.Any()); }
/// <summary> /// Разбиение грани путём, контакные вершины которого принадлежат данной грани /// </summary> /// <returns></returns> public IEnumerable <Edge> Split(Path path) { Debug.Assert(path.FromTo(this)); var list = new StackListQueue <Edge>(); if (path.Count() < 2) { return(list); } int index1 = IndexOf(path.First()); int index2 = IndexOf(path.Last()); List <Vertex> vertexs = path.ToList(); if (index1 == index2) { // Вырожденый случай когда путь представляет собой цикл // и пересечение с грань происходит только в одной точке if (path.Count > 3) { list.Add(new Edge(path.GetRange(0, path.Count - 1))); } list.Add(this); } else { if (index1 > index2) { int t = index1; index1 = index2; index2 = t; vertexs.Reverse(); } List <Vertex> list1 = GetRange(0, index1); list1.AddRange(vertexs.GetRange(0, vertexs.Count - 1)); list1.AddRange(GetRange(index2, this.Count() - index2)); list.Add(new Edge(list1)); vertexs.Reverse(); List <Vertex> list2 = GetRange(index1, index2 - index1); list2.AddRange(vertexs.GetRange(0, path.Count() - 1)); list.Add(new Edge(list2)); } Debug.WriteLineIf(list.Any(), this + " split by " + path + " is " + string.Join(",", list.Select(item => item.ToString()))); return(list); }
/// <summary> /// Разбиение пути в точках перечечения пути с графом на отдельные подпути /// </summary> /// <param name="path"></param> /// <returns></returns> public IEnumerable <Path> Split(Path path) { Debug.Assert(Count >= 2); var list = new StackListQueue <Path>(); StackListQueue <int> indexes; if (Settings.EnableCudafy) { try { int[,] matrix; lock (CudafySequencies.Semaphore) { CudafySequencies.SetSequencies( Vertices.Select(path.GetInts).Select(item => item.ToArray()).ToArray(), path.GetRange(1, Count - 2).Select(path.GetInts).Select(item => item.ToArray()).ToArray() ); CudafySequencies.Execute("Compare"); matrix = CudafySequencies.GetMatrix(); } lock (CudafyMatrix.Semaphore) { CudafyMatrix.SetMatrix(matrix); CudafyMatrix.ExecuteRepeatZeroIndexOfZero(); indexes = new StackListQueue <int>(CudafyMatrix.GetIndexes() .Where(index => index >= 0) .Select(index => index + 1)); } } catch (Exception ex) { Debug.WriteLine(ex.ToString()); indexes = new StackListQueue <int>( path.GetRange(1, Count - 2) .Intersect(Vertices) .Select(v => path.IndexOf(v))); } } else { indexes = new StackListQueue <int>( path.GetRange(1, Count - 2) .Intersect(Vertices) .Select(v => path.IndexOf(v))); } indexes.Sort(); indexes.Prepend(0); indexes.Append(Count - 1); Dictionary <Vertex, VertexSortedCollection> children = Children; for (int prev = indexes.Dequeue(); indexes.Any(); prev = indexes.Dequeue()) { if (((prev + 1) == indexes[0]) && children.ContainsKey(path[prev]) && children[path[prev]].Contains(path[indexes[0]])) { continue; } list.Add(new Path(path.GetRange(prev, indexes[0] - prev + 1))); } Debug.WriteLineIf(list.Any(), path + " split by " + this + " is " + string.Join(",", list.Select(item => item.ToString()))); return(list); }