Dancing Links + A* 应用于精确覆盖、重复覆盖

Dancing Links X(跳舞链) 双向十字交叉循环链表求解精确覆盖、重复覆盖。 骨牌覆盖、N皇后问题的高效解法。 阅读详情

      Dancing Links是由Knuth提出的用于一类搜索问题的通用优化。

      或称DLX。

      主要应用于精确覆盖和重复覆盖。

 

      精确覆盖题目:

      POJ3740、POJ3074、POJ3076、HDU4069

      重复覆盖题目:

      HDU3529、HDU2295、POJ1084

 

      关于DLX的详细介绍可以去查阅相关资料。

      假设一个0-1矩阵,要求选择某几个行,使得所有的列均只有一个1(精确覆盖),或者至少有一个1(重复覆盖)。

      DLX使用双向链表极大地优化了搜索。

      DLX可以说是一种模板。应用于一类题目。只要把问题建模转化为一定的格式,则可以应用DLX。

      精确覆盖应用于解数独、八皇后等。据说目前解数独速度最快的就是DLX。

      重复覆盖应用于类似雷达覆盖的问题。

     

      精确覆盖模板:

     

void remove(const int &c)
{
	l[r[c]] = l[c];
	r[l[c]] = r[c];
	int i, j;
	for (i=d[c]; i!=c; i=d[i])
	{
		for (j=r[i]; j!=i; j=r[j])
		{
			u[d[j]] = u[j];
			d[u[j]] = d[j];
			s[ch[j]]--;
		}
	}
}

void resume(const int &c)
{
	int i, j;
	for (i=u[c]; i!=c; i=u[i])
	{
		for (j=l[i]; j!=i; j=l[j])
		{
			s[ch[j]]++;
			u[d[j]] = j;
			d[u[j]] = j;
		}
	}
	l[r[c]] = c;
	r[l[c]] = c;
}

bool dfs(const int &k)
{
	if (r[head]==head)
	{
		return true;
	}
	int ss = INT_MAX;
	int c;
	int i, j;
	for (i=r[head]; i!=head; i=r[i])
	{
		if (s[i]<ss)
		{
			ss = s[i];
			c = i;
		}
	}
	remove(c);
	for (i=d[c]; i!=c; i=d[i])
	{
		o[k] = rh[i];
		len = k;
		for (j=r[i]; j!=i; j=r[j]) remove(ch[j]);
		if (dfs(k+1)) return true;
		for (j=l[i]; j!=i; j=l[j]) resume(ch[j]);
	}
	resume(c);
	return false;
}

 

      重复覆盖模板:

 

void remove(int c)
{
    int i;
    for (i=d[c]; i!=c; i=d[i])
    {
        l[r[i]] = l[i];
        r[l[i]] = r[i];
    }
}

void resume(int c)
{
    int i;
    for (i=u[c]; i!=c; i=u[i])
    {
        l[r[i]] = r[l[i]] = i;
    }
}

int h()
{
    memset(used, false, sizeof(used));
    int c, i, j;
    int ret = 0;
    for (c=r[head]; c!=head; c=r[c])
    {
        if (!used[c])
        {
            ret++;
            used[c] = true;
            for (i=d[c]; i!=c; i=d[i])
            {
                for (j=r[i]; j!=i; j=r[j])
                {
                    used[ch[j]] = true;
                }
            }
        }
    }
    return ret;
}

void dfs(int k)
{
    if (k+h()>=len)//启发式搜索
        return;
    if (r[head]==head)
    {
        len = k;
        return;
    }
    int ss = INT_MAX;
    int c, i, j;
    for (i=r[head]; i!=head; i=r[i])
    {
        if (s[i]<ss)
        {
            ss = s[i];
            c = i;
        }
    }
    for (i=d[c]; i!=c; i=d[i])
    {
        remove(i);
        for (j=r[i]; j!=i; j=r[j]) remove(j);
        dfs(k+1);
        for (j=l[i]; j!=i; j=l[j]) resume(j);
        resume(i);
    }
}

      共用部分:

 

