【发布时间】:2017-02-24 11:50:33
【问题描述】:
我正在开发这个程序,将分而治之的算法转换为动态规划算法。该算法用于测序(如 DNA)并找出这样做的成本。重申一下动态规划算法是有效的,而分而治之的不是,我不知道为什么。
#include<iostream>
#include <vector>
using namespace std;
int penalty;
int m, n;
char x[] = { 'A', 'A', 'C' }; //, 'A', 'G', 'T', 'T', 'A', 'C', 'C' };
char y[] = { 'T', 'A' }; //,'A' //, 'G', 'G', 'T', 'C', 'A' };
//find minimum
int min(int one, int two, int three)
{
if (one <= two && one <= three)
return one;
if (two <= one && two <= three)
return two;
return three;
}
//divide and conquer way of find the cost of the optimal path
int optMethod(int i, int j)
{
if (i == m)
return 2 * (n - j);
else if (j == n)
return 2 * (m - i);
else {
if (x[i] == y[j])
penalty = 0;
else
penalty = 1;
return min(optMethod(i + 1,j + 1) + penalty, optMethod(i + 1,j) + 2, optMethod(i,j + 1) + 2);
}
}
//dynamic programming way of finding cost of optimal path
void dynamicOptimal(vector<vector<int>>& opt1) {
for (int i = m; i >= 0; i--) {
for (int j = n; j >= 0; j--) {
if (i == m)
opt1[m][j] = 2 * (n - j);
else if (j == n)
opt1[i][n] = 2 * (m - i);
else {
if (x[i] == y[j])
penalty = 0;
else
penalty = 1;
opt1[i][j] = min(opt1[i+1][j+1] + penalty, opt1[i+1][j] + 2, opt1[i][j+1] + 2);
}
}
}
}
int main() {
m = sizeof(x);
n = sizeof(y);
//divide and conquer
cout << optMethod(0, 0) << endl;
//dynamic
vector <vector<int> > optimal(m+1, vector<int>(n+1, 0));
dynamicOptimal(optimal);
cout<<optimal[0][0]<<endl;
cin.get();
return 0;
}
我现在得到的是额外的惩罚,但我不知道在哪里。 [注意] 我知道我没有使用 std::min 并且我知道它在那里
【问题讨论】:
-
只是很小的细节:有
std::min。 -
我知道我只是喜欢在我面前看到它并且它不难写
-
@JoeM。继续推断您的“编写起来并不难”的逻辑,您可能根本不关心库。除了你的“不难写函数”有一个错误!
-
@CraigYoung 你发现了什么错误,因为我在动态编程和分治法中都使用了它,而动态编程一种有效,而分治法无效。这就是为什么我不认为这是我的最小功能。那有意义吗?另外,请注意内置的 min 函数只有 2 个参数,我只是查了一下,我需要三个。
-
@JoeM。 2) “我不认为这是我的 min 函数。这有意义吗?” 不,这没有意义。 (注意:我确实理解你在说什么,但你的推理是有缺陷的。)如果我把一条鱼放在水里,它就会快乐地生活。但如果我下得够久;最终我淹死了。同样的水不同的结果。 同样你可以得到相同的
min函数不同的结果:你的min永远不会返回three。因此,如果一位客户致电min(1,2,3),它会得到正确答案 (1) 并且可以正常工作。如果其他人调用min(3,2,1),它会得到错误答案 (2) 并可能返回自己的错误答案。
标签: c++ algorithm dynamic-programming divide-and-conquer