当某些节点分支到连接的节点循环时,如何在 C# 的图形中找到哈密顿循环?

How do I find a Hamiltonian Cycle in a Graph in C# when some nodes branch to a connected loop of nodes?

提问人:D.Man 提问时间:8/25/2023 最后编辑:D.Man 更新时间:8/26/2023 访问量:39

问:

我有这张图:

enter image description here

起始节点是 Hotel,我希望程序找到所有有效哈密顿循环的路径。

但是,尽管遵循了该算法的示例,我似乎无法使代码正常工作。

  public class Program
    {
        private const int vTotal = 12;
        private const int NODE = vTotal;

        private static int[,] graph = new int[NODE, NODE];
        private static int[] path = new int[NODE];

        public static string GetNodeDescription(int i)
        {
            
            if (i == 0) return "Hotel";
            if (i == 1) return "Sci Mus";
            if (i == 2) return "Toy Shop";
            if (i == 3) return "Big Whl";
            if (i == 4) return "Park";
            if (i == 5) return "Zoo";
            if (i == 6) return "Aqua";
            if (i == 7) return "Cath";
            if (i == 8) return "Castle";
            if (i == 9) return "War Ship";
            if (i == 10) return "Wax Works";
            if (i == 11) return "Art Gal";

            return "Unknown";
        }
        public static void DisplayCycle()
        {    //Function to display the cycle obtained
            Console.WriteLine("The Hamilton Cycle : \n");

            for (int i = 0; i < NODE; i++)
                Console.Write(path[i] + " " + GetNodeDescription(i) + "\n");

            Console.Write(path[0] + " " + GetNodeDescription(0) + "\n");     //print the first vertex again
        }

        public static bool IsValid(int v, int k)
        { 
            if (graph[path[k - 1], v] == 0)   //if there is no edge
                return false;

            for (int i = 0; i < k; i++)   //if vertex is already taken, skip that
                if (path[i] == v)
                    return false;

            return true;
        }

        public static bool CycleFound(int k)
        {
            if (k == NODE)
            {             //when all vertices are in the path
                if (graph[path[k - 1], path[0]] == 1)
                    return true;
                else
                    return false;
            }

            for (int v = 1; v < NODE; v++) 
            {       //for all vertices except starting point
                if (IsValid(v, k))
                {                //if possible to add v in the path
                    path[k] = v;
                    if (CycleFound(k + 1) == true)
                        return true;
                    path[k] = -1;               //when k vertex will not in the solution
                }
            }
            return false;
        }

        static bool HamiltonianCycle()
        {
            for (int i = 0; i < NODE; i++)
                path[i] = -1;
            path[0] = 0;     //first vertex as 0

            if (CycleFound(1) == false)
            {
                Console.WriteLine("Solution does not exist");
                return false;
            }

            DisplayCycle();
            return true;
        }


        static void Main(string[] args)
        {
            int i, j;
          
            graph = new int[,]
                {
                            { 0 , 1 , 0 , 0 , 0 , 1 , 0 , 1 , 0 , 0 , 0 , 0 },

                            { 1 , 0 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 },

                            { 0 , 1 , 0 , 1 , 0 , 0 , 0 , 0 , 0 , 1 , 0 , 0 },

                            { 0 , 0 , 1 , 0 , 1 , 0 , 0 , 0 , 0 , 0 , 1 , 0 },

                            { 0 , 0 , 0 , 1 , 0 , 1 , 0 , 0 , 0 , 0 , 0 , 0 },

                            { 1 , 0 , 0 , 0 , 1 , 0 , 1 , 0 , 0 , 0 , 0 , 0 },

                            { 0 , 0 , 0 , 0 , 0 , 1 , 0 , 1 , 0 , 0 , 0 , 1 },

                            { 1 , 0 , 0 , 0 , 0 , 0 , 1 , 0 , 1 , 0 , 0 , 0 },

                            { 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 0 , 1 , 0 , 0 },

                            { 0 , 0 , 1 , 0 , 0 , 0 , 0 , 0 , 1 , 0 , 1 , 0 },

                            { 0 , 0 , 0 , 1 , 0 , 0 , 0 , 0 , 0 , 1 , 0 , 1 },

                            { 0 , 0 , 0 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 1 , 0 }
                                };


            Console.WriteLine("The Graph :");
            for (i = 0; i < NODE; i++)
            {
                for (j = 0; j < NODE; j++)
                {
                    Console.Write(graph[i,j] + "\t");
                }
                Console.WriteLine();
            }

            Console.WriteLine();

            HamiltonianCycle();

        }
    }

运行后,我得到以下结果:

The Graph :
0       1       0       0       0       1       0       1       0       0       0       0
1       0       1       0       0       0       0       0       0       0       0       0
0       1       0       1       0       0       0       0       0       1       0       0
0       0       1       0       1       0       0       0       0       0       1       0
0       0       0       1       0       1       0       0       0       0       0       0
1       0       0       0       1       0       1       0       0       0       0       0
0       0       0       0       0       1       0       1       0       0       0       1
1       0       0       0       0       0       1       0       1       0       0       0
0       0       0       0       0       0       0       1       0       1       0       0
0       0       1       0       0       0       0       0       1       0       1       0
0       0       0       1       0       0       0       0       0       1       0       1
0       0       0       0       0       0       1       0       0       0       1       0

The Hamilton Cycle :

0 Hotel
1 Sci Mus
2 Toy Shop
3 Big Whl
4 Park
5 Zoo
6 Aqua
11 Cath
10 Castle
9 War Ship
8 Wax Works
7 Art Gal
0 Hotel

To automatically close the console when debugging stops, enable Tools->Options->Debugging->Automatically close the console when debugging stops.
Press any key to close this window . . .

这显然是不正确的,因为从美术馆返回酒店的路径是无效的。

我为图形制作的矩阵是否正确?

谁能告诉我哪里出了问题以及我需要做什么?

C# 图论 邻接矩阵 哈密顿循环

评论


答: 暂无答案