-3

I am working on this program converting a divide and conquer algorithm to a dynamic programming algorithm. The algorithm is for sequencing (like DNA) and finding the cost to do so. Just to reiterate the dynamic programming algorithm is working and the divide and conquer one is not and I cannot figure out why.

#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;
}

What I am getting right now is that there is a extra penalty being given but I can't figure out where. [NOTE] I know I did not use the std::min and I know its there

Joe M.
  • 16
  • 4
  • 1
    just tiny detail: there is `std::min`. – Cheers and hth. - Alf Oct 14 '16 at 23:41
  • I am aware I just like seeing it in front of me and its not difficult to write – Joe M. Oct 14 '16 at 23:44
  • 3
    @JoeM. Keep extrapolating your "it's not difficult to write" logic and you may as well not bother with libraries at all. That aside your "not difficult to write function" ***has a bug!*** – Disillusioned Oct 14 '16 at 23:50
  • @CraigYoung What bug did you find because I use it in both the dynamic programming and the Divide and conquer and the dynamic programming one works and the divide and conquer one doesn't. That is why I don't think it is my min function. Does that make sense? Also, note the built in min function is only 2 parameters, I just looked it up and I needed three for this. – Joe M. Oct 15 '16 at 01:20
  • @JoeM. 2) _"I don't think it is my min function. Does that make sense?"_ No it doesn't make sense. (NOTE: I ***do understand*** what you're saying but your reasoning is flawed.) If I put a fish under water it lives happily. But if I go under long enough; eventually I drown. Same water different outcomes. ***Similarly you can get same `min` function different outcomes***: Your `min` never returns `three`. So if one client calls `min(1,2,3)`, it gets the correct answer (1) and works. If the other calls `min(3,2,1)`, it gets the _wrong_ answer (2) and might ***return its own wrong answer***. – Disillusioned Oct 15 '16 at 08:25
  • @JoeM. 3) "_min function is only 2 parameters_" Are you sure about your source? Even C++ 98 has a 3 param overload to specify the compare function if needed (admittedly, that doesn't help you). But if you're using C++ 11 or 14, there are 2 more overloads. So try `#include ` and call `std::min({2,3,1});`. ***Yet regardless of which C++ you use...:*** The minimum of A, B, C is _very simply_ work out min A, B and min between that result and C! I.e. ***`std::min(std::min(a,b),c);`*** – Disillusioned Oct 15 '16 at 08:48
  • @JoeM. 1) _"What bug?"_: Your min implementation is clumsy, checking far more conditions that needed. So I carefully checked your `if` conditions. 1st `if` checks if `one` is the minimum, so if 2nd `if` runs you **know** that it's **not**. So the first condition in the 2nd `if` is pointless. Delete that and it should be easier to see that 2nd `if` always returns `true` when it runs. ***So you can never return three.*** – Disillusioned Oct 15 '16 at 09:01
  • don't worry guys while y'all were arguing about my min function I found the solution. it was the global scope of penalty was never being reset to 0. Thanks for your help!! – Joe M. Oct 15 '16 at 21:08

1 Answers1

0

You should change :

if (two <= one && two <= two)
        return two;
    return three;

With :

if (two <= one && two <= three)
        return two;
    return three;
  • Thanks!! I did that and it still is doing the same thing – Joe M. Oct 15 '16 at 02:09
  • While this fixes the typo, it's still a bad solution. The whole function is overly complex. Whenever comparing `n` values you only need `n-1` comparisons to determine the minimum. Challenge: figure it out. ;) – Disillusioned Oct 15 '16 at 08:56