算法设计与分析:实验三 回溯法——地图填色问题

实验内容与要求:

问题描述:

我们可以将地图转换为平面图,每个地区变成一个节点,相邻地区用边连接,我们要为这个图形的顶点着色,并且两个顶点通过边连接时必须具有不同的颜色。附件是给出的地图数据,请针对三个地图数据尝试分别使用5个(le450_5a),15个(le450_15b),25个(le450_25a)颜色为地图着色。

实验要求:

对下面这个小规模数据,利用四色填色测试算法的正确性;

对附件中给定的地图数据填涂;

随机产生不同规模的图,分析算法效率与图规模的关系(四色)

基本回溯算法

思路

  • 从图的第一个节点开始,尝试为其染色。
  • 对于当前节点,尝试为其选择一种颜色,然后递归地尝试为其相邻的未染色节点染色。
  • 如果染色过程中出现了冲突,即当前节点与已染色的相邻节点颜色相同,就回溯到上一步重新尝试其他颜色。
  • 当所有节点都染色完毕,即递归到最后一个节点时,找到了一种合法的染色方案,返回 1。
  • 统计所有合法染色方案的数量,并返回结果。

 思维导图

伪代码

深搜回溯函数

  1. function DFS1(x):
  2.     // 如果已经遍历完所有节点,则返回 1 表示找到了一种合法的染色方案
  3.     if x > n:
  4.         return 1
  5.     cnt = 0
  6.     u = id[x] // 当前节点的编号
  7.     // 遍历尝试每一种颜色
  8.     for i from 1 to MAXCOL:
  9.         valid = true
  10.         // 遍历当前节点之前的节点(即染过的节点)
  11.         for j from 1 to x - 1:
  12.             // 如果当前节点与之前染色的节点相邻且颜色相同,则该颜色不合法
  13.             if link[u][id[j]] and color[id[j]] == i:
  14.                 valid = false
  15.                 break
  16.         // 如果当前颜色合法,则尝试用该颜色染色当前节点并继续递归
  17.         if valid:
  18.             color[u] = i // 尝试用颜色 i 染色节点 u
  19.             cnt += DFS1(x + 1) // 继续递归下一个节点
  20.     return cnt
  21. function Solve1():
  22.     // 初始化 color 数组,全部置为 0,表示未染色
  23.     initialize color array with zeros
  24.     // 调用深度优先搜索函数从第一个节点开始染色
  25.     return DFS1(1)

运行结果

由运行结果可以看出得到正确的填色方案数为480,但是运行时间为0.00ms,应该是因为数据规模较小,导致程序执行速度非常快,低于计时的精度。

算法过程:

在着色尝试过程中,依次尝试可用的颜色,并更新与当前节点相邻的节点的颜色状态,剔除不可用的颜色。若成功找到一种着色方案,即所有顶点都被成功着色,则返回 True。下面图示以其中一种染色方案为例(从左往右,从上往下):

 

时间复杂度

  • 在每一次递归调用 DFS1 中,对当前节点进行颜色的尝试,最多需要尝试 MAXCOL 种颜色,所以对于每一个节点,该部分的时间复杂度为 O(MAXCOL)。
  • 在每一次颜色尝试中,需要遍历当前节点的所有邻接节点,最坏情况下,有 x-1 个邻接节点,因此该部分的时间复杂度为 O(x)。
  • 因为递归调用会在每个节点处进行,总的递归调用次数最多为节点数量 x。
  • 因此,总的时间复杂度为 O(x * MAXCOL * x) = O(x^2 * MAXCOL)。即O(n^3),这是一个巨大的指数级别,如果节点数量较少,并且最大可选颜色数量也不是很大时,算法的性能是可以接受的,但是一旦数量增加就很难运行出结果,所以我们一定要对此回溯法进行优化。

 优化深搜回溯算法

