【挑战】计算48种依次泛化的假设情况下,总共有多少种不可再简化的析合范式?

简介: 一种可行的算法: 由于属性泛化后,一个泛化的假设可以对应多个具体假设。 把所有假设按三属性泛化,二属性泛化,一属性泛化,具体属性排序(这样可以保证排在后面的假设不会包含前面的任何一个假设,所以省略了一些包含判断),进行循环枚举,按顺序遍历所有假设组合248种可能(当然绝大部分都提前结束了,不会是那么夸张的量级,虽然也不低):使用栈来实现非递归,如果当前假设还有没被析合式所包含的具体假设,则认为可以入栈,并当前栈大小的长度计数加1,并继续扫描。

一种可行的算法: 
由于属性泛化后,一个泛化的假设可以对应多个具体假设。 
把所有假设按三属性泛化,二属性泛化,一属性泛化,具体属性排序(这样可以保证排在后面的假设不会包含前面的任何一个假设,所以省略了一些包含判断),进行循环枚举,按顺序遍历所有假设组合248种可能(当然绝大部分都提前结束了,不会是那么夸张的量级,虽然也不低):

  • 使用栈来实现非递归,如果当前假设还有没被析合式所包含的具体假设,则认为可以入栈,并当前栈大小的长度计数加1,并继续扫描。
  • 如果当前扫描已经到了最后一个假设,或者所有具体假设已经被全部包含,则退栈。
  • 循环结束条件:当最后一个假设作为第一个压入栈的元素时,认为已经遍历结束。

由于一共有18种具体假设,可以用一个32位整型(变量为hypos_cur)的后18位来表示每一个具体假设。用1表示具体假设没被包含,用0表示具体假设已经被析合式包含。初始的析合式为空,可以设初试值为0X3FFFF。每个假设也对应一个32位整型(假设变量为hypo_const),代表着它所对应了哪些具体假设,如果它包含了某种具体假设,则该位为1。

  • 判断析合式是否包含了全部的具体假设:hypos_cur=0。
  • 判断该假设是否已经被析合范式包含:用hypo_const与hypos_cur做与运算(结果用hypo_tmp表示),如果为0表示已经被包含(判断该假设是否包含了当前的析合式:用hypo_const与hypos_cur做或运算,如果为0X3FFFFF,则认为该假设包含了当前析合式,但由于前面对所有假设做了排序,不可能出现这种情况,所以可以省略该判断)。
  • 当某个假设加入析合范式后(入栈)用hypos_cur与hypo_tmp做异或运算,来更改析合式所包含的具体假设。
  • 出栈时再次用hypos_cur与hypo_tmp做异或,回到加入该假设前的情况。
  • 因为是指数级遍历的算法,所以很慢

