DFS算法及应用(一)

简介: DFS(深度优先搜索)是一种图遍历算法,常用于解决穷举问题,如全排列、迷宫问题、图的连通性等。它沿着树的深度分支进行探索,直至达到叶子节点,若无法继续则回溯。例如,将数字6拆分为3个正整数的递增序列问题可以通过DFS实现,类似地,分糖果问题和买瓜问题同样可以用DFS求解。DFS通常涉及递归或栈结构,通过标记已访问节点避免重复。在编程中,会定义递归函数,设定结束条件,然后枚举可能的情况,并处理下一层节点。

DFS简介


搜索算法:穷举问题解空间所有情况


深度优先搜索:既暴力枚举,尽可能一条路走到底,走不了再回退


给定一个数字x,将其拆分成3个正整数,后一个要求大于等于前一个,给出方案.


  • 就需要实现n重循环
  • n重循环=特定的树状结构=DFS搜索


给定一个数字x=6,将其拆分成3个正整数,后一个要求大于等于前一个,给出方案。



DFS模板


def dfs(depth):
    
    if depth == n:
        # 递归的出口
        return
 
    # 每次循环做的枚举操作


例题:


分糖果


两种糖果分别有9个和16个,要全部分给7个小朋友,每个小朋友得到的糖果总数最少为2个最多为5个,问有多少种不同的分法。糖果必须全部分完。两种糖果分别有9个和16个,要全部分给7个小朋友,每个小朋友得到的糖果总数最少为2个最多为5个,问有多少种不同的分法。糖果必须全部分完。


ans = 0  # 方案数
 
 
def dfs(depth, n, m):     # 每一层都有枚举
    # depth 第几个小朋友
    # n,m为剩余量
    if depth == 7:   # 不管还剩多少,dfs都结束了,如果剩余为零则说明ans加一
        if n == 0 and m == 0:
            global ans
            ans += 1
        return
    for i in range(0, 6):
        for j in range(0, 6):   # i+j是第一个小朋友的全部糖
            if 2 <= i + j <= 5 and i <= n and j <= m:
                dfs(depth + 1, n - i, m - j)
 
dfs(0,9,16)
print(ans)
 
# 5067671


在写dfs函数时,要先写出递归的结束深度,以及在此处的判断,然后写出分糖果的一一枚举情况,最后写出下一层(下一个小朋友)的情况。


买瓜


小蓝正在一个瓜摊上买瓜。瓜摊上共有n个瓜,每个瓜的重量为A;小蓝刀功了得,他可以把任何瓜劈成完全等重的两份,不过每个瓜只能劈一刀。小蓝希望买到的瓜的重量的和恰好为m。请问小蓝至少要劈多少个瓜才能买到重量恰好为m的瓜。如果无论怎样小蓝都无法得到总重恰好为m 的瓜,请输出—1。


输入的第一行包含两个整数n,m,用一个空格分隔,分别表示瓜的个数和小蓝想买到的瓜的总重量。


第二行包含n个整数A,相邻整数之间使用一个空格分隔,分别表示每个瓜的重量。