四种深搜回溯优化剪枝优化搜索顺序,排除等效冗余,可行性剪枝和最优性剪枝。

  • 优化搜索顺序:通过合理的搜索顺序,优先探索最有希望的分支,可以尽早地找到解,从而减少搜索时间。
  • 排除等效冗余:在搜索过程中,避免探索等效的状态或者已经探索过的状态,以减少冗余的搜索。
  • 可行性剪枝:在搜索过程中,根据当前状态的局部信息,判断某些分支不可能产生解,从而减少不必要的搜索。
  • 最优性剪枝:在搜索过程中,根据问题的特性,通过一些启发式方法,提前排除掉不可能比当前最优解更好的分支,从而加速搜索过程。

在地图填色这个问题中,目标是为每个节点分配一个颜色,以使相邻节点的颜色不同,但通常不存在一个“最佳”的颜色分配方案。因此不存在最优解。所以使用到了前面三种剪枝方法,在下面的优化方法种会指明该种优化方法是属于哪一种优化方法。

最大度结点优先涂色(最大度优化-优化搜索顺序)

按照节点的度数从大到小进行排序,优先考虑处理度数较高的节点。这是因为度数较大的节点在填色过程中受到的约束更多,因此在确定其颜色时会更加复杂。当相邻节点的颜色选择较多且不相同时,度数较大的节点的可选颜色将会受到更大的限制,可能导致其剩余可填涂的颜色数量减少甚至为零。以实验样例为例,当4、7、8、9这四个节点各自填上不同的颜色时,节点6就会发现没有可选的颜色可以填充,从而需要进行回溯操作,这会导致时间的浪费。如果能够首先处理度数较大的节点6,就可以尽量避免这种情况,提高算法的效率。

伪代码

最大化优化DFS

  1. function DFS2(x):
  2.     if x > n:
  3.         return 1  
  4.     u = 0  
  5.     for i = 1 to n:
  6.         if not colored[i] and deg[i] > deg[u]:  // 如果节点未被着色且度数比当前最大度数大
  7.             u = id[i]  // 更新节点编号为当前节点编号
  8.     temp = 0  
  9.     for i = 1 to MAXCOL:  
  10.         valid = true  // 初始化当前颜色是否可用
  11.         for j = 1 to x - 1:  // 遍历已经着色的相邻节点
  12.             if link[u][id[j]] and color[id[j]] == i:  // 如果当前颜色与相邻节点的颜色相同
  13.                 valid = false  // 当前颜色不可用
  14.                 break  
  15.         if valid:  
  16.             color[u] = i  
  17.             temp += DFS2(x + 1)  // 递归调用DFS2,继续填充下一个节点的颜色
  18.             color[u] = 0  // 回溯,将当前节点颜色还原为未着色状态
  19.     return temp  // 返回当前节点的所有合法着色方案总数

剩余可填颜色数量最少的先涂(最少颜色优化-优化搜索顺序)

在给地图涂色的时候,优先选择先给剩余可填涂颜色比较少的点涂色。

  • 考虑对每一个点定义两个属性:一个属性表示剩余可填颜色的数量,另一个属性表示可以填充哪些颜色
  • 涂色时,先在所有的点中找到剩余可填涂颜色最少的点,遍历该点剩余可以填涂的颜色进行搜索。
  • 在涂完该点之后,需要对该点的临接点的两个属性——剩余可填涂颜色以及剩余可填涂颜色的数量,进行更新。
  • 在回溯时,需要对临接点的修改进行复原。

填涂颜色状态表示:使用二进制来表示使用一个二进制串来记录该点可以填涂的颜色有哪些,既二进制串中的第0位表示第一种颜色,第1位表示第二种颜色,该位为1时表示该点可以填涂该颜色,为0时表示该点不可以填涂该颜色。通过异或操作来填色(1^1=0),通过或操作来复原(1|0=1)。

伪代码:

最少颜色优化DFS

  1. function DFS3(x):
  2.     if x > n:  return 1
  3.     u = 0  
  4.     for i = 1 to n:  
  5.         if not color[i] and siz[i] < siz[u]:  // 如果节点未被着色且剩余可填涂颜色数量比当前最小值小
  6.             u = id[i]  // 更新节点编号为当前节点编号
  7.     cnt = 0  
  8.     for i = 1 to MAXCOL:  // 遍历所有颜色
  9.         if state[u] & (1 << (i - 1)):  // 如果当前颜色可用(二进制判断)
  10.             color[u] = i  // 将当前节点着色为当前颜色
  11.             limit = 1 << (i - 1)  // 当前颜色的限制
  12.             for j = 1 to n:  // 遍历所有邻接点
  13.                 if link[u][j] and not color[j] and (state[j] & limit):  // 如果相邻且未被着色,并且该颜色可用
  14.                     colored[u][j] = true  // 记录该点被染色(被更新了)
  15.                     state[j] = state[j] ^ limit  // 更新该点把1变成0
  16.                     siz[j]--  // 减少相邻点的可填涂颜色数量
  17.             cnt += DFS3(x + 1)  // 递归调用DFS3,继续填充下一个节点的颜色
  18.             color[u] = 0  // 回溯,将当前节点颜色还原为未着色状态
  19.             for j = 1 to n:  
  20.                 if colored[u][j]:  // 如果已被染色
  21.                     colored[u][j] = false  // 取消染色标记
  22.                     state[j] = state[j] | limit  // 把0变成1
  23.                     siz[j]++  // 恢复相邻点的可填涂颜色数量
  24.     return cnt  // 返回当前节点的所有合法着色方案总数
  25. function Solve3():
  26.     initialize color array with zeros  
  27.     initialize state array with -1  // 初始化状态数组为-1,表示所有节点都可以填充任意颜色
  28.     initialize colored array with false  // 初始化染色标记数组为false,表示所有相邻点未被染色
  29.     for i = 1 to n:
  30.         siz[i] = MAXCOL  // 初始化每个节点的剩余可填涂颜色数量为最大可填涂颜色数量
  31.     siz[0] = 100  
  32.     return DFS3(1)

基于最少颜色优化提前中断(可行性剪枝)

在最少颜色优化中的过程中,可以发现给一个点填上对应的颜色的时候,会使得对应的点的邻接点的可填涂颜色数量变少。而当某一个未涂色点的可填涂颜色数量被更新为0的时候,就表明该点已经不能在满足要求的情况下填色,所以没有必要继续搜索下去,而是可以直接让涂色点跳过该颜色找下一个颜色是否可以填涂。以实验样例为例,当4、7、5、8这四个节点各自填上不同的颜色时,当枚举节点8的邻点时就会发现节点6没有可选的颜色可以填充,此时节点8染红色的方案就没必要再递归下去直接剪掉即可,提高了算法的效率。

伪代码

基于最少颜色优化提前中断DFS

  1. function DFS4(x):
  2.     if x > n:  return 1  
  3.     u = 0
  4.     for i = 1 to n:
  5.         if not color[i] and siz[i] < siz[u]:  
  6.             u = id[i]  
  7.     cnt = 0  
  8.     for i = 1 to MAXCOL:  
  9.         if state[u] & (1 << (i - 1)):
  10.             color[u] = i  
  11.             flag = true  // 初始化标志位,表示当前方案是否合法
  12.             limit = 1 << (i - 1)
  13.             for j = 1 to n:  
  14.                 if link[u][j] and not color[j] and (state[j] & limit):  // 如果相邻且未被着色,并且该颜色可用
  15.                     colored[u][j] = true  // 记录该点被染色(被更新了)
  16.                     state[j] = state[j] ^ limit  // 更新该点把1变成0
  17.                     siz[j]--  // 减少相邻点的可填涂颜色数量
  18.                     if siz[j] == 0:  // 如果相邻点没有剩余可填涂颜色
  19.                         flag = false  // 当前方案不合法
  20.                         break  // 中断
  21.             if flag:  // 如果当前方案合法
  22.                 cnt += DFS4(x + 1)  // 递归调用DFS4,继续填充下一个节点的颜色
  23.             color[u] = 0  // 回溯,将当前节点颜色还原为未着色状态
  24.             for j = 1 to n:
  25.                 if colored[u][j]:
  26.                     colored[u][j] = false  
  27.                     state[j] = state[j] | limit  
  28.                     siz[j]++
  29.     return cnt

