博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Dancing Links
阅读量:6592 次
发布时间:2019-06-24

本文共 4922 字,大约阅读时间需要 16 分钟。

Dancing Links用来解决如下精确匹配的问题:

选择若干行使得每一列恰好有一个1。Dancing Links通过对非零元素建立双向十字循环链表。上面的例子建立的链表如下所示:

计算的时候使用搜索的策略。每次选出1最少的一列,比如c,然后选择这一列中的某一行,比如r,(r,c)=1,然后r中所有1所在的列,那些其他行这些列有1的都删掉(这些行不会在r算入答案后也在答案里,否则就有某些列多于一个1出现)。然后这就变成一个规模更小的问题,继续搜索。无解时要回溯。

1 class CDancingLinks  2 {  3 protected:  4     struct DancingLinksNode  5     {  6         DancingLinksNode* left;  7         DancingLinksNode* right;  8         DancingLinksNode* down;  9         DancingLinksNode* up; 10         int col; 11         int row; 12     }; 13  14     typedef DancingLinksNode Node; 15  16     int *m_columnEleNumbers; 17     int m_colNumber; 18     int m_rowNumber; 19     Node* m_pool; 20     Node** m_head; 21     int m_curUsePoolIndex; 22  23  24  25  26  27     void _Remove(Node* cur) 28     { 29         --m_columnEleNumbers[cur->col]; 30         for(Node* p=cur->down;p!=cur;p=p->down) 31         { 32             p->left->right=p->right; 33             p->right->left=p->left; 34         } 35     } 36  37     void _Resume(Node* cur) 38     { 39         ++m_columnEleNumbers[cur->col]; 40         for(Node* p=cur->up;p!=cur;p=p->up) 41         { 42             p->left->right=p; 43             p->right->left=p; 44         } 45     } 46  47  48  49     bool _SearchSolution(const int depth,std::vector
&solution) 50 { 51 Node* p=_GetNode(0); 52 if(p->left==p) return true; 53 54 int Min=m_rowNumber+1; 55 int MinColumnIndex=0; 56 for(Node* q=p->left;q!=p;q=q->left) 57 { 58 if(m_columnEleNumbers[q->col]
col]; 61 MinColumnIndex=q->col; 62 } 63 } 64 65 66 for(Node* q=_GetNode(MinColumnIndex)->down;q!=_GetNode(MinColumnIndex);q=q->down) 67 { 68 _Remove(q); 69 solution.push_back(q->row); 70 for(Node* rr=q->right;rr!=q;rr=rr->right) _Remove(rr); 71 if(_SearchSolution(depth+1,solution)) return true; 72 for(Node* rr=q->left;rr!=q;rr=rr->left) _Resume(rr); 73 solution.pop_back(); 74 _Resume(q); 75 } 76 77 return false; 78 } 79 80 Node* _GetNode(int id) { return m_pool+id; } 81 82 void _ReleaseMemory() 83 { 84 if(m_columnEleNumbers) 85 { 86 delete[] m_columnEleNumbers; 87 m_columnEleNumbers=nullptr; 88 } 89 90 if(m_pool) 91 { 92 delete[] m_pool; 93 m_pool=nullptr; 94 } 95 if(m_head) 96 { 97 delete[] m_head; 98 m_head=nullptr; 99 }100 }101 102 public:103 104 CDancingLinks():m_colNumber(-1),m_rowNumber(-1),105 m_columnEleNumbers(nullptr),m_pool(nullptr),m_head(nullptr) {}106 107 /***108 列下标为[1,Column]109 ***/110 CDancingLinks(const int Column,const int Row):111 m_columnEleNumbers(nullptr),m_pool(nullptr),m_head(nullptr)112 {113 SetSize(Column,Row);114 }115 116 /***117 列下标为[1,Column]118 ***/119 void SetSize(const int Column,const int Row)120 {121 m_colNumber=Column;122 m_rowNumber=Row;123 124 _ReleaseMemory();125 126 m_columnEleNumbers=new int[m_colNumber+1];127 m_pool=new Node[m_colNumber*(m_rowNumber+1)+1];128 m_head=new Node*[m_rowNumber+1];129 Clear();130 }131 132 void Clear()133 {134 for(int i=0;i<=m_colNumber;++i)135 {136 Node* cur=_GetNode(i);137 cur->left=((i==m_colNumber)?_GetNode(0):_GetNode(i+1));138 cur->right=((0==i)?_GetNode(m_colNumber):_GetNode(i-1));139 m_columnEleNumbers[i]=0;140 141 cur->up=cur->down=_GetNode(i);142 cur->col=i;143 cur->row=0;144 }145 for(int i=1;i<=m_rowNumber;++i) m_head[i]=NULL;146 m_curUsePoolIndex=m_colNumber+1;147 }148 149 ~CDancingLinks()150 {151 _ReleaseMemory();152 }153 154 void AddElement(const int row,const int col)155 {156 157 Node* cur=m_pool+(m_curUsePoolIndex++);158 159 cur->up=_GetNode(col);160 cur->down=_GetNode(col)->down;161 m_pool[col].down->up=cur;162 m_pool[col].down=cur;163 164 165 if(m_head[row]==NULL)166 {167 m_head[row]=cur->left=cur->right=cur;168 }169 else170 {171 cur->left=m_head[row]->left;172 cur->right=m_head[row];173 m_head[row]->left->right=cur;174 m_head[row]->left=cur;175 }176 ++m_columnEleNumbers[col];177 cur->col=col;178 cur->row=row;179 }180 181 bool GetSolution(std::vector
&Solution)182 {183 return _SearchSolution(0,Solution);184 }185 };

 

转载于:https://www.cnblogs.com/jianglangcaijin/p/5990034.html

你可能感兴趣的文章
mybatis-ehcache 用法配置备忘
查看>>
Python2.7升级到3.0 HTMLTestrunner报错解决方法
查看>>
Redis介绍以及安装(Linux)
查看>>
FreeBSD下php-mbstring的安装
查看>>
去掉VS2012中的红色波浪下划线
查看>>
[文档]关于接口文档的写法
查看>>
一次tensorflow的尝试
查看>>
家具行业探索:企业管理沟通新模式
查看>>
ReplyError: MISCONF Redis is configured to save RDB snapshots,
查看>>
建立Git版本库管理框架例子
查看>>
nginx防止部分DDOS攻击
查看>>
编写一个截取字符串的函数,输入为一个字符串和字节数,输出为按字节截取的字符串。 但是要保证汉字......
查看>>
number_format() 函数定义和用法
查看>>
Java8中聚合操作collect、reduce方法详解
查看>>
查看记录
查看>>
mybatis报ORA-00911: 无效字符
查看>>
Swift UIView动画animateWithDuration
查看>>
Maven 集成Tomcat插件
查看>>
css中的line-height问题
查看>>
nagios监控配置
查看>>