def dfs(depth, weight, cnt):   # 写之前要明确参数,这是第几个瓜,目前买到的质量是多少,目前劈瓜几次
    # 第depth个瓜
    # 当前买到瓜的重量
    # 劈了多少次
 
    # 剪枝
    if weight > m:    # 剪枝的出口
        return
    if weight == m:
        global ans
        ans = min(ans, cnt)
    if depth == n:   # 正常的出口
        return
 
    # 不买
    dfs(depth + 1, weight, cnt)
    # 买
    dfs(depth + 1, weight + A[depth], cnt)
    # 卖一半
    dfs(depth + 1, weight + A[depth] // 2, cnt + 1)
 
 
n, m = map(int, input().split())   # 买n个瓜,希望买到的总质量为m
m *= 2
A = list(map(int, input().split()))
A = [x * 2 for x in A]
ans = n + 1  # 表示每个挂=瓜都劈一次
dfs(0, 0, 0)
if ans == n + 1:
    ans = -1
print(ans)
 


  • 为了避免除以二造成的精确度缺失,我们对小蓝所期望的总质量m和每个瓜的质量A乘以二,可以默认劈瓜的次数为n+1,如果递归搜索完成还没有得到m,就让ans等于-1。


  • 同理depth,weight,cnt分别代表了轮到了第几个瓜,当前搜索到的总质量,劈瓜的次数。


  • 我们先写出函数的结束,既depth == n ,然后到了枚举阶段,上个案例是每次分给小朋友的糖果数,这次是根据劈不劈瓜分成三种情况。最后还有剪枝的回退,写入前段部分。


3 10

1 3 13

2



DFS算法及应用(二)+https://developer.aliyun.com/article/1544415?spm=a2c6h.13148508.setting.18.1fa24f0eaie4S4

相关文章
|
3天前
|
存储 自然语言处理 算法
位运算入门及简单算法题的应用
位运算入门及简单算法题的应用
11 1
|
2天前
|
算法 程序员 数据处理
【数据结构与算法】使用单链表实现队列:原理、步骤与应用
【数据结构与算法】使用单链表实现队列:原理、步骤与应用
|
2天前
|
存储 算法 编译器
【数据结构与算法】使用数组实现栈:原理、步骤与应用
【数据结构与算法】使用数组实现栈:原理、步骤与应用
|
2天前
|
存储 算法
【数据结构和算法】---二叉树(2)--堆的实现和应用
【数据结构和算法】---二叉树(2)--堆的实现和应用
5 0
|
3天前
|
算法 Java
Java数据结构与算法:图算法之深度优先搜索(DFS)
Java数据结构与算法:图算法之深度优先搜索(DFS)
|
6天前
|
算法 索引
DFS算法及应用(二)
回溯:回溯就是DFS的一种,在搜索探索过程中寻找问题的解,当发现不满足求解条件时,就回溯返回,尝试其他路径。
|
6天前
|
算法
KNN算法原理及应用(二)
不能将所有数据集全部用于训练,为了能够评估模型的泛化能力,可以通过实验测试对学习器的泛化能力进行评估,进而做出选择。因此需要使用一个测试集来测试学习器对新样本的判别能力。
|
2天前
|
机器学习/深度学习 自然语言处理 算法
m基于深度学习的OFDM+QPSK链路信道估计和均衡算法误码率matlab仿真,对比LS,MMSE及LMMSE传统算法
**摘要:** 升级版MATLAB仿真对比了深度学习与LS、MMSE、LMMSE的OFDM信道估计算法,新增自动样本生成、复杂度分析及抗频偏性能评估。深度学习在无线通信中,尤其在OFDM的信道估计问题上展现潜力,解决了传统方法的局限。程序涉及信道估计器设计,深度学习模型通过学习导频信息估计信道响应,适应频域变化。核心代码展示了信号处理流程,包括编码、调制、信道模拟、降噪、信道估计和解调。
23 8
|
4天前
|
算法
基于GA遗传优化的混合发电系统优化配置算法matlab仿真
**摘要:** 该研究利用遗传算法(GA)对混合发电系统进行优化配置,旨在最小化风能、太阳能及电池储能的成本并提升系统性能。MATLAB 2022a用于实现这一算法。仿真结果展示了一系列图表,包括总成本随代数变化、最佳适应度随代数变化,以及不同数据的分布情况,如负荷、风速、太阳辐射、弃电、缺电和电池状态等。此外,代码示例展示了如何运用GA求解,并绘制了发电单元的功率输出和年变化。该系统原理基于GA的自然选择和遗传原理,通过染色体编码、初始种群生成、适应度函数、选择、交叉和变异操作来寻找最优容量配置,以平衡成本、效率和可靠性。
|
5天前
|
机器学习/深度学习 算法
基于鲸鱼优化的knn分类特征选择算法matlab仿真
**基于WOA的KNN特征选择算法摘要** 该研究提出了一种融合鲸鱼优化算法(WOA)与K近邻(KNN)分类器的特征选择方法,旨在提升KNN的分类精度。在MATLAB2022a中实现,WOA负责优化特征子集,通过模拟鲸鱼捕食行为的螺旋式和包围策略搜索最佳特征。KNN则用于评估特征子集的性能。算法流程包括WOA参数初始化、特征二进制编码、适应度函数定义(以分类准确率为基准)、WOA迭代搜索及最优解输出。该方法有效地结合了启发式搜索与机器学习,优化特征选择,提高分类性能。