优先涂邻接点不能涂而该点可以涂的颜色(最小影响-优化搜素顺序)

对一个还没有涂色的点而言,为了让这个点涂的颜色对邻接点的影响尽可能的小(即尽可能不会影响邻接点剩余可填涂颜色),应该优先涂邻接点不能涂而该点可以涂的颜色。实现方式为在给一个点涂色的时候,先遍历邻接的点,对每一个邻接点的“邻接点不能涂而涂色点可以涂”的颜色进行计数,根据计数值从大到小排序,涂色点根据该顺序来遍历涂什么颜色,先选择邻接点不能涂而涂色点可以涂的数量最多的颜色。

最小影响DFS

  1. function DFS6(x):
  2.     if x > n:  return 1  
  3.     u = id[x]  
  4.     for i = 1 to MAXCOL:  // 初始化颜色计数值为0
  5.         col[i].second = i  // 颜色标号
  6.         col[i].first = 0  // 颜色计数值
  7.     for k = 0 to size of vmatrix[u]:  // 遍历当前节点的邻接节点
  8.         j = vmatrix[u][k]  // 获取当前邻接节点编号
  9.         if not color[j]:  // 如果邻接节点未被着色
  10.             for i = 1 to MAXCOL:  // 遍历所有颜色
  11.                 if (state[u] & (1 << (i - 1))) and not (state[j] & (1 << (i - 1))):  // 如果当前节点可以填涂颜色并且邻接节点不能填涂颜色
  12.                     col[i].first++  // 颜色计数值加一
  13.     sort col[] based on col[].first in ascending order  // 根据颜色计数值升序排序
  14.     cnt = 0
  15.     for i = MAXCOL to 1 DEC:  // 枚举计数大的颜色
  16.         ii = col[i].second  // 获取当前颜色标号
  17.         valid = true  
  18.         for j = 1 to x - 1:
  19.             if link[u][id[j]] and color[id[j]] == ii:  
  20.                 valid = false  
  21.                 break
  22.         if valid:
  23.             color[u] = ii  
  24.             cnt += DFS6(x + 1)  
  25.             color[u] = 0
  26.     return cnt

注意:该方法结合前面的优化一起使用,在选点时使用最大度优化和最少颜色优化,在填色时使用最小影响优化。即在尽可能找可选颜色最少的同时找度数尽可能大的点,在该点中选取填涂颜色的时候,先选择邻接点不能涂而涂色点可以涂的数量最多的颜色。

颜色对称性方案等效优化(排除等效冗杂)

根据排列组合数学的知识,当找到一个可行解并且使用了 M 种颜色时,将这个可行解的颜色互相调换一下可以得到另外的 M!−1 种可行解。例如如果只有3种颜色可以涂,则当找到上面的一种可行解的时候,就可以找到另外的3!-1种可行解。

如果可以找到所有“类型不同”的涂色方案可行解,那么就可以直接将每一种可行解乘上对应的M!,再累加起来就可以得到所有的可行解。

实际搜索中,要找到每一个不同类型的涂色方案并不容易,无法让搜索朝着找到每一个类型不同的涂色方案的方向搜索。因此,我们退而求其次,不再考虑所有节点的颜色组合,而是仅考虑初始节点、两个相邻节点以及三个节点的不同颜色组合。

处理思路:

根据节点数量的不同,分别处理不同的情况:

  • 如果节点数量为1,那么方案数为 MAXCOL,其中 MAXCOL 是可填颜色的最大种类数目。
  • 如果节点数量为2,那么方案数为 MAXCOL * (MAXCOL - 1)。
  • 如果节点数量大于2,按照一定策略先给图中的某些节点染色,然后计算剩余节点的涂色方案数。具体策略如下:
  1. 选择第一个节点(标号为1)并染上颜色1,更新与其相邻的节点的状态。
  2. 选择与节点1相邻度数最大的节点作为节点2,并染上颜色2,更新与其相邻的节点的状态。
  3. 再选择与节点1和2相邻度数最大的节点作为节点3,并染上颜色3,更新与其相邻的节点的状态。如果不存在这样的节点,则选择与节点1或2相邻且度数最大的节点作为节点3。
  4. 最后,计算剩余节点的涂色方案数,使用公式进行相乘即为总的涂色方案数。