int new_node(int up, int down, int left, int right)
{
    l[size] = left;
    r[size] = right;
    u[size] = up;
    d[size] = down;
    l[right] = r[left] = u[down] = d[up] = size;
    return size++;
}

void init(int n, int m)
{
    size = 0;
    head = new_node(0, 0, 0, 0);
    len = n;
    int i;
    for (i=1; i<=m; i++)
    {
        new_node(i, i, l[head], head);
        ch[i] = i;
        s[i] = 0;
    }
    for (i=0; i<=n; i++)
        rh[i] = -1;
}

void insert_node(int i, int j)
{
    ch[size] = j;
    s[j]++;
    if (rh[i]==-1)
    {
        rh[i] = new_node(j, d[j], size, size);
    }
    else
    {
        new_node(j, d[j], rh[i], r[rh[i]]);
    }
}

      DLX一般难在建模。只要建好模,一切都好办。

      不过有些题目建模过程极其猥琐……比如POJ1084……


      题解:

     

      POJ3740:精确覆盖的基本题目。

      POJ3074、POJ3076:数独的基本题目。把数组转化为01矩阵再进行DLX。

      HDU4069:数独小变种,只是块的部分改变了,影响不大。

 

      HDU3529:以空格为行,障碍为列,进行重复覆盖即可。

      HDU2295:NC的我,由于一个字母打错,TLE了10次,然后精度问题WA了3次,还有一个CE,最终AC……二分雷达的半径进行重复覆盖,以雷达为行,以城市为列。

      POJ1084:超恶心的一道题目。重复覆盖。以火柴为行,以方格为列。若某火柴支配某个方格(可多个方格),则标记为1。题目恶心在,方格的边长必须从小到大排列;如果从大到小排列的话,超时没话说。做这道题耗时n天,期间感冒……

     

探索与精确覆盖:算法的实现与应用 本章介绍了通过穷举搜索解决激光问题的方法,以及精确覆盖问题的算法实现。详细描述了激光问题转化为完美匹配问题的过程,以及如何使用穷举搜索算法和‘跳舞链接’算法求解精确覆盖问题。通过构造稀疏矩阵并使用双链表进行高效存储,展示了算法在Sudoku和铺瓷砖问题中的应用。 阅读详情

相关推荐

解密数学问题:精确覆盖与算法实践

本文探讨了在数论和算法领域中精确覆盖问题的解决方案与应用。通过分析不同类型的数学问题,如Mendelsohn三元组、斯坦纳三元组系统以及八皇后问题,本文深入解析了如何通过算法求解这类问题。同时,文中还介绍了算法在实际问题中的应用,例如单词搜索谜题的构造与解法,并通过实例展示了算法在解决这些问题中的效率和可行性。

weixin_29323977的博客 364

精确覆盖问题

