UVA - 529 Addition Chains(迭代+dfs)


  Addition Chains 

An addition chain for n is an integer sequence $<a_0, a_1, a_2, \dots, a_m>$ with the following four properties:

  • a0 = 1
  • am = n
  • a0<a1<a2<...<am-1<am
  • For each k ( $1 \le k \le m$) there exist two (not neccessarily different) integers i and j ( $0 \le i, j \le k-1$) with ak =ai +aj

You are given an integer n. Your job is to construct an addition chain for n with minimal length. If there is more than one such sequence, any one is acceptable.

For example, <1,2,3,5> and <1,2,4,5> are both valid solutions when you are asked for an addition chain for 5.

Input Specification 

The input file will contain one or more test cases. Each test case consists of one line containing one integer  n (  $1 \le n \le 10000$). Input is terminated by a value of zero (0) for  n.

Output Specification 

For each test case, print one line containing the required integer sequence. Separate the numbers by one blank.


Hint: The problem is a little time-critical, so use proper break conditions where necessary to reduce the search space.

Sample Input 

5
7
12
15
77
0

Sample Output 

1 2 4 5
1 2 4 6 7
1 2 4 8 12
1 2 4 5 10 15
1 2 4 8 9 17 34 68 77



题目大意:
给定一个数,按要求输出元素最少的序列。

  1. a0 = 1 
  2. am = n 
  3. a0 < a1 < a2 < ... < am-1 < am 
  4. 对于任意的1<=k<=m,都有ak = ai + aj
解题思路:
a[k] = a[k-1] + a[i]  0 <= i <= k-1
迭代加深搜索。限定搜索的深度k,然后开始进行DFS搜索,如果搜索完没有解,深度deep++,继续上诉搜索,直到找到可行解。

#include <stdio.h>
#include <string.h>
const int N = 100;
int deep;
int ans[N];
int n;
bool ok;
void dfs(int cur) {
	if(cur == deep) {
		if(ans[cur] == n) {
			ok = true;
		}
		return;
	}
	for(int i = 0; i <= cur; i++) {
		if(ans[cur] + ans[i] <= n) { //剪枝1
			int sum = ans[i] + ans[cur];

			for(int k = cur+1; k < deep; k++) { //剪枝2
				sum *= 2;
			}
			if(sum < n) { //如果当前最大的策略都小于n,则跳过
				continue;
			}
			
			ans[cur+1] = ans[i] + ans[cur];
			dfs(cur+1);
			if(ok) {
				return;
			}
		}
	}
}
int main() {
	while(scanf("%d",&n) != EOF && n) {
		memset(ans,0,sizeof(ans));
		ans[0] = 1;
		ok = false;
		
		//求出最短深度
		int sum = 1;
		deep = 0;
		while(sum < n) {
			sum *= 2;
			deep++;
		}
		//迭代
		while(true) {
			dfs(0);
			if(ok) {
				break;
			}
			deep++;
		}
		for(int i = 0; i < deep; i++) {
			printf("%d ",ans[i]);
		}
		printf("%d\n",ans[deep]);
	}
	return 0;
}

