• C#,图颜色问题(MCP,M-coloring problem)的回溯(Backtracking)算法与源代码


     给定一个无向图和一个数字m,确定该图是否最多可以使用m种颜色着色,以确保该图的两个相邻顶点没有使用相同的颜色着色。这里,图的着色意味着将颜色分配给所有顶点。
    输入:
    二维数组图[V][V],其中V是图中的顶点数,图[V][V]是图的邻接矩阵表示。如果从i到j有一条直边,则值图[i][j]为1,否则图[i][j]为0。
    整数m是可以使用的最大颜色数。
    输出:
    数组颜色[V]的数字应为1到m。颜色[i]应表示指定给第i个顶点的颜色。如果图形不能用m颜色着色,代码也应该返回false。

    我们将使用回溯来解决上述问题。

    回溯是通过测试所有可能的组合来解决问题的方法。如果有任何子问题不符合给定的约束,那么我们将放弃完整的子问题(回溯),后退一步,然后尝试其他可能的组合。回溯算法在时间上通常是指数的。

    我们将使用颜色数组color[]来存储M种颜色。现在遍历颜色[],然后将每个颜色逐个指定给所有顶点。如果任何颜色分配与约束不匹配,则我们将回溯并取消分配先前分配给顶点的颜色。如果顶点计数达到顶点总数,我们将返回true,如果任何赋值都不符合给定条件(相邻顶点必须具有不同的颜色),那么我们将返回false。

    递归:

    在for a循环的帮助下尝试从1到m的每种颜色。

    如果可以使用该颜色对其进行着色,即相邻节点均不具有相同的颜色,则Is safe函数将返回true。

    如果这是一个算法并遵循某种直觉,请提及它。

    将其着色,然后调用下一个节点的递归函数,如果它返回true,我们将返回true。

    如果为假,则去掉颜色。

    现在,如果我们已经尝试了从1到m的每种颜色,并且不可能用m种颜色中的任何一种来着色,那么返回false。

     

    源程序(POWER BY TRUFFER):

    1. using System;
    2. using System.Text;
    3. using System.Collections;
    4. using System.Collections.Generic;
    5. namespace Legalsoft.Truffer.Algorithm
    6. {
    7. public class MCP_Node
    8. {
    9. public int color { get; set; } = 1;
    10. public HashSet<int> edges { get; set; } = new HashSet<int>();
    11. }
    12. public static partial class Algorithm_Gallery
    13. {
    14. private static int Vertex_Number = 4;
    15. #region 算法1
    16. private static bool MCP_IsSafe(bool[,] graph, int[] color)
    17. {
    18. for (int i = 0; i < Vertex_Number; i++)
    19. {
    20. for (int j = i + 1; j < Vertex_Number; j++)
    21. {
    22. if (graph[i, j] && color[j] == color[i])
    23. {
    24. return false;
    25. }
    26. }
    27. }
    28. return true;
    29. }
    30. public static bool MCP_Solve(bool[,] graph, int m, int i, int[] color)
    31. {
    32. if (i == Vertex_Number)
    33. {
    34. if (MCP_IsSafe(graph, color))
    35. {
    36. return true;
    37. }
    38. return false;
    39. }
    40. for (int j = 1; j <= m; j++)
    41. {
    42. color[i] = j;
    43. if (MCP_Solve(graph, m, i + 1, color))
    44. {
    45. return true;
    46. }
    47. color[i] = 0;
    48. }
    49. return false;
    50. }
    51. #endregion
    52. #region 算法2
    53. private static bool MCP_IsSafe(int v, int[,] graph, int[] color, int c)
    54. {
    55. for (int i = 0; i < Vertex_Number; i++)
    56. {
    57. if (graph[v, i] == 1 && c == color[i])
    58. {
    59. return false;
    60. }
    61. }
    62. return true;
    63. }
    64. private static bool MCP_Solve_Utility(int[,] graph, int m, ref int[] color, int v)
    65. {
    66. if (v == Vertex_Number)
    67. {
    68. return true;
    69. }
    70. for (int c = 1; c <= m; c++)
    71. {
    72. if (MCP_IsSafe(v, graph, color, c))
    73. {
    74. color[v] = c;
    75. if (MCP_Solve_Utility(graph, m, ref color, v + 1))
    76. {
    77. return true;
    78. }
    79. color[v] = 0;
    80. }
    81. }
    82. return false;
    83. }
    84. private static bool MCP_Solve(int[,] graph, int m)
    85. {
    86. int[] color = new int[Vertex_Number];
    87. for (int i = 0; i < Vertex_Number; i++)
    88. {
    89. color[i] = 0;
    90. }
    91. if (MCP_Solve_Utility(graph, m, ref color, 0) == false)
    92. {
    93. return false;
    94. }
    95. return true;
    96. }
    97. #endregion
    98. #region 算法3
    99. public static bool MCP_Solve(List<MCP_Node> nodes, int n, int m)
    100. {
    101. List<int> visited = new List<int>();
    102. for (int i = 0; i < n + 1; i++)
    103. {
    104. visited.Add(0);
    105. }
    106. int maxColors = 1;
    107. for (int sv = 1; sv <= n; sv++)
    108. {
    109. if (visited[sv] > 0)
    110. {
    111. continue;
    112. }
    113. visited[sv] = 1;
    114. Queue q = new Queue();
    115. q.Enqueue(sv);
    116. while (q.Count != 0)
    117. {
    118. int top = (int)q.Peek();
    119. q.Dequeue();
    120. foreach (int it in nodes[top].edges)
    121. {
    122. if (nodes[top].color == nodes[it].color)
    123. {
    124. nodes[it].color += 1;
    125. }
    126. maxColors = Math.Max(maxColors, Math.Max(nodes[top].color, nodes[it].color));
    127. if (maxColors > m)
    128. {
    129. return false;
    130. }
    131. if (visited[it] == 0)
    132. {
    133. visited[it] = 1;
    134. q.Enqueue(it);
    135. }
    136. }
    137. }
    138. }
    139. return true;
    140. }
    141. #endregion
    142. }
    143. }

  • 相关阅读:
    算法笔记:堆
    C++代码示例:排列数简单生成工具
    React中封装echarts图表组件以及自适应窗口变化
    《Spring安全配置》
    找实习之从0开始的后端学习日记【9.17】
    「PAT乙级真题解析」Basic Level 1109 擅长C (问题分析+完整步骤+伪代码描述+提交通过代码)
    solr-7.7.3 搭建
    Thread.currentThread().getName() 和 this.getName()区别详解
    OpenRoads导出FBX体积为0kb问题解决
    华为OD机试 - 机器人搬砖(Java & JS & Python & C)
  • 原文地址:https://blog.csdn.net/beijinghorn/article/details/125438593