下面将直接贴上代码,供参阅讨论:

  1 #include <vector>
  2 
  3 #include <stack>
  4 
  5 using namespace std;
  6 
  7  
  8 
  9 //按泛化程度排序,保证排在后面的假设不会不会包含前面的任何一个假设
 10 
 11 static const char list[] = {
 12 
 13     0,0,0,
 14 
 15     0,0,1,0,0,2,0,0,3,0,1,0,0,2,0,0,3,0,1,0,0,2,0,0,
 16 
 17     0,1,1,0,1,2,0,1,3,0,2,1,0,2,2,0,2,3,0,3,1,0,3,2,0,3,3,
 18 
 19     1,0,1,1,0,2,1,0,3,2,0,1,2,0,2,2,0,3,
 20 
 21     1,1,0,1,2,0,1,3,0,2,1,0,2,2,0,2,3,0,
 22 
 23     1,1,1,1,1,2,1,1,3,1,2,1,1,2,2,1,2,3,1,3,1,1,3,2,1,3,3,
 24 
 25     2,1,1,2,1,2,2,1,3,2,2,1,2,2,2,2,2,3,2,3,1,2,3,2,2,3,3
 26 
 27 };
 28 
 29  
 30 
 31 //用来派生的抽象类
 32 
 33 class hypos {
 34 
 35 public:
 36 
 37     virtual int insert(int cur) = 0;
 38 
 39 };
 40 
 41  
 42 
 43 //单个的假设类
 44 
 45 /*
 46 
 47 hypo_const  假设对应的具体假设集合
 48 
 49 */
 50 
 51 class hypo :public hypos {
 52 
 53 public:
 54 
 55     hypo(int a, int b, int c) {
 56 
 57         hypo_const = 0;
 58 
 59         vector<char>  p[3];
 60 
 61         if (a == 0) {
 62 
 63             p[0].push_back(1);
 64 
 65             p[0].push_back(2);
 66 
 67         }
 68 
 69         else
 70 
 71             p[0].push_back(a);
 72 
 73         if (b == 0) {
 74 
 75             p[1].push_back(1);
 76 
 77             p[1].push_back(2);
 78 
 79             p[1].push_back(3);
 80 
 81         }
 82 
 83         else
 84 
 85             p[1].push_back(b);
 86 
 87         if (c == 0) {
 88 
 89             p[2].push_back(1);
 90 
 91             p[2].push_back(2);
 92 
 93             p[2].push_back(3);
 94 
 95         }
 96 
 97         else
 98 
 99             p[2].push_back(c);
100 
101         for (unsigned int i = 0;i < p[0].size();i++)
102 
103             for (unsigned int j = 0;j < p[1].size();j++)
104 
105                 for (unsigned int k = 0;k < p[2].size();k++)
106 
107                     hypo_const |= (1 << (p[0][i] * 9 + p[1][j] * 3 + p[2][k] - 13));
108 
109     }
110 
111  
112 
113     //判断是否要加入到析合式 如果还有具体假设没被包含,则加入
114 
115     int insert(int cur) {
116 
117         return (hypo_const & cur);
118 
119     };
120 
121  
122 
123 private:
124 
125     int hypo_const;
126 
127 };
128 
129  
130 
131 //用于压入栈的派生类 用来实现非递归
132 
133 /*
134 
135 hypo_tmp    记录这个假设入栈时,带入了哪些具体假设,出栈时要还原
136 
137 ptr         记录入栈时的位置
138 
139 */
140 
141 class hypo_ss :public hypos {
142 
143 public:
144 
145     hypo_ss(int _ptr,int tmp){
146 
147         hypo_tmp = tmp;
148 
149         ptr = _ptr;
150 
151     }
152 
153     int insert(int cur) {
154 
155         return 0;
156 
157     };
158 
159     int hypo_tmp;
160 
161     int ptr;
162 
163 };
164 
165  
166 
167 //用来循环遍历的类
168 
169 /*
170 
171 sum     各个长度的析合式各有多少种可能
172 
173 ss      用来实现非递归的栈
174 
175 hypos_cur   当前没被包含的具体假设 初始值为0X3FFFF
176 
177 hyposs  48个假设集合
178 
179 */
180 
181 class Traversal :public hypos {
182 
183 public:
184 
185     Traversal() {
186 
187         hypos_cur = 0x3ffff;
188 
189         for(int i=0;i<48;i++)
190 
191             hyposs.push_back(hypo(list[3*i], list[3*i+1], list[3*i+2]));
192 
193     }
194 
195  
196 
197     //循环顺序遍历的主体
198 
199     //cur  初试的位置 设为0
200 
201     int insert(int cur) {
202 
203         //当前指向的位置
204 
205         int ptr = cur;
206 
207         while (1) {
208 
209             //退出条件 当最后一个假设作为第一个入栈的元素 表示遍历完成
210 
211             if (ptr > 47 && !ss.size()) break;
212 
213             //回退条件  扫描到最后或者所有具体假设都被包含
214 
215             if (hypos_cur == 0 || ptr>47) {
216 
217                 hypo_ss hypo_tmp = ss.top();
218 
219                 hypos_cur ^= hypo_tmp.hypo_tmp;
220 
221                 ptr = hypo_tmp.ptr + 1;
222 
223                 ss.pop();
224 
225                 continue;
226 
227             }
228 
229  
230 
231             //入栈条件  如果该假设还有未被包含的具体假设 则入栈,并当前栈大小的计数加1
232 
233             if (int tmp =hyposs[ptr].insert(hypos_cur)) {
234 
235                 hypos_cur ^= tmp;
236 
237                 ss.push(hypo_ss(ptr, tmp));
238 
239                 if (sum.size() < ss.size())
240 
241                     sum.push_back(0);
242 
243                 sum[ss.size() - 1]++;
244 
245             }
246 
247             ptr++;
248 
249         }
250 
251         return 1;
252 
253     };
254 
255     //输出各个长度的可能数
256 
257     void print() {
258 
259         for (unsigned int i = 0;i < sum.size();i++)
260 
261             printf("length %d : %d\n", i + 1, sum[i]);
262 
263     }
264 
265 private:
266 
267     vector<int> sum;
268 
269     stack<hypo_ss> ss;
270 
271     int hypos_cur;
272 
273     vector<hypo> hyposs;
274 
275 };
276 
277  
278 
279 int main()
280 
281 {
282 
283     Traversal traversal;
284 
285     traversal.insert(0);
286 
287     traversal.print();
288 
289     system("pause");
290 
291     return 0;
292 
293 }

 