精确覆盖问题(Exact Cover Problem),指给定许多集合Si(1≤i≤n)S_i\left(1\le i\le n\right)Si​(1≤i≤n), 以及集合X⊂SX\subset SX⊂S,求满足以下条件的无序多元组(T1,T2,⋯ ,Tm)\left(T_1,T_2,\cdots,T_m\right)(T1​,T2​,⋯,Tm​):(001011010010010110010100100001000010001101) \left(\begin{array}{lllllll} 0 & 0

思维缜密的博客 1484

探索数学游戏中的精确覆盖问题

本文深入探讨了数学游戏,特别是与五格骨牌和六格骨牌相关的精确覆盖问题。文章详细分析了如何通过特定的算法和程序设计来解决这类问题,并提供了多种解决方案,包括减少对称性,从而简化计算过程。此外,还讨论了如何将问题转化为矩阵计算,以达到快速寻找解决方案的目的。

weixin_42575505的博客 273

利用DeepSeek辅助改造精确覆盖问题的例子求解数独

本文介绍了一个使用精确覆盖算法(Exact Cover)求解数独的Python实现。程序通过建立元素与子集之间的映射关系,采用深度优先搜索策略找到精确覆盖解。核心类ExactCoverOfSt实现了精确覆盖问题的求解框架,solve_sudoku函数将其应用于数独问题的转换和求解。程序还支持从文件读取数独题目,在1000道17个已知数的测试中仅耗时6秒,效率与C语言的DLX算法相当。文章同时指出代码在不同Python版本中的类型注解兼容性问题,如在Python 3.8中list[int]类型会报错。

l1t的专栏 398

【随机过程】Markov Chain的定义及发展历程与实际应用

本模块书写的初衷:由于在学习张波张景肖等学者所著的《应用随机过程》存在着不甚了解的知识点,经过个人查找资料并整理、分享,希望能够为有同样疑惑的读者贡献绵薄之力,同时如果个人编写内容有错误,恳请读者指正。本文为对《应用随机过程》第42页中Markov Chain基本概念的补充。1.Markov Chain的定义俄国数学家 Andrey Andreyevich Markov 研究并提出一个用数学方法就能解释自然变化的一般规律模型,被命名为马尔科夫链(Markov Chain)。

qq_49657150的博客 3742

学生党投稿Applied Soft Computing:从导师账号登录到通讯作者设置的全流程解惑

本文详细解析了学生投稿Applied Soft Computing期刊的全流程,重点介绍了导师账号登录、通讯作者设置、作者排序调整以及开放获取费用等关键环节的避坑技巧。针对LaTeX稿件处理和财务选项选择提供了实用建议,帮助学生顺利完成SCI期刊投稿。

weixin_30352191的博客 210

DANCING LINKS解决重复覆盖问题

问题描述: 给定一个n*m的矩阵,有些位置为1,有些位置为0。如果G[i][j]==1则说明i行可以覆盖j列。 Problem: 1)选定最少的行,使得每列有且仅有一个1. 2)选定最少的行,使得每列至少一个1. DLX原理: 这类属于NP问题的问题,可以使用搜索解决。但是普通的搜索必超时无疑。因此我们要设法加优化来加快速度。 Dancing Links从数据结构方面对此类搜索进行了

The_star_is_at的博客 1210

AFSim编译一:windows

AFSim在windows上的编译

Meepo的博客 4734

dancing links详解

Dancing links是一种能高效实现Knuth的X算法的技术,它可以使很多搜索问题得到极大的优化。 假设x是一个双向链表中的一个节点,L[x]表示X的前驱,R[x]表示x的后继, 则R[L[x]] = R[x], L[R[x]] = L[x]这一操作可以把x从链表中移除,这是众所周知的, 当然,一个细致的程序员还会用 L[x] = R[x] = x或 L[x] = R[x] = NUL

sunny606的专栏 8535

【UE5.3 Cesium for Unreal】GlobePawn编译实战:从源码修改到功能实现

本文详细介绍了在UE5.3中为Cesium for Unreal插件编译和集成非官方增强组件GlobePawn的完整实战流程。从获取源码、准备资产文件、部署项目结构,到逐行修改代码适配工程并解决典型编译错误,最终实现在三维地球上实现类似Google Earth的丝滑鼠标交互体验。

weixin_29011667的博客 307

大数据之数据抽取架构演变过程

而当时我们搭建的Flink集群是基于YARN进行资源管理和调度的,因为YARN中不仅仅包含着FLInk的资源,也有hive,zoozie,hdfs等等的资源,这样容易造成yarn资源的过度使用,容易引起整个底座的cpu以及内存的使用问题,经过排查,主要是由于FLink的使用资源引起的,所以后续就把Flink从整个集群中剥离出来,进行资源的隔离,最后Flink采用了StandAlone HA部署(但是这个目前还是存在问题,后续根据项目进行优化)'topic' = '表名',二、数据抽取架构的演变。

