// File: /workspace/github_cpp_makefile_star2_O1/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 0x6a4e(%rip), %r14      # 0x9fd8
leaq 0x3b9b(%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, 0x6d9b(%rip)      # 0xa368
movl %eax, 0x6db5(%rip)      # 0xa388
movl %eax, 0x6db3(%rip)      # 0xa38c
movq 0x8(%r15), %rsi
leaq -0xa8(%rbp), %rdi
leaq -0xe0(%rbp), %rdx
callq 0x42f6
leaq 0x3b3c(%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 0x69b6(%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 0x4438
leaq 0x6d35(%rip), %rsi      # 0xa390
leaq 0x6d26(%rip), %rdx      # 0xa388
leaq 0x6d23(%rip), %rcx      # 0xa38c
leaq 0x6cf8(%rip), %r8       # 0xa368
leaq -0x88(%rbp), %rdi
callq 0x258a
movq -0x88(%rbp), %rdi
cmpq %r14, %rdi
je 0x3694
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 0x68f6(%rip), %rdi      # 0x9fd8
leaq 0x3a60(%rip), %rsi      # 0x7149
movl $0x14, %edx
callq 0x21e0
movl 0x6c6f(%rip), %esi      # 0xa368
movq 0x68d8(%rip), %rdi      # 0x9fd8
callq 0x22e0
movq %rax, %rdi
callq 0x20c0
movq 0x68c4(%rip), %rdi      # 0x9fd8
leaq 0x3a43(%rip), %rsi      # 0x715e
movl $0x10, %edx
callq 0x21e0
movl 0x6c5d(%rip), %esi      # 0xa388
movq 0x68a6(%rip), %rdi      # 0x9fd8
callq 0x22e0
movq %rax, %rdi
callq 0x20c0
movq 0x6892(%rip), %rdi      # 0x9fd8
leaq 0x3a22(%rip), %rsi      # 0x716f
movl $0x19, %edx
callq 0x21e0
movl 0x6c2f(%rip), %esi      # 0xa38c
movq 0x6874(%rip), %rdi      # 0x9fd8
callq 0x22e0
movq %rax, %rdi
callq 0x20c0
movq %r12, -0x38(%rbp)
xorl %ebx, %ebx
leaq 0x6ab2(%rip), %r14      # 0xa230
leaq 0x6c0b(%rip), %r15      # 0xa390
leaq -0xe0(%rbp), %r12
movl 0x6bd6(%rip), %edi      # 0xa368
movq %r14, %rsi
callq 0x2799
xorps %xmm0, %xmm0
movaps %xmm0, -0xe0(%rbp)
movl 0x6be2(%rip), %eax      # 0xa38c
movl %eax, -0xe0(%rbp)
movl 0x6bd2(%rip), %eax      # 0xa388
movl %eax, -0xdc(%rbp)
movq $0x0, -0xd8(%rbp)
movq 0x6a62(%rip), %rcx      # 0xa230
addq %rbx, %rcx
movq %r15, %rdi
movq %r12, %rsi
callq 0x2d6d
movq 0x6a4d(%rip), %rsi      # 0xa230
leaq (%rsi,%rbx), %rdi
addq $0x20, %rdi
addq %rbx, %rsi
callq 0x3ea0
movq 0x6a36(%rip), %rax      # 0xa230
movl 0x18(%rax,%rbx), %ecx
movl %ecx, 0x38(%rax,%rbx)
addq $0x58, %rbx
cmpq $0xa50, %rbx            # imm = 0xA50
jne 0x378c
movl 0x6b73(%rip), %eax      # 0xa38c
movl %eax, 0x69d1(%rip)      # 0xa1f0
movq 0x6a0a(%rip), %rdi      # 0xa230
movq 0x6a0b(%rip), %rsi      # 0xa238
leaq -0x12b9(%rip), %rdx     # 0x257b
callq 0x4333
movq 0x69f0(%rip), %rsi      # 0xa230
movl 0x18(%rsi), %eax
cmpl 0x69a7(%rip), %eax      # 0xa1f0
jge 0x385d
movl %eax, 0x699f(%rip)      # 0xa1f0
leaq 0x6980(%rip), %rdi      # 0xa1d8
callq 0x3ea0
movl $0x40033333, %eax       # imm = 0x40033333
movl %eax, 0x6b08(%rip)      # 0xa370
movl %eax, 0x6b06(%rip)      # 0xa374
movl 0x6af4(%rip), %eax      # 0xa368
movl %eax, %ecx
shrl $0x1f, %ecx
addl %eax, %ecx
movl $0x3f99999a, %eax       # imm = 0x3F99999A
movl %eax, 0x6af2(%rip)      # 0xa378
sarl %ecx
xorps %xmm0, %xmm0
cvtsi2ss %ecx, %xmm0
movl $0x3f333333, 0x6ae3(%rip) # imm = 0x3F333333
movl %eax, 0x6acd(%rip)      # 0xa36c
movss %xmm0, 0x6ad9(%rip)     # 0xa380
negl %ecx
xorps %xmm0, %xmm0
cvtsi2ss %ecx, %xmm0
movss %xmm0, 0x6acc(%rip)     # 0xa384
leaq 0x6a81(%rip), %rdi      # 0xa340
movq $0x0, -0x30(%rbp)
xorl %esi, %esi
callq 0x2260
leaq -0xe0(%rbp), %rbx
movq %rbx, %rdi
callq 0x2210
movq %rbx, %r15
movq %rbx, %rdi
xorl %esi, %esi
callq 0x2220
leaq 0x695f(%rip), %r14      # 0xa250
movq %r14, %r13
xorl %ebx, %ebx
leaq -0x6fa(%rip), %r12      # 0x3203
movq %r13, %rdi
movq %r15, %rsi
movq %r12, %rdx
movq %rbx, %rcx
callq 0x2320
incq %rbx
addq $0x8, %r13
cmpq $0x1e, %rbx
jne 0x38fd
movq %r15, %rdi
movq -0x30(%rbp), %r13
incl %r13d
callq 0x22c0
xorl %ebx, %ebx
leaq -0xe8(%rbp), %r12
movq (%rbx,%r14), %rdi
movq %r12, %rsi
callq 0x2180
addq $0x8, %rbx
cmpq $0xf0, %rbx
jne 0x3933
movss 0x6a24(%rip), %xmm0     # 0xa378
movaps %xmm0, %xmm1
subss 0x6a1d(%rip), %xmm1     # 0xa37c
xorps %xmm2, %xmm2
cvtsi2ss %r13d, %xmm2
divss 0x36d1(%rip), %xmm1     # 0x7040
mulss %xmm2, %xmm1
addss %xmm0, %xmm1
movss %xmm1, 0x69ed(%rip)     # 0xa36c
movq %r13, -0x30(%rbp)
cmpl $0x2bc, %r13d           # imm = 0x2BC
jne 0x38f1
xorps %xmm0, %xmm0
leaq -0x120(%rbp), %rsi
movaps %xmm0, (%rsi)
movl 0x69e9(%rip), %eax      # 0xa38c
movl %eax, (%rsi)
movl 0x69dd(%rip), %eax      # 0xa388
movl %eax, 0x4(%rsi)
movq $0x0, 0x8(%rsi)
leaq 0x69d3(%rip), %rdi      # 0xa390
leaq 0x6814(%rip), %rcx      # 0xa1d8
callq 0x2d6d
movq 0x6608(%rip), %rdi      # 0x9fd8
leaq 0x37b2(%rip), %rsi      # 0x7189
movl $0x1d, %edx
callq 0x21e0
movl 0x6809(%rip), %esi      # 0xa1f0
movq 0x65ea(%rip), %rdi      # 0x9fd8
callq 0x22e0
movq %rax, %rdi
callq 0x20c0
leaq 0x698e(%rip), %rsi      # 0xa390
leaq -0x68(%rbp), %rdi
callq 0x4392
leaq -0x68(%rbp), %rdi
callq 0x2e86
movq -0x68(%rbp), %rdi
testq %rdi, %rdi
je 0x3a29
movq -0x58(%rbp), %rsi
subq %rdi, %rsi
callq 0x21c0
leaq 0x67a8(%rip), %rsi      # 0xa1d8
leaq -0x50(%rbp), %rdi
callq 0x4124
leaq -0x50(%rbp), %rdi
callq 0x2a9c
movq -0x50(%rbp), %rdi
testq %rdi, %rdi
je 0x3a57
movq -0x40(%rbp), %rsi
subq %rdi, %rsi
callq 0x21c0
callq 0x2040
movq %rax, %rbx
movq 0x6572(%rip), %rdi      # 0x9fd8
leaq 0x373a(%rip), %rsi      # 0x71a7
movl $0xe, %edx
callq 0x21e0
subq -0x38(%rbp), %rbx
xorps %xmm0, %xmm0
cvtsi2sd %rbx, %xmm0
divsd 0x35c5(%rip), %xmm0     # 0x7050
movq 0x6546(%rip), %rdi      # 0x9fd8
callq 0x2280
leaq 0x3718(%rip), %rsi      # 0x71b6
movl $0x9, %edx
movq %rax, %rdi
callq 0x21e0
movq 0x6526(%rip), %rdi      # 0x9fd8
callq 0x20c0
leaq 0x6882(%rip), %rdi      # 0xa340
callq 0x21f0
xorl %edi, %edi
callq 0x2300
jmp 0x3b00
movq %rax, %rbx
movq -0x50(%rbp), %rdi
testq %rdi, %rdi
je 0x3b03
movq -0x40(%rbp), %rsi
jmp 0x3aee
movq %rax, %rbx
movq -0x68(%rbp), %rdi
testq %rdi, %rdi
je 0x3b03
movq -0x58(%rbp), %rsi
subq %rdi, %rsi
callq 0x21c0
jmp 0x3b03
jmp 0x3b00
jmp 0x3b00
jmp 0x3b00
jmp 0x3b00
movq %rax, %rbx
leaq -0xf8(%rbp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x3b3e
movq -0xf8(%rbp), %rsi
jmp 0x3b31
jmp 0x3b3b
movq %rax, %rbx
movq -0x88(%rbp), %rdi
cmpq %r14, %rdi
je 0x3b3e
movq -0x78(%rbp), %rsi
incq %rsi
callq 0x21c0
jmp 0x3b3e
movq %rax, %rbx
leaq -0x98(%rbp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x3b5d
movq -0x98(%rbp), %rsi
incq %rsi
callq 0x21c0
movq %rbx, %rdi
callq 0x22f0
nop