伪代码:

颜色对称优化DFS

  1. function Solve8():
  2.        for each node i: // 初始化
  3.         color[i] = 0
  4.         state[i] = -1
  5.         for each adjacent node j of i:
  6.             colored[i][j] = false
  7.         siz[i] = MAXCOL
  8.     siz[0] = 100
  9.     ans = 0 // 计算涂色方案数
  10.     if n == 1:
  11.         ans = MAXCOL
  12.     else if n == 2:
  13.         ans = MAXCOL * (MAXCOL - 1)
  14.     else: // 给第一个节点染色为1,并更新相邻节点的状态
  15.         color[1] = 1
  16.         UpdateColor(1, 1)
  17.         // 选择与节点1相邻度数最大的节点作为节点2,并染色为2
  18.         u = 0
  19.         for each node i from 1 to n:
  20.             if link[1][i] and deg[u] < deg[i]:
  21.                 u = i
  22.         color[u] = 2
  23.         UpdateColor(u, 2)
  24.         // 选择与节点1和2相邻度数最大的节点作为节点3,并染色为3
  25.         v = 0
  26.         for each node i from 1 to n:
  27.             if link[u][i] and link[1][i] and deg[v] < deg[i]:
  28.                 v = i
  29.         if v == 0:
  30.             for each node i from 1 to n:
  31.                 if i != 1 and i != u and (link[i][u] or link[i][1]) and deg[v] < deg[i]:
  32.                     v = i
  33.             color[v] = 3
  34.             UpdateColor(v, 3)
  35.             ans = MAXCOL * (MAXCOL - 1) * (MAXCOL - 2) * DFS5(4)
  36.             RecoveryColor(v, 3)
  37.             color[v] = 1
  38.             UpdateColor(v, 1)
  39.             ans += MAXCOL * (MAXCOL - 1) * DFS5(4)
  40.         else:
  41.             color[v] = 3
  42.             UpdateColor(v, 3)
  43.             ans = MAXCOL * (MAXCOL - 1) * (MAXCOL - 2) * DFS5(4)
  44.     return ans

随机生成地图填色算法效率分析

图规模对运行时间的影响

点数为n,设边数为2*n,可填颜色种数为4。

每组规模个测试三次,取运行时间的平均值,运行结果如下图所示:

由上述图表可以知道,随着图规模的增大,算法的运行时间也相应增加。且当解的个数达到一定程度时,图规模大的运行时间显著增加。

这是因为在回溯算法中,每一层的节点对应着图中的一个节点,并且需要尝试填充不同的颜色。因此,随着图规模的扩大,图中节点的数量增加,导致回溯树的深度也随之增加。这样一来,整个回溯树的规模变得更大,算法需要更多的时间来遍历和搜索可能的解决方案。

图边数对运行时间的影响

点数为20,设边数为50、60、70、80,可填颜色种数为4,运行结果如下图所示:

由上面图表可知,当点数不变时,随着边数的增加,可行解数量减少,算法的运行时间也在减小。

这是因为在图的点数相同的情况下,图的边数增多会导致点的平均度数增多,图中的约束条件变得更加明显,因此可能的解决方案数量减少。

又因为在前面的基于最少颜色提前中断优化时,我们已知若某个点填了颜色c后将会使其相邻节点都无法填颜色c,就会把其相邻节点填颜色c的分枝剪掉。现在随着边数的增加,点的平均相邻点个数增多了,那么对于某个点来说,它能剪掉的分枝就变多了。而点数不变意味着回溯树形结构的层数不变。在回溯树形结构层数不变的情况下能剪掉的分枝变多了,减少了搜索空间的大小,因此算法的运行时间变小。

可填颜色数对运行时间的影响

点数为20,设边数为60,可填颜色种数为4、5、6、7。

由上图可知,随着可填颜色数的增加,可行解的个数也呈指数级增长。

