// File: /workspace/github_cpp_makefile_star2_O2/ahnafraihan[P]BestFirstSearch/main.cpp
// Function: knapsack3(int, int*, int*, int, int)
void knapsack3(int n, int p[], int w[], int W, int maxprofit) {
    int optSize = 0; //initialize current optimal size 0
    int numNodes = 1; //initalize current number of nodes visited to 1, to account for root node
    int numLeaves = 0; //initalize current number of leaf nodes visited to 0
    
    //initialize priority queue of nodes Q
    priority_queue<node>Q;
    
    //initialize nodes u and v, with v as root
    node u, v;
    
    //initialize Q to be empty
    v.level = 0; v.profit = 0; v.weight = 0; v.k.resize(n+1, 0); u.k.resize(n+1,0);
    maxprofit = 0; //set current maximum profit to 0
    
    v.bound = bound(n, p, w, W, v);
    Q.push(v); //enqueue v
    
    //remove node with best bound
    while(!Q.empty()){
        v= Q.top();
        Q.pop();
        //expand v to see if it is promising
        if(v.bound > maxprofit) {
            numNodes += 2; //increment number of total nodes visited
            u.level = v.level + 1; // child of v
            //"yes" child
            
            u.weight = v.weight + w[u.level-1];
            u.profit = v.profit + p[u.level-1];
            u.k = v.k; //pass down optimization history to child
            u.k.at(u.level-1) = 1; //designate part of personal solution
            if(u.weight <= W && u.profit > maxprofit) {
                maxprofit = u.profit;
                optimalSolution = u.k; //add to global optimal solution
            }
            
            //find the upper bound of our child u
            u.bound = bound(n, p, w, W, u);
            if(u.bound > maxprofit  && u.weight < W) {
                Q.push(u);
            }
            else
                numLeaves++;
            //"no" child
            
            u.weight = v.weight;
            u.profit = v.profit;
            u.k.at(u.level - 1) = 0;
            u.bound = bound(n, p, w, W, u);
            //node chosen to be expanded
            if(u.bound > maxprofit  && u.weight < W) {
                Q.push(u);
            }
            else
                numLeaves++;
            //node not expanded
        }//queue is empty
        else
            numLeaves++; //increment number of leaf nodes visited
    }
    
    //calculate size of our optimal solution from optimalSolution global variable
    for (int i = 0; i < optimalSolution.size(); i++) {
        if (optimalSolution.at(i) == 1)
            optSize++;
    }
    
    //create output stream to record results onto output text file
    ofstream myfile;
    myfile.open (output.c_str());
    myfile << n << "," << maxprofit << "," << optSize << endl << numNodes << "," << numLeaves << endl;
    for (int i = 0; i < optimalSolution.size(); i++) {
        if (optimalSolution.at(i) == 1)
            myfile << w[i] << "," << p[i] << endl;
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x318, %rsp            # imm = 0x318
movl %ecx, %r15d
movq %rdx, -0x40(%rbp)
movq %rsi, %r12
xorps %xmm0, %xmm0
andq $0x0, -0xb0(%rbp)
leaq -0x68(%rbp), %r14
andq $0x0, 0x10(%r14)
leaq -0x90(%rbp), %rcx
andq $0x0, 0x10(%rcx)
movups %xmm0, (%rcx)
andq $0x0, -0x10(%rcx)
andl $0x0, -0x8(%rcx)
movaps %xmm0, -0xc0(%rbp)
movups %xmm0, (%r14)
movq %rdi, -0x50(%rbp)
leal 0x1(%rdi), %eax
movslq %eax, %rbx
leaq -0x338(%rbp), %rdx
andl $0x0, (%rdx)
movq %rcx, %rdi
movq %rbx, %rsi
callq 0x2c2c
leaq -0x338(%rbp), %rdx
andl $0x0, (%rdx)
movq %r14, %rdi
movq %rbx, %rsi
callq 0x2c2c
leaq -0x138(%rbp), %rdi
leaq -0xa0(%rbp), %rsi
callq 0x2c66
leaq -0x138(%rbp), %r8
movq -0x50(%rbp), %rdi
movq %r12, %rsi
movq -0x40(%rbp), %rdx
movl %r15d, %ecx
callq 0x2bb4
leaq -0xa0(%rbp), %rbx
movss %xmm0, 0xc(%rbx)
leaq -0x128(%rbp), %rdi
callq 0x2e36
leaq -0xc0(%rbp), %rdi
movq %rbx, %rsi
callq 0x2c7e
movl %r15d, -0x30(%rbp)
pushq $0x1
popq %rax
movl %eax, -0x44(%rbp)
movl $0x0, -0x2c(%rbp)
leaq -0xa0(%rbp), %r14
leaq -0xc0(%rbp), %rbx
xorl %r13d, %r13d
cvtsi2ssl -0x2c(%rbp), %xmm0
movss %xmm0, -0x34(%rbp)
movq -0xc0(%rbp), %rsi
cmpq -0xb8(%rbp), %rsi
je 0x29e2
movq %r14, %rdi
callq 0x2c9e
movq %rbx, %rdi
callq 0x2cc4
movss -0x94(%rbp), %xmm0
ucomiss -0x34(%rbp), %xmm0
ja 0x2877
incl %r13d
jmp 0x2840
movslq -0xa0(%rbp), %rax
leal 0x1(%rax), %ecx
movl %ecx, -0x78(%rbp)
movq -0x40(%rbp), %rcx
movl (%rcx,%rax,4), %ecx
addl -0x98(%rbp), %ecx
movl %ecx, -0x70(%rbp)
movl (%r12,%rax,4), %eax
addl -0x9c(%rbp), %eax
movl %eax, -0x74(%rbp)
leaq -0x68(%rbp), %rdi
leaq -0x90(%rbp), %rsi
callq 0x2ce8
movslq -0x78(%rbp), %rsi
decq %rsi
leaq -0x68(%rbp), %rdi
callq 0x2dbc
movl $0x1, (%rax)
movl -0x30(%rbp), %eax
cmpl %eax, -0x70(%rbp)
jg 0x28ed
movl -0x74(%rbp), %r15d
cmpl -0x2c(%rbp), %r15d
jle 0x28ed
leaq 0x4840(%rip), %rdi      # 0x7120
leaq -0x68(%rbp), %rsi
callq 0x2ce8
movl %r15d, -0x2c(%rbp)
leaq -0x110(%rbp), %rdi
leaq -0x78(%rbp), %rsi
callq 0x2c66
movq -0x50(%rbp), %rdi
movq %r12, %rsi
movq -0x40(%rbp), %rdx
movl -0x30(%rbp), %r15d
movl %r15d, %ecx
leaq -0x110(%rbp), %r8
callq 0x2bb4
movss %xmm0, -0x6c(%rbp)
leaq -0x100(%rbp), %rdi
callq 0x2e36
cvtsi2ssl -0x2c(%rbp), %xmm1
movss -0x6c(%rbp), %xmm0
movss %xmm1, -0x34(%rbp)
ucomiss %xmm1, %xmm0
jbe 0x2954
cmpl %r15d, -0x70(%rbp)
jge 0x2954
movq %rbx, %rdi
leaq -0x78(%rbp), %rsi
callq 0x2c7e
jmp 0x2957
incl %r13d
movq -0x9c(%rbp), %rax
movq %rax, -0x74(%rbp)
movslq -0x78(%rbp), %rsi
decq %rsi
leaq -0x68(%rbp), %rdi
callq 0x2dbc
andl $0x0, (%rax)
leaq -0xe8(%rbp), %rdi
leaq -0x78(%rbp), %rsi
callq 0x2c66
addl $0x2, -0x44(%rbp)
movq -0x50(%rbp), %rdi
movq %r12, %rsi
movq -0x40(%rbp), %rdx
movl -0x30(%rbp), %r15d
movl %r15d, %ecx
leaq -0xe8(%rbp), %r8
callq 0x2bb4
movss %xmm0, -0x6c(%rbp)
leaq -0xd8(%rbp), %rdi
callq 0x2e36
movss -0x6c(%rbp), %xmm0
ucomiss -0x34(%rbp), %xmm0
jbe 0x29da
cmpl %r15d, -0x70(%rbp)
jge 0x29da
movq %rbx, %rdi
leaq -0x78(%rbp), %rsi
callq 0x2c7e
jmp 0x2836
incl %r13d
jmp 0x2836
xorl %r14d, %r14d
leaq 0x4734(%rip), %r15      # 0x7120
xorl %ebx, %ebx
movq 0x4733(%rip), %rax      # 0x7128
subq 0x4724(%rip), %rax      # 0x7120
sarq $0x2, %rax
cmpq %r14, %rax
jbe 0x2a1f
movq %r15, %rdi
movq %r14, %rsi
callq 0x2dbc
xorl %ecx, %ecx
cmpl $0x1, (%rax)
sete %cl
addl %ecx, %ebx
incq %r14
jmp 0x29ee
leaq -0x338(%rbp), %rdi
callq 0x2190
movq 0x4706(%rip), %rsi      # 0x7138
leaq -0x338(%rbp), %rdi
pushq $0x10
popq %rdx
callq 0x2030
leaq -0x338(%rbp), %rdi
movq -0x50(%rbp), %rsi
callq 0x21a0
leaq 0x15c8(%rip), %rsi      # 0x4020
movq %rax, %rdi
callq 0x20f0
movq %rax, %rdi
movl -0x2c(%rbp), %esi
callq 0x21a0
leaq 0x15ae(%rip), %rsi      # 0x4020
movq %rax, %rdi
callq 0x20f0
movq %rax, %rdi
movl %ebx, %esi
callq 0x21a0
movq %rax, %rdi
callq 0x2090
movq %rax, %rdi
movl -0x44(%rbp), %esi
callq 0x21a0
leaq 0x1582(%rip), %rsi      # 0x4020
movq %rax, %rdi
callq 0x20f0
movq %rax, %rdi
movl %r13d, %esi
callq 0x21a0
movq %rax, %rdi
callq 0x2090
xorl %ebx, %ebx
leaq 0x465e(%rip), %r14      # 0x7120
leaq -0x338(%rbp), %r13
leaq 0x1550(%rip), %r15      # 0x4020
movq 0x4651(%rip), %rax      # 0x7128
subq 0x4642(%rip), %rax      # 0x7120
sarq $0x2, %rax
cmpq %rbx, %rax
jbe 0x2b2a
movq %r14, %rdi
movq %rbx, %rsi
callq 0x2dbc
cmpl $0x1, (%rax)
jne 0x2b25
movq -0x40(%rbp), %rax
movl (%rax,%rbx,4), %esi
movq %r13, %rdi
callq 0x21a0
movq %rax, %rdi
movq %r15, %rsi
callq 0x20f0
movl (%r12,%rbx,4), %esi
movq %rax, %rdi
callq 0x21a0
movq %rax, %rdi
callq 0x2090
incq %rbx
jmp 0x2ad0
leaq -0x338(%rbp), %rdi
callq 0x2130
leaq -0x90(%rbp), %rdi
callq 0x2e36
leaq -0x68(%rbp), %rdi
callq 0x2e36
leaq -0xc0(%rbp), %rdi
callq 0x2ef2
addq $0x318, %rsp            # imm = 0x318
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x2b77
jmp 0x2b77
jmp 0x2b77
jmp 0x2b77
jmp 0x2b77
jmp 0x2b7c
jmp 0x2b77
movq %rax, %rbx
jmp 0x2b8b
movq %rax, %rbx
leaq -0x338(%rbp), %rdi
callq 0x2130
leaq -0x90(%rbp), %rdi
callq 0x2e36
leaq -0x68(%rbp), %rdi
callq 0x2e36
leaq -0xc0(%rbp), %rdi
callq 0x2ef2
movq %rbx, %rdi
callq 0x21b0