Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/322.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 段链识别算法_C#_Arrays_Algorithm - Fatal编程技术网

C# 段链识别算法

C# 段链识别算法,c#,arrays,algorithm,C#,Arrays,Algorithm,我有一个片段数组: ISegment[]段 由接口定义: 公共接口ISegment { Point3D A{get;}//段起点 Point3D B{get;}//段终点 } 其中可以包含以下实例: 公共类行:ISegment { 公共点3D A{get;}//行起点 公共点3D B{get;}//线端点 /*…其他线属性和方法*/ } 或以下情况: 公共类弧:ISegment { 公共点3D A{get;}//弧起点 公共点3D B{get;}//弧终点 /*…其他弧特性和方法*/ }

我有一个片段数组:

ISegment[]段
由接口定义:

公共接口ISegment
{
Point3D A{get;}//段起点
Point3D B{get;}//段终点
}
其中可以包含以下实例:

公共类行:ISegment
{
公共点3D A{get;}//行起点
公共点3D B{get;}//线端点
/*…其他线属性和方法*/
}
或以下情况:

公共类弧:ISegment
{
公共点3D A{get;}//弧起点
公共点3D B{get;}//弧终点
/*…其他弧特性和方法*/
}
并且可以由以下图像表示:

我正在搜索一种优雅的算法,以将其识别为段链:

ISegment[][]段链
结果是:

[[s1、s2、s3、s4]、[s5、s6]、[s7]、[s8、s9、s10]、[s11、s12]]
没有任何订单考虑

注:

  • 输入1D数组
    可以有任何顺序
  • 输出2D数组
    段链
    可以有任何顺序
  • 圆弧段可以具有相同的起点和终点

欢迎您的帮助