天道酬勤 866

舞蹈链(Dancing Links) 精确覆盖和重复覆盖模板

首先是精确覆盖 这个是洛谷的模板题 舞蹈链的说明网上很多,我就不再赘述了。 简单地说,精确覆盖就是确定一个矩阵中选出某几行,每一列的1值只在1个行中出现过,也就是任意两行的列交集为空。 那么大致思路就是递归,先选出一行将所有其他行中与这一行中列冲突的都删掉,然后剩下的元素组成一个矩阵,继续刚才的过程。如果这一行是不行的,那么就换一行。用一个十字链表维护当前矩阵。非常优秀的算法。 deep就是当前取...

天翼之城的博客 949

在Simulink中实现基于深度强化学习的控制算法仿真建模

通过上述步骤,你可以在Simulink中实现基于深度强化学习的控制算法仿真建模。这种方法适用于许多复杂的控制问题,尤其是当传统控制方法难以找到有效解决方案时。随着经验的积累,你可以进一步探索不同的深度强化学习算法及其变种,以适应更广泛的应用场景。此外,还可以结合其他先进技术(如迁移学习、多智能体协作等),提升模型的表现能力。

amy_mhd的博客 414

Sudoku 数独 Dancing Links模板

推荐论文: momodi的《Dancing Links 在搜索中的应用》、Knuth的DLX论文、陈丹琦的《Dancing Links的应用》   Dancing Links是用来优化一类精确覆盖问题中的DFS过程。 精确覆盖问题是指在一个01矩阵中,选出一些行使每一列有且

魔神翼 3348

【AI 编程工具】Codex配置部署指南

目录一、环境准备与基础安装1. 系统兼容性检查2. 前置依赖安装3. 安装方式选择二、API密钥配置与认证1. 获取API密钥2. 配置文件设置3. 临时配置方式三、沙盒环境配置与安全策略1. 沙盒模式选择2. 安全最佳实践四、高级功能配置1. 模型上下文协议(MCP)配置2. 模型版本切换3. 自定义网关配置五、常见问题排查1. 安装失败2. API调用失败3. 处理速度慢4. 配置文件不生效六、生产环境部署建议macOS/Linux:官方提供稳定支持,推荐使用原生环境Windows:官方标注为实验性支持

以实战经验介绍行业知识 2881

SAP Gateway Foundation OData V4 服务管理深度解析,从 Service Repository 到 Service Group 的完整运行逻辑

本文解析了SAP S/4HANA中OData V4 API的技术架构,重点阐述Service Repository、Service与Service Group的三层管理体系。以SalesOrder和PurchaseOrder API为例,说明不同服务可能属于特定repository(如srvd_a2x)而非默认DEFAULT库。Service Group作为业务模型组合单元,支持跨服务引用和统一配置,其发布状态直接影响服务可用性。文中对比了后台管理事务/IWBEP/V4_ADMIN与网关端/IWFND/V4

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 82

【POJ1084】Square Destroyer 重复覆盖问题 DLX(Dancing Links)

这么赞的重复覆盖问题DLX版题解还去哪找?菜鸟和老鸟都来看看。

辗转山河弋流歌 2594

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

Hdu 2295 (二分+重复覆盖问题 Dancing Links)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2295   题意:给出一些城市及一些雷达的坐标,要求从这些雷达中选取最多k个能够覆盖所有的城市,问雷达的最小覆盖半径为多少。   二分半径,则可转化为一个判定问题,即给定雷达的

dooder_daodao的专栏 1248

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

Dancing Links

关于这方面知识,牛叉的论文(中文翻译稿): http://sqybi.com/works/dlxcn/ 首先介绍: Donald Knuth'sAlgorithm X:http://en.wikipedia.org/wiki/Algorithm_X 伪算法: If the matrix A is empty, the problem is solved; terminat