<think>我们遇到了一个错误:`Error in node r[2,1] Node inconsistent with parents`。这个错误通常发生在贝叶斯模型中,当初始化值(inits)与模型的先验分布不一致时。在二项分布的模型中,响应变量`r`(即每个研究每个治疗组的响应者数量)必须满足`0 <= r <= n`(n为样本量)。如果初始值不满足这个条件,或者模型在采样过程中产生了不合理的值(比如r>n),就会导致这个错误。 ### 可能原因及解决方案: 1. **零单元校正问题**:虽然我们之前使用了`correction=0.5`,但在`gemtc`包中,我们需要在数据输入前就进行校正,而不是在函数参数中设置(因为`mtc.network`没有`correction`参数)。所以,我们需要在数据预处理阶段进行校正。 2. **数据问题**:检查数据中是否有`responders`大于`sampleSize`的情况,或者存在缺失值。 3. **初始值问题**:JAGS在初始化时可能为潜在变量(如基线效应)生成了不合理的初始值,导致`r`的计算值超出范围。 ### 修正步骤: #### 1. 数据预处理(零单元校正) 在创建网络之前,对数据进行校正,确保每个研究的每个治疗组中,`responders`不为0且不等于`sampleSize`(即避免0和全响应的情况)。常用的校正方法是在整个数据集中所有`responders`和`non-responders`(即`sampleSize - responders`)都加上0.5。 ```r # 校正数据:对每个治疗组的responders和样本量进行调整 data <- data %>% mutate( non_responders = sampleSize - responders, responders_corrected = responders + 0.5, non_responders_corrected = non_responders + 0.5, sampleSize_corrected = responders_corrected + non_responders_corrected ) %>% select(study, treatment, responders = responders_corrected, sampleSize = sampleSize_corrected) ``` #### 2. 检查数据合理性 确保校正后的数据满足:`0 < responders < sampleSize`。 #### 3. 调整初始值 我们可以尝试为模型提供合理的初始值,特别是对于基线效应(baseline effects)和随机效应。在`mtc.model`中,我们可以通过`inits`参数来设置初始值函数。 ```r # 创建一个初始化函数,确保初始值合理 my.inits <- function() { list( "mu" = runif(1, -1, 1), # 基线效应的初始值,根据实际情况调整范围 "d" = c(NA, runif(length(treatments$id) - 1, -0.5, 0.5)) # 相对效应初始值 ) } # 在运行模型时指定初始值函数 model <- mtc.model( network, type = "binom", link = "logit", linearModel = "random", n.chain = 4, # 使用4条链 inits = my.inits # 使用自定义初始值 ) ``` #### 4. 调整模型参数 如果问题仍然存在,可以尝试调整先验分布,特别是随机效应的方差先验(异质性参数)。默认情况下,异质性参数可能过大,导致极端值出现。 ```r model <- mtc.model( network, type = "binom", link = "logit", linearModel = "random", n.chain = 4, inits = my.inits, hy.prior = mtc.hy.prior("std.dev", "dunif", 0, 10) # 调整异质性先验为均匀分布 ) ``` ### 完整修正代码示例 ```r # 数据预处理:零单元校正 data_corrected <- data %>% mutate( responders = responders + 0.5, sampleSize = sampleSize + 1 # 因为responder和non-responder各加0.5,总样本量加1 ) # 重新创建网络 network <- mtc.network(data.ab = data_corrected, treatments = treatments) # 定义初始值函数 my.inits <- function(chain) { return(list( .RNG.name = "base::Mersenne-Twister", .RNG.seed = chain * 100, mu = runif(1, -1, 1), d = c(NA, runif(nrow(treatments) - 1, -0.5, 0.5)) )) } # 创建模型(使用自定义初始值函数和先验) model <- mtc.model( network, type = "binom", link = "logit", linearModel = "random", n.chain = 4, inits = my.inits, hy.prior = mtc.hy.prior("std.dev", "dunif", 0, 10) ) # 运行模型(注意:增加迭代次数和退火次数) results <- mtc.run( model, n.adapt = 100000, # 退火迭代 n.iter = 200000, # 正式迭代 thin = 10 ) ``` ### 注意事项 - 如果仍然出现错误,请检查具体是哪个节点(如`r[2,1]`)出现问题,然后查看对应的研究数据,确保数据合理。 - 考虑使用`debug`模式或简化模型(如固定效应模型)来定位问题。 §§相关问题§§ 1. 在网状Meta分析中,如何处理二分类数据中的零事件(zero events)研究?有哪些校正方法? 2. JAGS模型中出现“Node inconsistent with parents”错误时,除了初始值调整,还有哪些调试方法? 3. 随机效应网状Meta分析中,如何选择合适的异质性先验分布(如均匀分布、半正态分布)? 4. MCMC模拟中,如何确定退火(adaptation)迭代次数和正式迭代次数以保证收敛?</think>您的代码在执行 `mtc.run()` 时遇到错误:"Error in node r[2,1] Node inconsistent with parents"。这通常发生在二项分布的贝叶斯模型中,当初始值或数据与模型结构不匹配时。以下是关键原因和解决方案: ### 错误原因分析 1. **零单元校正问题**: - 虽然使用了 `correction=0.5`,但 JAGS 模型仍可能遇到极端值(如响应数=样本量) - 错误中的 `r[2,1]` 表示第2个研究的第1个治疗组数据存在矛盾 2. **初始值冲突**: - JAGS 自动生成的初始值可能不满足二项分布约束:`0 ≤ responders ≤ sampleSize` 3. **数据边界问题**: - 当 `responders = 0` 或 `responders = sampleSize` 时,logit变换会得到无穷大值 ### 完整解决方案 #### 1. 增强数据预处理 ```r # 强化零单元校正 (处理0和100%响应的情况) data <- data %>% mutate( responders = case_when( responders == 0 ~ 0.5, responders == sampleSize ~ sampleSize - 0.5, TRUE ~ responders ), sampleSize = ifelse(responders == sampleSize | responders == 0, sampleSize + 1, sampleSize) ) ``` #### 2. 手动设置合理初始值 ```r # 自定义初始值函数 safe_inits <- function(chain_id) { list( mu = rnorm(1, 0, 1), # 基线效应 d = c(NA, rnorm(nrow(treatments)-1, 0, 0.5)), # 相对效应 .RNG.name = "base::Mersenne-Twister", .RNG.seed = chain_id * 100 ) } model <- mtc.model( network, type = "binom", link = "logit", linearModel = "random", n.chain = 4, # 使用4条链 inits = safe_inits # 应用安全初始值 ) ``` #### 3. 添加模型约束(BUGS代码注入) ```r # 修改模型先验约束 model <- mtc.model( network, type = "binom", link = "logit", linearModel = "random", hy.prior = mtc.hy.prior("std.dev", "dunif", 0, 5), # 限制异质性范围 # 注入自定义BUGS代码防止溢出 code = " for(i in 1:ns) { for(k in 1:na[i]) { r[i,k] ~ dbin(p[i,k], n[i,k]) logit(p[i,k]) <- mu[i] + delta[i,k] delta[i,k] ~ dnorm(md[i,k], prec) md[i,k] <- d[t[i,k]] - d[t[i,1]] # 相对效应 } } # 添加边界约束 for(k in 1:nt) { d[k] <- ifelse(k == 1, 0, d_nonref[k-1]) d_nonref[k-1] ~ dnorm(0, 0.01) T(-5,5) # 限制效应量范围 } " ) ``` #### 4. 分阶段运行MCMC ```r # 第一阶段:短链测试 test_run <- mtc.run(model, n.adapt=5000, n.iter=10000, thin=2) # 检查诊断 gelman.diag(test_run) # Gelman-Rubin统计量应<1.05 traceplot(test_run) # 观察链的混合情况 # 第二阶段:正式运行(仅当测试通过时) if(max(gelman.diag(test_run)$psrf[,1]) < 1.05) { results <- mtc.run(model, n.adapt = 100000, n.iter = 200000, thin = 10) } else { warning("模型未收敛,请检查数据或调整先验") } ``` ### 关键预防措施 1. **数据验证**: ```r # 检查所有研究是否满足: 0 < responders < sampleSize invalid_studies <- data %>% filter(responders <= 0 | responders >= sampleSize) ``` 2. **简化模型测试**: ```r # 先尝试固定效应模型 simple_model <- mtc.model(network, type="binom", linearModel="fixed") ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值