我认为,像下面这样的方法应该有效:

  • 将它们全部放在
    字典
    中,其中起始点是一个键,在此点开始的
    段列表
    是一个值
  • 将所有起点和终点放入字典,其中的值为与该点相等的可用终点数
  • 从步骤2中选取字典中有0的任何起点。它不能添加到任何链中。如果没有这样的点,则取任意点(因为有一个循环)
  • 对于当前点,取从其中开始的任何段(如果存在)。字典中可用点的递减值
  • 如果没有合适的分段,则从步骤3继续

  • 我有一个迭代的方法应该可以工作。不过,我不知道它有多优雅。我更喜欢使用
    列表
    而不是
    数组
    ,因为它们可以动态扩展(初始化时不需要大小)

    方法签名如下所示:

    public static List<List<ISegment>>GetSegmentChains(List<ISegment> segments)
    
    类修改以包括构造函数和
    ToString()
    override

    public interface ISegment
    {
        string Name { get; }
        Point3D A { get; }
        Point3D B { get; }
    }
    
    public class Line : ISegment
    {
        public string Name { get; }
        public Point3D A { get; }
        public Point3D B { get; }
    
        public Line(string name, Point3D a, Point3D b)
        {
            Name = name;
            A = a;
            B = b;
        }
    
        public override string ToString()
        {
            return Name;
        }
    }
    
    public class Arc : ISegment
    {
        public string Name { get; }
        public Point3D A { get; }
        public Point3D B { get; }
    
        public Arc(string name, Point3D singlePoint) : this(name, singlePoint, singlePoint)
        {
        }
    
        public Arc(string name, Point3D a, Point3D b)
        {
            Name = name;
            A = a;
            B = b;
        }
    
        public override string ToString()
        {
            return Name;
        }
    }
    
    辅助方法在示例中生成线段列表,确定线段是否为单个线段链,确定线段是否包含点,以及从线段获取非匹配点:

    public static List<ISegment> GenerateSegmentList()
    {
        // Generate the points in the diagram
        var A = new Point3D(0, 0, 0);
        var B = new Point3D(0, 0, 1);
        var C = new Point3D(0, 0, 2);
        var D = new Point3D(0, 0, 3);
        var E = new Point3D(0, 0, 4);
        var F = new Point3D(0, 0, 5);
        var G = new Point3D(0, 0, 6);
        var H = new Point3D(0, 0, 7);
        var I = new Point3D(0, 0, 8);
        var J = new Point3D(0, 0, 9);
        var K = new Point3D(0, 1, 0);
        var L = new Point3D(0, 1, 1);
        var M = new Point3D(0, 1, 2);
        var N = new Point3D(0, 1, 3);
    
        // Generate the segments in the diagram
        return new List<ISegment>
        {
            new Line("s1", A, B),
            new Line("s2", B, C),
            new Line("s3", C, D),
            new Line("s4", D, E),
            new Line("s5", F, G),
            new Line("s6", G, H),
            new Arc("s7", I),
            new Line("s8", J, K),
            new Line("s9", K, L),
            new Line("s10", L, J),
            new Line("s11", M, N),
            new Arc("s12", N, M)
        };
    }
    
    public static bool IsSingleSegmentChain(ISegment segment)
    {
        return segment != null && segment.A == segment.B;
    }
    
    public static bool ContainsPoint(ISegment segment, Point3D pointToMatch)
    {
        return segment != null && (segment.A == pointToMatch || segment.B == pointToMatch);
    }
    
    public static Point3D GetNonMatchingPoint(ISegment segment, Point3D pointToMatch)
    {
        return segment == null
            ? default(Point3D)
            : (segment.A == pointToMatch)
                ? segment.B
                : segment.A;
    }
    
    公共静态列表GenerateSegmentList()
    {
    //在图表中生成点
    var A=新的点3d(0,0,0);
    var B=新的点3d(0,0,1);
    var C=新的点3d(0,0,2);
    var D=新的点3d(0,0,3);
    var E=新的点3d(0,0,4);
    var F=新的点3d(0,0,5);
    var G=新的点3D(0,0,6);
    var H=新点3D(0,0,7);
    var I=新的点3d(0,0,8);
    var J=新的点3d(0,0,9);
    var K=新的点3d(0,1,0);
    var L=新点3D(0,1,1);
    var M=新的点3d(0,1,2);
    var N=新的点3d(0,1,3);
    //在图中生成段
    返回新列表
    {
    新线(“s1”、A、B),
    新线(“s2”、B、C),
    新线(“s3”,C,D),
    新线(“s4”、D、E),
    新线(“s5”,F,G),
    新线(“s6”,G,H),
    新Arc(“s7”,I),
    新线(“s8”,J,K),
    新线(“s9”,K,L),
    新线(“s10”,L,J),
    新线(“s11”,M,N),
    新弧(“s12”,N,M)
    };
    }
    公共静态布尔单段链(ISegment段)
    {
    返回段!=null&&segment.A==segment.B;
    }
    公共静态布尔包含点(ISEMENT段,点3D点匹配)
    {
    返回段!=null&(段.A==pointToMatch | |段.B==pointToMatch);
    }
    公共静态点3D GetNonMatchingPoint(ISegment段,Point3D pointToMatch)
    {
    返回段==null
    ?默认值(点3D)
    :(段.A==点匹配)
    ?B段
    :A段;
    }
    
    示例用法

    private static void Main()
    {
        List<ISegment> segments = GenerateSegmentList();
        List<List<ISegment>> segmentChains = GetSegmentChains(segments);
    
        for(int i = 0; i < segmentChains.Count; i++)
        {
            Console.WriteLine($"Segment Chain #{i + 1}: {string.Join(" => ", segmentChains[i])}");
        }
    
        Console.WriteLine("\nDone!\nPress any key to exit...");
        Console.ReadKey();
    }
    
    private static void Main()
    {
    列表段=GenerateSegmentList();
    List segmentChains=GetSegmentChains(段);
    对于(int i=0;i”,段链[i]));
    }
    Console.WriteLine(“\n完成!\n按任意键退出…”);
    Console.ReadKey();
    }
    
    输出


    您是否已经有了非优雅的解决方案?如果是这样,请发布它,以便人们可以提出改进建议,或者在它不起作用的地方提供帮助。确切地说,“细分链”是什么?从任何细分开始。检查所有其他线段,起点等于该线段起点或终点的任何线段都连接在链中。
    Arc
    s是否曾经是链的一部分?
    s链是否可以与
    s链
    s链
    s?或者其他
    Arc
    s?@C.Evenhuis,是的。[s11,s12]在本例中。这适用于简单的情况,而不适用于更复杂的情况。假设有五条线段在同一点相交。您将拥有多条链。这就是为什么会有Dijkstra。@jdweng,因为在问题链被表示为数组时,我希望链数最少的解决方案(对于您的案例,是3)是正确的。您希望得到哪种链的其他解决方案?数组并不意味着段[0]连接到段[1]连接到段[2]。数组只表示任意顺序的段。我希望您有一个图,其中链是该图的一部分。@jdweng,您在说什么?至于我,它不能被命名为链子。链应该是一条路径,顺序:)我并不反对你。我只是说链/路径是图的一部分。
    private static void Main()
    {
        List<ISegment> segments = GenerateSegmentList();
        List<List<ISegment>> segmentChains = GetSegmentChains(segments);
    
        for(int i = 0; i < segmentChains.Count; i++)
        {
            Console.WriteLine($"Segment Chain #{i + 1}: {string.Join(" => ", segmentChains[i])}");
        }
    
        Console.WriteLine("\nDone!\nPress any key to exit...");
        Console.ReadKey();
    }