这是因为增加了可选颜色的数量,使得每个节点的选择变得更加灵活,从而导致了更多的解的可能性。然而,这同时也导致了更多的搜索空间和更长的运行时间。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/52708.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

仿华为车机UI--图标从Workspace拖动到Hotseat同时保留图标在原来位置

基于Android13 Launcher3,原生系统如果把图标从Workspace拖动到Hotseat里则Workspace就没有了&#xff0c;需求是执行拖拽动作后&#xff0c;图标同时保留在原位置。 实现效果如下&#xff1a; 实现思路&#xff1a; 1.如果在workspace中拖动&#xff0c;则保留原来“改变图标…

Scratch教学案例-《三顾茅庐》:让编程学习如同故事般引人入胜

三顾茅庐-小虎鲸Scratch资源站 在编程的世界里&#xff0c;我们常常寻找那种既能激发创意&#xff0c;又能提升技能的学习方式。今天&#xff0c;小虎鲸Scratch资源站为您带来了一款独特的教学作品——《三顾茅庐》。这是一部将经典故事与编程教学巧妙结合的Scratch项目&#x…

在docker中安装skywalking + es

ES的版本和官网 es版本&#xff1a; Past Releases of Elastic Stack Software | Elastic es版本logstash版本JDK版本对应关系 支持一览表 | Elastic skywalking的版本说明和官网 Advanced deployment | Apache SkyWalking skywalking和es的对应关系&#xff0c;在网页的…

读书笔记:《深入理解Java虚拟机》(4)

垃圾收集器与内存分配策略 一、对象已死&#xff1f; 堆中几乎放着所有的对象实例&#xff0c;对堆垃圾回收前的第一步就是要判断哪些对象已经死亡&#xff08;即不能再被任何途径使用的对象&#xff09;。 引用计数法 给对象中添加一个引用计数器&#xff1a; 每当有一个…

day03-面向对象-内部类泛型常用API

一、内部类 内部类是类中的五大成分之一&#xff08;成员变量、方法、构造器、代码块、内部类&#xff09; 如果一个类定义在另一个类的内部&#xff0c;这个类就是内部类。 场景&#xff1a;当一个类的内部&#xff0c;包含了一个完整的事物&#xff0c;且这个事物没有必要单…

bitmap(位图)的使用

零存零取&#xff0c;整存零取&#xff0c;整存整取, 零存整取 bitmap介绍 位图不是真正的数据类型&#xff0c;它是定义在字符串类型中,一个字符串类型的值最多能存储512M字节的内容, 位上限&#xff1a;2^(9(512)10(1024)10(1024)3(8b1B))2^32b 语句操作&#xff1a; s…

[报错] nvcc -V 找不到

报错&#xff1a; nvcc : 无法将“nvcc”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写&#xff0c;ObjectNotFound: (nvcc:String) [], CommandNotFoundExceptionFullyQualifiedErrorId : CommandNotFoundException 找不到 nvcc -V&#xff0c;试过…

鸿蒙(API 12 Beta5版)【通过文本生成码图】

基本概念 码图生成能力支持将字符串转换为自定义格式的码图。 场景介绍 码图生成能力支持将字符串转换为自定义格式的码图&#xff0c;包含条形码、二维码生成。 可以将字符串转成联系人码图&#xff0c;手机克隆码图&#xff0c;例如将"HUAWEI"字符串生成码图使…

深度学习系列71:表格检测和识别

1. pdf处理 如果是可编辑的pdf格式&#xff0c;那么可以直接用pdfplumber进行处理&#xff1a; import pdfplumber import pandas as pdwith pdfplumber.open("中新科技&#xff1a;2015年年度报告摘要.PDF") as pdf:page pdf.pages[1] # 第一页的信息text pag…

【开端】基于nginx部署的具有网关的web日志分析

一、绪论 基于nginx部署的具有网关的web日志分析&#xff0c;我们可以分析的日志有nginx的access.log &#xff0c;网关的日志和应用的日志 二、日志分析 1、nginx日志 参数 说明 示例 $remote_addr 客户端地址 172.17.0.1 $remote_user 客户端用户名称 -- $time_lo…

Datawhale AI夏令营