fangc的专栏 650

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

Dancing links——DLX搜索详解

前置芝士 ——精确覆盖问题 百度百科 简单来说,就是有多个集合,要你选若干个拼在一起,包含的数和另一个给出的集合完全相同。 这个问题也可以用矩阵表示出来,每一行表示一个集合,如果这个集合中出现了数x,那么在第x列就放个1,否则就是0。 打个比方~ 假如有这么几个集合: {1,2} {3,4,6} {1,4,5} {2,5} {1} 那么搞成矩阵就变成了这个样子: (1100000011011001...

a_forever_dream的博客 896

DLX——Dancing Links

    Dancing Links是Knuth教授在近几年来写的一篇文章,是一类搜索问题的通用优化。它主要利用双向十字链表来存储稀疏矩阵,来达到搜索中的优化。在搜索问题中,矩阵会随着递归的加深会变得越来越稀疏,这种情况下用dancelinks来存储矩阵,往往会达到很好的效果。     核心代码:     对于熟悉双向链表的人,一定不会陌生: L[R[x]] = L[x] R[L[x]] =...

yangzhongmin21的专栏 197

dancing link

<br />论文http://sqybi.com/works/dlxcn/;<br />其实论文已经翻译的很清楚了,这里列出了里面要重点理解的一些地方。最后加了一个自己实现的代码。需要说明的是这个算法所能解决的问题是一类有精确覆盖模型的问题,只要能转化成这种模型,就可用这个算法比较高效的解决。<br /> <br /> <br />L[x]和R[x]分别表示x的前驱节点和后继节点。每个程序员都知道如下操作:<br />L[R[x]] ← L[x], R[L[x]] ← R[x]<br />(1)<br />

notsmarty 3696

dancing links

最早接触Dancing Links的时候,是在csdn论坛上逛的时候,发现有人在研究数独程序,由于本人开发过数独游戏,就进去看了看,发现有人说用Dancing Links来求解数独最快了,于是我就决定去了解一下Dancing Links。 1.   Dancing Links是什么? Dancing Links是一类搜索问题的通用优化,对精确覆盖问题有奇效,也可解决

willinglive 1021

dancing links(舞蹈链)——求解精准覆盖及重复覆盖问题

跳跃的舞者,舞蹈链(Dancing Links)算法——求解精确覆盖问题 精确覆盖问题的定义:给定一个由0-1组成的矩阵,是否能找到一个行的集合,使得集合中每一列都恰好包含一个1 例如:如下的矩阵 就包含了这样一个集合(第1、4、5行) 如何利用给定的矩阵求出相应的行的集合呢?我们采用回溯法 矩阵1: 先假定选择第1行,如下所示: 如上图中所示,红色的那行是选中的一行,这一行...

ling_wang的博客 2704

HDU 3498 whosyourdaddy【Dancing Links重复覆盖】

有n个单位的敌人,对某个敌人进行攻击时该敌人以及与其直接相邻的敌人都会被消灭。问消灭所有敌人所需的最少攻击次数。 重复覆盖问题。我把此题贴出来是想说剪枝优化很有必要,一个小细节就能决定是TLE还是AC。 #include #include #include #include #include using namespace std; const int maxn = 60*60

~飞呀,飞~ 779

简单易懂的Dancing links讲解(3)

Dancing Links除了能解决精确覆盖问题,还能解决重复覆盖问题,这里重点讲重复覆盖 题目:高手做题                                   描述                                  SubRaY被布置了n道作业题,可是他一道也不会..但他知道有w位高手,并知道每位高手                    

Mr.Phoebe的专栏 871
上一篇: POJ1077、HDU1043 Eight 八数码问题:双向BFS、A*
下一篇: 欧拉函数
Human_CK
博客等级 码龄16年 23粉丝 152原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值