// File: /workspace/github_cpp_makefile_star2_O3/maramire[P]SP_PSO/parallel_main.cpp
// Function: main
int main(int argc, const char *argv[]) 
{


    /* Taking algorithm time performance! */
    auto t1 = chrono::high_resolution_clock::now(); 

    cout << "Start!"<<endl;

    /* Open Instance File */

    /* Define number of items to pack */
    n_items = 0; 
    strip_width = 0;
    max_height = 0;

    string filepath = argv[1];
    cout << "-> Opening instances!"<<endl;
    openInstance(filepath, items, strip_width, max_height, n_items);

    
    unsigned int a = filepath.rfind('.');
    unsigned int b = filepath.rfind('/',a-1);
    string name = filepath.substr(b+1,a-b-1);
    
    

    cout << "-> Number of items: " << n_items << endl;
    cout << "-> Strip width: " << strip_width << endl;
    cout << "-> Upper bound computed: "  << max_height << endl;

    

    
    /* Initialize particles */
    for(int i=0; i<N_PARTICLES; i++){
        //unsigned seed = i+1;
        particle_init(n_items, swarm);

        /* Initialize strip */
        Strip s = {};
        s.height = max_height;
        s.width = strip_width;

        s.x_position = 0;
        s.y_position = 0;
    
        /* Evaluate each particle */
        HR(items,s,n_items,swarm[i]); 

        swarm[i].pbest = swarm[i].permutation;
        swarm[i].pbest_fitness = swarm[i].fitness;

    } 

    //showSwarm(swarm);

    gbest.fitness = max_height;


    /* Select best position */
    sort(swarm.begin(), swarm.end(), compareByFitness);
    
    if (swarm[0].fitness < gbest.fitness)
    {
        gbest.fitness = swarm[0].fitness;
        gbest.permutation = swarm[0].permutation;
    }

    int iter = 0;
    
    c1 = 2.05;
    c2 = 2.05;
    omega_max = 1.2;
    omega_min = 0.7;
    omega = 1.2;

    velocity_max = (n_items)/2;
    velocity_min = -(n_items)/2;
    

    /* create threads */
    long i;
    void *status;
    pthread_attr_t attr; 
    pthread_mutex_init(&mutex, NULL);

    /* Create threads to perform  */
    pthread_attr_init(&attr);
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);

    

    while (iter<MAX_ITER)
    {

        iter++;
        for(i=0; i<N_PARTICLES; i++){
            
            pthread_create(&threads[i], &attr, particle_function, (void *)i);

        } 
        pthread_attr_destroy(&attr);

        /* Join here */

        /* Wait on the other threads */
        for(i=0; i<N_PARTICLES; i++)
        {
            pthread_join(threads[i], &status);
        }

        omega = (omega_max)-((omega_max-omega_min)/MAX_ITER)*iter;

    }
    
    

    //showSwarm(swarm);
    //showRectangles(items);

    //showPermutation(gbest);

    Strip s = {};
    s.height = max_height;
    s.width = strip_width;

    s.x_position = 0;
    s.y_position = 0;

    HR(items,s,n_items,gbest); 
    cout << "-> Fitness of best solution: " << gbest.fitness << endl;
    
    showRectangles(items);
    showPermutation(gbest.permutation);

    //cout << "-> End!" << endl;

    auto t2 = chrono::high_resolution_clock::now(); 
    chrono::duration<double> time_span = (t2 - t1);
    cout << "-> It took me " << time_span.count() << " seconds.";
    cout << endl;

/*     ofstream myfile;
    myfile.open ("Results/"+name+".csv", fstream::app);
    myfile << gbest.fitness << "," << time_span.count() << endl;
    myfile.close(); */

    pthread_mutex_destroy(&mutex);
    pthread_exit(NULL);
    return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xf8, %rsp