目录
相关文章
|
1天前
|
移动开发 数据可视化
R语言两层2^k析因试验设计(因子设计)分析工厂产量数据和Lenth方法检验显著性可视化|数据分享(二)
R语言两层2^k析因试验设计(因子设计)分析工厂产量数据和Lenth方法检验显著性可视化|数据分享(二)
11 0
|
1天前
|
数据可视化
R语言两层2^k析因试验设计(因子设计)分析工厂产量数据和Lenth方法检验显著性可视化|数据分享(一)
R语言两层2^k析因试验设计(因子设计)分析工厂产量数据和Lenth方法检验显著性可视化|数据分享(一)
17 0
|
2月前
【SPSS】两独立样本的极端反应检验和两配对样本的非参数检验详细操作教程(附案例实战)
【SPSS】两独立样本的极端反应检验和两配对样本的非参数检验详细操作教程(附案例实战)
41 0
|
9月前
|
算法 调度 决策智能
【两阶段鲁棒优化】利用列-约束生成方法求解两阶段鲁棒优化问题(Python代码实现)
【两阶段鲁棒优化】利用列-约束生成方法求解两阶段鲁棒优化问题(Python代码实现)
177 0
【两阶段鲁棒优化】利用列-约束生成方法求解两阶段鲁棒优化问题(Python代码实现)
|
9月前
Matlab:如何利用层次分析法(升级版)计算具有多重指标的判断矩阵的一致性检验和权重
Matlab:如何利用层次分析法(升级版)计算具有多重指标的判断矩阵的一致性检验和权重
150 0
|
6月前
Induction hypothesis(归纳假设
Induction hypothesis(归纳假设)是一种基于归纳推理的假设或推测,通常用于科学、工程和数学等领域中。它是一种从特殊情况或实例中推断出一般性结论或规律的方法。归纳假设是基于观察到的数据或现象,通过对这些数据或现象进行总结和归纳,从而得出一个更普遍的结论或规律。 使用归纳假设的方法可以分为以下几个步骤:
254 5
|
8月前
|
存储 数据可视化 数据挖掘
知识点丨重测序数据进行kinship亲缘关系分析、构建IBS矩阵的方法与介绍
知识点丨重测序数据进行kinship亲缘关系分析、构建IBS矩阵的方法与介绍
知识点丨重测序数据进行kinship亲缘关系分析、构建IBS矩阵的方法与介绍
|
算法 C++
详细实例说明+典型案例实现 对枚举法进行全面分析 | C++
简单的来说,算法就是用计算机程序代码来实现数学思想的一种方法。学习算法就是为了了解它们在计算机中如何演算,以及在当今的信息时代,它们是如何在各个层面上影响我们的日常生活的,从而提高我们的逻辑思维能力和处理实际问题的能力。善用算法、巧用算法,是培养程序设计逻辑的重中之重,许多实际的问题都可用多个可行的算法来解决, 但是要从中找出最优的解决算法却是一项挑战。
130 0
详细实例说明+典型案例实现 对枚举法进行全面分析 | C++
|
存储 算法 C++
详细实例说明+典型案例实现 对动态规划法进行全面分析 | C++
在上面我们通过通俗易懂的例子对动态规划法进行了理解,也用该方法的核心对斐波那契数列进行了优化。动态规划是分治法的一个延伸,它增加了记忆机制的使用,将处理过的子问题的答案记录下来,从而避免去重复计算。
218 0
详细实例说明+典型案例实现 对动态规划法进行全面分析 | C++
|
机器学习/深度学习 自然语言处理 达摩院
模型精度再被提升,统一跨任务小样本学习算法 UPT 给出解法!
UPT是一种面向多种NLP任务的小样本学习算法,致力于利用多任务学习和预训练增强技术,在仅需要标注极少训练数据的情况下,提升大规模预训练语言模型在多种场景下的模型精度。