一、物体检测算法 物体检测算法主要分为两类&#xff1a;One-Stage&#xff08;一阶段&#xff09;和Two-Stage&#xff08;两阶段&#xff09;模型。 二、One-Stage目标检测算法 定义&#xff1a;One-Stage目标检测算法是一种直接在图像上进行目标检测的方法&#xff0c;无…

数字化转型升级探索(二)

在数字化转型升级的探索中&#xff0c;我们计划通过整合前沿技术如人工智能、物联网和大数据&#xff0c;全面改造传统业务流程&#xff0c;打造智能化、数据驱动的业务架构&#xff0c;实现从数据采集、处理到分析的全链条数字化&#xff0c;以提升决策效率、优化运营管理&…

C++和QT

什么是QT Qt 是一个跨平台的 C图形用户界面应用程序框架。 它为应用程序开发者提供建立艺术级图形界面所需的所有功能。 它是完全面向对象的&#xff0c;很容易扩展&#xff0c;并且允许真正的组件编程。 QT的优点 跨平台&#xff0c;几乎支持所有的平台 接口简单&#x…

pandas操作Excel文件

pandas操作Excel文件 一、前言二、指定读取的工作表与header设置2.1指定工作表2.2header设置 三、读取Excel数据3.1iloc读取数据3.2read_excel读取数据3.3loc读取数据 四、DataFrame数据筛选4.1根据列标签对整列进行筛选4.2使用iloc对区域进行筛选4.3自定义筛选 五、DataFrame类…

【GPT】Coze使用开放平台接口-【6】Dify 也来一遍

前面讲了 coze 的相关用法&#xff0c;这边想着用 Dify 也来一遍&#xff0c;刚开始的时候接触的是 Dify&#xff0c;后面才是 coze。Dify 和 coze 的侧重点不同&#xff0c;我个人是更倾向用 Dify 构建工作流就可以了&#xff0c;coze 还是相对全能。 本节用 Dify 也会创建插…

Linux文件IO缓存

一、缓冲区大小对 I/O 系统调用性能的影响 总之&#xff0c;如果与文件发生大量的数据传输&#xff0c;通过采用大块空间缓冲数据&#xff0c;以及执行更少的 系统调用&#xff0c;可以极大地提高 I / O 性能 二、stdio 库的缓冲 当操作磁盘文件时&#xff0c;缓冲大块数据以…

ArcGIS Pro技术应用

GIS是利用电子计算机及其外部设备&#xff0c;采集、存储、分析和描述整个或部分地球表面与空间信息系统。简单地讲&#xff0c;它是在一定的地域内&#xff0c;将地理空间信息和 一些与该地域地理信息相关的属性信息结合起来&#xff0c;达到对地理和属性信息的综合管理。GIS的…

Hreflang 和 SEO:新手完整指南

每天&#xff0c;数以百万计的法国用户访问像 Amazon.com 这样的全球网站。虽然 Amazon.com 的官方页面是英文的&#xff0c;但用户仍然可以看到法语的文本和产品描述。这是因为亚马逊的全球网站有针对法国的本地化版本&#xff0c;确保所有法国用户都可以自动看到法语的网站内…

五种多目标优化算法(NSGA3、MOPSO、MOGWO、NGSA2、SPEA2)性能对比,包含47个多目标测试函数,6种评价指标,MATLAB代码

一、五种多目标算法及六种评价指标简介 多目标灰狼优化算法&#xff08;MOGWO&#xff09;&#xff1a; MOGWO是由Mirjalili等人在2016年提出的&#xff0c;基于灰狼优化算法&#xff08;GWO&#xff09;的多目标版本。它引入了存档机制和改进的头狼选择方式&#xff0c;以处理…

uniapp(微信小程序如何使用单选框、复选框)

一、先看效果 二、数据结构 说明&#xff1a;selected用来记录每次用户选择的值&#xff0c;当是单选的时候属性中的selected属性需要设置成字符串&#xff0c;当是复选框的时候&#xff0c;此时选择的是数组&#xff0c;selected属性应设置为数组。type用来区分当前是单选还是…