movq %rsi, %r15
callq 0x2040
movq %rax, %r12
movq 0x6a49(%rip), %r14      # 0x9fd8
leaq 0x3b96(%rip), %rsi      # 0x712c
movl $0x6, %edx
movq %r14, %rdi
callq 0x21e0
movq (%r14), %rax
movq -0x18(%rax), %rdi
addq %r14, %rdi
movl $0xa, %esi
callq 0x21a0
movsbl %al, %esi
movq %r14, %rdi
callq 0x2030
movq %rax, %rdi
callq 0x2110
xorl %eax, %eax
movl %eax, 0x6d96(%rip)      # 0xa368
movl %eax, 0x6db0(%rip)      # 0xa388
movl %eax, 0x6dae(%rip)      # 0xa38c
movq 0x8(%r15), %rsi
leaq -0xa8(%rbp), %rdi
leaq -0xe8(%rbp), %rdx
callq 0x4300
leaq 0x3b37(%rip), %rsi      # 0x7133
movl $0x15, %edx
movq %r14, %rdi
callq 0x21e0
movq (%r14), %rax
addq -0x18(%rax), %r14
movq %r14, %rdi
movl $0xa, %esi
callq 0x21a0
movsbl %al, %esi
movq 0x69b1(%rip), %rdi      # 0x9fd8
callq 0x2030
movq %rax, %rdi
callq 0x2110
leaq -0x78(%rbp), %r14
movq %r14, -0x10(%r14)
movq -0xa8(%rbp), %rsi
movq -0xa0(%rbp), %rdx
addq %rsi, %rdx
leaq -0x88(%rbp), %rdi
callq 0x4442
leaq 0x6d30(%rip), %rsi      # 0xa390
leaq 0x6d21(%rip), %rdx      # 0xa388
leaq 0x6d1e(%rip), %rcx      # 0xa38c
leaq 0x6cf3(%rip), %r8       # 0xa368
leaq -0x88(%rbp), %rdi
callq 0x258a
movq -0x88(%rbp), %rdi
cmpq %r14, %rdi
je 0x3699
movq -0x78(%rbp), %rsi
incq %rsi
callq 0x21c0
leaq -0xa8(%rbp), %r14
movq %r14, %rdi
movl $0x2e, %esi
movq $-0x1, %rdx
callq 0x2330
movq %rax, %rbx
leal -0x1(%rax), %edx
movq %r14, %rdi
movl $0x2f, %esi
callq 0x2330
leal 0x1(%rax), %edx
notl %eax
addl %eax, %ebx
leaq -0x108(%rbp), %rdi
movq %r14, %rsi
movq %rbx, %rcx
callq 0x21d0
movq 0x68f1(%rip), %rdi      # 0x9fd8
leaq 0x3a5b(%rip), %rsi      # 0x7149
movl $0x14, %edx
callq 0x21e0
movl 0x6c6a(%rip), %esi      # 0xa368
movq 0x68d3(%rip), %rdi      # 0x9fd8
callq 0x22e0
movq %rax, %rdi
callq 0x20c0
movq 0x68bf(%rip), %rdi      # 0x9fd8
leaq 0x3a3e(%rip), %rsi      # 0x715e
movl $0x10, %edx
callq 0x21e0
movl 0x6c58(%rip), %esi      # 0xa388
movq 0x68a1(%rip), %rdi      # 0x9fd8
callq 0x22e0
movq %rax, %rdi
callq 0x20c0
movq 0x688d(%rip), %rdi      # 0x9fd8
leaq 0x3a1d(%rip), %rsi      # 0x716f
movl $0x19, %edx
callq 0x21e0
movl 0x6c2a(%rip), %esi      # 0xa38c
movq 0x686f(%rip), %rdi      # 0x9fd8
callq 0x22e0
movq %rax, %rdi
callq 0x20c0
movq %r12, -0x38(%rbp)
xorl %ebx, %ebx
leaq 0x6aad(%rip), %r14      # 0xa230
leaq 0x6c06(%rip), %r15      # 0xa390
leaq -0xe8(%rbp), %r12
movl 0x6bd1(%rip), %edi      # 0xa368
movq %r14, %rsi
callq 0x279f
movl 0x6be7(%rip), %eax      # 0xa38c
movl %eax, -0xe8(%rbp)
movl 0x6bd7(%rip), %eax      # 0xa388
movl %eax, -0xe4(%rbp)
movq $0x0, -0xe0(%rbp)
movq 0x6a67(%rip), %rcx      # 0xa230
addq %rbx, %rcx
movq %r15, %rdi
movq %r12, %rsi
callq 0x2d7e
movq 0x6a52(%rip), %rsi      # 0xa230
leaq (%rsi,%rbx), %rdi
addq $0x20, %rdi
addq %rbx, %rsi
callq 0x3e8c
movq 0x6a3b(%rip), %rax      # 0xa230
movl 0x18(%rax,%rbx), %ecx
movl %ecx, 0x38(%rax,%rbx)
addq $0x58, %rbx
cmpq $0xa50, %rbx            # imm = 0xA50
jne 0x3791
movl 0x6b7c(%rip), %eax      # 0xa38c
movl %eax, 0x69da(%rip)      # 0xa1f0
movq 0x6a13(%rip), %rdi      # 0xa230
movq 0x6a14(%rip), %rsi      # 0xa238
leaq -0x12b0(%rip), %rdx     # 0x257b
callq 0x433d
movq 0x69f9(%rip), %rsi      # 0xa230
movl 0x18(%rsi), %eax
cmpl 0x69b0(%rip), %eax      # 0xa1f0
jge 0x3854
movl %eax, 0x69a8(%rip)      # 0xa1f0
leaq 0x6989(%rip), %rdi      # 0xa1d8
callq 0x3e8c
movl $0x40033333, %eax       # imm = 0x40033333
movl %eax, 0x6b11(%rip)      # 0xa370
movl %eax, 0x6b0f(%rip)      # 0xa374
movl 0x6afd(%rip), %eax      # 0xa368
movl %eax, %ecx
shrl $0x1f, %ecx
addl %eax, %ecx
movl $0x3f99999a, %eax       # imm = 0x3F99999A
movl %eax, 0x6afb(%rip)      # 0xa378
sarl %ecx
cvtsi2ss %ecx, %xmm0
movl $0x3f333333, 0x6aef(%rip) # imm = 0x3F333333
movl %eax, 0x6ad9(%rip)      # 0xa36c
movss %xmm0, 0x6ae5(%rip)     # 0xa380
negl %ecx
xorps %xmm0, %xmm0
cvtsi2ss %ecx, %xmm0
movss %xmm0, 0x6ad8(%rip)     # 0xa384
leaq 0x6a8d(%rip), %rdi      # 0xa340
movq $0x0, -0x30(%rbp)
xorl %esi, %esi
callq 0x2260
leaq -0xe8(%rbp), %rbx
movq %rbx, %rdi
callq 0x2210
movq %rbx, %r15
movq %rbx, %rdi
xorl %esi, %esi
callq 0x2220
leaq 0x696b(%rip), %r14      # 0xa250
movq %r14, %r13
xorl %ebx, %ebx
leaq -0x6d3(%rip), %r12      # 0x321e
movq %r13, %rdi
movq %r15, %rsi
movq %r12, %rdx
movq %rbx, %rcx
callq 0x2320
incq %rbx
addq $0x8, %r13
cmpq $0x1e, %rbx
jne 0x38f1
movq %r15, %rdi
movq -0x30(%rbp), %r13
incl %r13d
callq 0x22c0
xorl %ebx, %ebx
leaq -0xb0(%rbp), %r12
movq (%rbx,%r14), %rdi
movq %r12, %rsi
callq 0x2180
addq $0x8, %rbx
cmpq $0xf0, %rbx
jne 0x3927
movss 0x6a30(%rip), %xmm0     # 0xa378
movaps %xmm0, %xmm1
subss 0x6a29(%rip), %xmm1     # 0xa37c
xorps %xmm2, %xmm2
cvtsi2ss %r13d, %xmm2
divss 0x36dd(%rip), %xmm1     # 0x7040
mulss %xmm2, %xmm1
addss %xmm0, %xmm1
movss %xmm1, 0x69f9(%rip)     # 0xa36c
movq %r13, -0x30(%rbp)
cmpl $0x2bc, %r13d           # imm = 0x2BC
jne 0x38e5
movl 0x6a02(%rip), %eax      # 0xa38c
leaq -0x118(%rbp), %rsi
movl %eax, (%rsi)
movl 0x69ef(%rip), %eax      # 0xa388
movl %eax, 0x4(%rsi)
movq $0x0, 0x8(%rsi)
leaq 0x69e5(%rip), %rdi      # 0xa390
leaq 0x6826(%rip), %rcx      # 0xa1d8
callq 0x2d7e
movq 0x661a(%rip), %rdi      # 0x9fd8
leaq 0x37c4(%rip), %rsi      # 0x7189
movl $0x1d, %edx
callq 0x21e0
movl 0x681b(%rip), %esi      # 0xa1f0
movq 0x65fc(%rip), %rdi      # 0x9fd8
callq 0x22e0
movq %rax, %rdi
callq 0x20c0
leaq 0x69a0(%rip), %rsi      # 0xa390
leaq -0x68(%rbp), %rdi
callq 0x439c
leaq -0x68(%rbp), %rdi
callq 0x2ea1
movq -0x68(%rbp), %rdi
testq %rdi, %rdi
je 0x3a17
movq -0x58(%rbp), %rsi
subq %rdi, %rsi
callq 0x21c0
leaq 0x67ba(%rip), %rsi      # 0xa1d8
leaq -0x50(%rbp), %rdi
callq 0x412c
leaq -0x50(%rbp), %rdi
callq 0x2aa2
movq -0x50(%rbp), %rdi
testq %rdi, %rdi
je 0x3a45
movq -0x40(%rbp), %rsi
subq %rdi, %rsi
callq 0x21c0
callq 0x2040
movq %rax, %rbx
movq 0x6584(%rip), %rdi      # 0x9fd8
leaq 0x374c(%rip), %rsi      # 0x71a7
movl $0xe, %edx
callq 0x21e0
subq -0x38(%rbp), %rbx
cvtsi2sd %rbx, %xmm0
divsd 0x35da(%rip), %xmm0     # 0x7050
movq 0x655b(%rip), %rdi      # 0x9fd8
callq 0x2280
leaq 0x372d(%rip), %rsi      # 0x71b6
movl $0x9, %edx
movq %rax, %rdi
callq 0x21e0
movq 0x653b(%rip), %rdi      # 0x9fd8
callq 0x20c0
leaq 0x6897(%rip), %rdi      # 0xa340
callq 0x21f0
xorl %edi, %edi
callq 0x2300
jmp 0x3aeb
movq %rax, %rbx
movq -0x50(%rbp), %rdi
testq %rdi, %rdi
je 0x3aee
movq -0x40(%rbp), %rsi
jmp 0x3ad9
movq %rax, %rbx
movq -0x68(%rbp), %rdi
testq %rdi, %rdi
je 0x3aee
movq -0x58(%rbp), %rsi
subq %rdi, %rsi
callq 0x21c0
jmp 0x3aee
jmp 0x3aeb
jmp 0x3aeb
jmp 0x3aeb
jmp 0x3aeb
movq %rax, %rbx
leaq -0xf8(%rbp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x3b29
movq -0xf8(%rbp), %rsi
jmp 0x3b1c
jmp 0x3b26
movq %rax, %rbx
movq -0x88(%rbp), %rdi
cmpq %r14, %rdi
je 0x3b29
movq -0x78(%rbp), %rsi
incq %rsi
callq 0x21c0
jmp 0x3b29
movq %rax, %rbx
leaq -0x98(%rbp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x3b48
movq -0x98(%rbp), %rsi
incq %rsi
callq 0x21c0
movq %rbx, %rdi
callq 0x22f0