// File: 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
subq $0x230, %rsp            # imm = 0x230
movl $0x0, -0x4(%rbp)
movl %edi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
callq 0x2030
movq %rax, -0x18(%rbp)
movq 0x140ff(%rip), %rdi     # 0x17fd8
leaq 0xc24c(%rip), %rsi      # 0x1012c
callq 0x21c0
movq %rax, %rdi
movq 0x140d9(%rip), %rsi     # 0x17fc8
callq 0x2200
movl $0x0, 0x144ca(%rip)     # 0x183c8
movl $0x0, 0x144e0(%rip)     # 0x183e8
movl $0x0, 0x144da(%rip)     # 0x183ec
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x178(%rbp)
leaq -0x39(%rbp), %rdi
movq %rdi, -0x170(%rbp)
callq 0x23a0
movq -0x178(%rbp), %rsi
movq -0x170(%rbp), %rdx
leaq -0x38(%rbp), %rdi
callq 0x5c20
jmp 0x3f4a
leaq -0x39(%rbp), %rdi
callq 0x2220
movq 0x1407e(%rip), %rdi     # 0x17fd8
leaq 0xc1d2(%rip), %rsi      # 0x10133
callq 0x21c0
movq %rax, -0x180(%rbp)
jmp 0x3f6f
movq -0x180(%rbp), %rdi
movq 0x1404b(%rip), %rsi     # 0x17fc8
callq 0x2200
jmp 0x3f84
leaq -0x70(%rbp), %rdi
leaq -0x38(%rbp), %rsi
callq 0x20a0
jmp 0x3f93
leaq 0x14456(%rip), %rsi     # 0x183f0
leaq 0x14447(%rip), %rdx     # 0x183e8
leaq 0x14444(%rip), %rcx     # 0x183ec
leaq 0x14419(%rip), %r8      # 0x183c8
leaq -0x70(%rbp), %rdi
callq 0x2640
jmp 0x3fba
leaq -0x70(%rbp), %rdi
callq 0x2100
leaq -0x38(%rbp), %rdi
movq %rdi, -0x188(%rbp)
movl $0x2e, %esi
movq $-0x1, %rdx
callq 0x23e0
movq -0x188(%rbp), %rdi
movl %eax, -0x74(%rbp)
movl -0x74(%rbp), %eax
decl %eax
movl %eax, %edx
movl $0x2f, %esi
callq 0x23e0
movq -0x188(%rbp), %rsi
movl %eax, -0x78(%rbp)
movl -0x78(%rbp), %eax
movl %eax, %ecx
incl %ecx
movl %ecx, %edx
movl -0x74(%rbp), %ecx
notl %eax
addl %ecx, %eax
movl %eax, %ecx
leaq -0x98(%rbp), %rdi
callq 0x21f0
jmp 0x4024
movq 0x13fad(%rip), %rdi     # 0x17fd8
leaq 0xc117(%rip), %rsi      # 0x10149
callq 0x21c0
movq %rax, -0x190(%rbp)
jmp 0x4040
movq -0x190(%rbp), %rdi
movl 0x1437b(%rip), %esi     # 0x183c8
callq 0x2370
movq %rax, -0x198(%rbp)
jmp 0x405b
movq -0x198(%rbp), %rdi
movq 0x13f5f(%rip), %rsi     # 0x17fc8
callq 0x2200
jmp 0x4070
movq 0x13f61(%rip), %rdi     # 0x17fd8
leaq 0xc0e0(%rip), %rsi      # 0x1015e
callq 0x21c0
movq %rax, -0x1a0(%rbp)
jmp 0x408c
movq -0x1a0(%rbp), %rdi
movl 0x1434f(%rip), %esi     # 0x183e8
callq 0x2370
movq %rax, -0x1a8(%rbp)
jmp 0x40a7
movq -0x1a8(%rbp), %rdi
movq 0x13f13(%rip), %rsi     # 0x17fc8
callq 0x2200
jmp 0x40bc
movq 0x13f15(%rip), %rdi     # 0x17fd8
leaq 0xc0a5(%rip), %rsi      # 0x1016f
callq 0x21c0
movq %rax, -0x1b0(%rbp)
jmp 0x40d8
movq -0x1b0(%rbp), %rdi
movl 0x14307(%rip), %esi     # 0x183ec
callq 0x2370
movq %rax, -0x1b8(%rbp)
jmp 0x40f3
movq -0x1b8(%rbp), %rdi
movq 0x13ec7(%rip), %rsi     # 0x17fc8
callq 0x2200
jmp 0x4108
movl $0x0, -0x9c(%rbp)
cmpl $0x1e, -0x9c(%rbp)
jge 0x4291
movl 0x142a3(%rip), %edi     # 0x183c8
leaq 0x14164(%rip), %rsi     # 0x18290
callq 0x28f0
jmp 0x4133
xorps %xmm0, %xmm0
movaps %xmm0, -0xb0(%rbp)
movl 0x142a9(%rip), %eax     # 0x183ec
movl %eax, -0xb0(%rbp)
movl 0x14299(%rip), %eax     # 0x183e8
movl %eax, -0xac(%rbp)
movl $0x0, -0xa8(%rbp)
movl $0x0, -0xa4(%rbp)
movl 0x14259(%rip), %eax     # 0x183c8
movl %eax, -0x1bc(%rbp)
movslq -0x9c(%rbp), %rsi
leaq 0x1410d(%rip), %rdi     # 0x18290
callq 0x58e0
movl -0x1bc(%rbp), %edx
movq %rax, %rcx
leaq 0x14258(%rip), %rdi     # 0x183f0
leaq -0xb0(%rbp), %rsi
callq 0x30c0
jmp 0x41a6
movslq -0x9c(%rbp), %rsi
leaq 0x140dc(%rip), %rdi     # 0x18290
movq %rdi, -0x1d0(%rbp)
callq 0x58e0
movq -0x1d0(%rbp), %rdi
movq %rax, -0x1c8(%rbp)
movslq -0x9c(%rbp), %rsi
callq 0x58e0
movq -0x1c8(%rbp), %rsi
movq %rax, %rdi
addq $0x20, %rdi
callq 0x4f20
jmp 0x41ef
movslq -0x9c(%rbp), %rsi
leaq 0x14093(%rip), %rdi     # 0x18290
callq 0x58e0
movl 0x18(%rax), %eax
movl %eax, -0x1d4(%rbp)
movslq -0x9c(%rbp), %rsi
leaq 0x14077(%rip), %rdi     # 0x18290
callq 0x58e0
movl -0x1d4(%rbp), %ecx
movl %ecx, 0x38(%rax)
movl -0x9c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x9c(%rbp)
jmp 0x4112
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
leaq -0x39(%rbp), %rdi
callq 0x2220
jmp 0x4753
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
jmp 0x474a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
leaq -0x70(%rbp), %rdi
callq 0x2100
jmp 0x474a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
jmp 0x473e
movl 0x14155(%rip), %eax     # 0x183ec
movl %eax, 0x13fb3(%rip)     # 0x18250
leaq 0x13fec(%rip), %rdi     # 0x18290
movq %rdi, -0x1e0(%rbp)
callq 0x5d20
movq -0x1e0(%rbp), %rdi
movq %rax, -0xb8(%rbp)
callq 0x5d50
movq %rax, -0xc0(%rbp)
movq -0xb8(%rbp), %rdi
movq -0xc0(%rbp), %rsi
leaq -0x1ccf(%rip), %rdx     # 0x2610
callq 0x5cd0
jmp 0x42e6
leaq 0x13fa3(%rip), %rdi     # 0x18290
xorl %eax, %eax
movl %eax, %esi
callq 0x58e0
movl 0x18(%rax), %eax
cmpl 0x13f51(%rip), %eax     # 0x18250
jge 0x435c
leaq 0x13f88(%rip), %rdi     # 0x18290
movq %rdi, -0x1f8(%rbp)
xorl %eax, %eax
movl %eax, %esi
movq %rsi, -0x1f0(%rbp)
callq 0x58e0
movq -0x1f8(%rbp), %rdi
movq -0x1f0(%rbp), %rsi
movl 0x18(%rax), %eax
movl %eax, 0x13f1a(%rip)     # 0x18250
leaq 0x13efb(%rip), %rax     # 0x18238
movq %rax, -0x1e8(%rbp)
callq 0x58e0
movq -0x1e8(%rbp), %rdi
movq %rax, %rsi
callq 0x4f20
jmp 0x435a
jmp 0x435c
movl $0x0, -0xc4(%rbp)
movss 0xbcba(%rip), %xmm0     # 0x10028
movss %xmm0, 0x1405a(%rip)    # 0x183d0
movss 0xbcaa(%rip), %xmm0     # 0x10028
movss %xmm0, 0x1404e(%rip)    # 0x183d4
movss 0xbc92(%rip), %xmm0     # 0x10020
movss %xmm0, 0x14042(%rip)    # 0x183d8
movss 0xbc86(%rip), %xmm0     # 0x10024
movss %xmm0, 0x14036(%rip)    # 0x183dc
movss 0xbc72(%rip), %xmm0     # 0x10020
movss %xmm0, 0x14016(%rip)    # 0x183cc
movl 0x1400c(%rip), %eax     # 0x183c8
movl $0x2, %ecx
cltd
idivl %ecx
cvtsi2ss %eax, %xmm0
movss %xmm0, 0x14010(%rip)    # 0x183e0
xorl %eax, %eax
subl 0x13ff0(%rip), %eax     # 0x183c8
movl $0x2, %ecx
cltd
idivl %ecx
cvtsi2ss %eax, %xmm0
movss %xmm0, 0x13ff8(%rip)    # 0x183e4
leaq 0x13fad(%rip), %rdi     # 0x183a0
xorl %eax, %eax
movl %eax, %esi
callq 0x22f0
leaq -0x110(%rbp), %rdi
callq 0x2280
leaq -0x110(%rbp), %rdi
xorl %esi, %esi
callq 0x22b0
cmpl $0x2bc, -0xc4(%rbp)     # imm = 0x2BC
jge 0x4532
movl -0xc4(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xc4(%rbp)
movq $0x0, -0xd0(%rbp)
cmpq $0x1e, -0xd0(%rbp)
jge 0x448d
movq -0xd0(%rbp), %rax
leaq 0x13e58(%rip), %rdi     # 0x182b0
shlq $0x3, %rax
addq %rax, %rdi
movq -0xd0(%rbp), %rcx
leaq -0x110(%rbp), %rsi
leaq -0xd84(%rip), %rdx      # 0x36f0
callq 0x23c0
movq -0xd0(%rbp), %rax
addq $0x1, %rax
movq %rax, -0xd0(%rbp)
jmp 0x4440
leaq -0x110(%rbp), %rdi
callq 0x2350
movq $0x0, -0xd0(%rbp)
cmpq $0x1e, -0xd0(%rbp)
jge 0x44e4
movq -0xd0(%rbp), %rcx
leaq 0x13df4(%rip), %rax     # 0x182b0
movq (%rax,%rcx,8), %rdi
leaq -0xd8(%rbp), %rsi
callq 0x21a0
jmp 0x44ce
jmp 0x44d0
movq -0xd0(%rbp), %rax
addq $0x1, %rax
movq %rax, -0xd0(%rbp)
jmp 0x44a4
movss 0x13eec(%rip), %xmm1    # 0x183d8
movss 0x13ee4(%rip), %xmm0    # 0x183d8
subss 0x13ee0(%rip), %xmm0    # 0x183dc
movss 0xbb28(%rip), %xmm2     # 0x1002c
divss %xmm2, %xmm0
cvtsi2ssl -0xc4(%rbp), %xmm2
movd %xmm0, %eax
xorl $0x80000000, %eax       # imm = 0x80000000
movd %eax, %xmm0
mulss %xmm2, %xmm0
addss %xmm1, %xmm0
movss %xmm0, 0x13e9f(%rip)    # 0x183cc
jmp 0x4416
xorps %xmm0, %xmm0
movaps %xmm0, -0x120(%rbp)
movl 0x13eaa(%rip), %eax     # 0x183ec
movl %eax, -0x120(%rbp)
movl 0x13e9a(%rip), %eax     # 0x183e8
movl %eax, -0x11c(%rbp)
movl $0x0, -0x118(%rbp)
movl $0x0, -0x114(%rbp)
movl 0x13e5a(%rip), %edx     # 0x183c8
leaq 0x13e7b(%rip), %rdi     # 0x183f0
leaq 0x13cbc(%rip), %rcx     # 0x18238
leaq -0x120(%rbp), %rsi
callq 0x30c0
jmp 0x458a
movq 0x13a47(%rip), %rdi     # 0x17fd8
leaq 0xbbf1(%rip), %rsi      # 0x10189
callq 0x21c0
movq %rax, -0x200(%rbp)
jmp 0x45a6
movq -0x200(%rbp), %rdi
movl 0x13c9d(%rip), %esi     # 0x18250
callq 0x2370
movq %rax, -0x208(%rbp)
jmp 0x45c1
movq -0x208(%rbp), %rdi
movq 0x139f9(%rip), %rsi     # 0x17fc8
callq 0x2200
jmp 0x45d6
leaq 0x13e13(%rip), %rsi     # 0x183f0
leaq -0x138(%rbp), %rdi
callq 0x5d80
jmp 0x45eb
leaq -0x138(%rbp), %rdi
callq 0x33e0
jmp 0x45f9
leaq -0x138(%rbp), %rdi
callq 0x4880
leaq 0x13c2c(%rip), %rsi     # 0x18238
leaq -0x150(%rbp), %rdi
callq 0x5780
jmp 0x461a
leaq -0x150(%rbp), %rdi
callq 0x2cc0
jmp 0x4628
leaq -0x150(%rbp), %rdi
callq 0x5550
callq 0x2030
movq %rax, -0x158(%rbp)
leaq -0x158(%rbp), %rdi
leaq -0x18(%rbp), %rsi
callq 0x5e70
movq %rax, -0x210(%rbp)
jmp 0x4659
movq -0x210(%rbp), %rax
movq %rax, -0x168(%rbp)
leaq -0x160(%rbp), %rdi
leaq -0x168(%rbp), %rsi
callq 0x5ec0
jmp 0x467c
movq 0x13955(%rip), %rdi     # 0x17fd8
leaq 0xbb1d(%rip), %rsi      # 0x101a7
callq 0x21c0
movq %rax, -0x218(%rbp)
jmp 0x4698
leaq -0x160(%rbp), %rdi
callq 0x5f00
movsd %xmm0, -0x220(%rbp)
jmp 0x46ae
movsd -0x220(%rbp), %xmm0
movq -0x218(%rbp), %rdi
callq 0x23d0
movq %rax, -0x228(%rbp)
jmp 0x46cb
movq -0x228(%rbp), %rdi
leaq 0xbadd(%rip), %rsi      # 0x101b6
callq 0x21c0
jmp 0x46e0
movq 0x138f1(%rip), %rdi     # 0x17fd8
movq 0x138da(%rip), %rsi     # 0x17fc8
callq 0x2200
jmp 0x46f5
leaq 0x13ca4(%rip), %rdi     # 0x183a0
callq 0x2260
xorl %eax, %eax
movl %eax, %edi
callq 0x2390
jmp 0x470c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
leaq -0x138(%rbp), %rdi
callq 0x4880
jmp 0x473e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
leaq -0x150(%rbp), %rdi
callq 0x5550
leaq -0x98(%rbp), %rdi
callq 0x2100
leaq -0x38(%rbp), %rdi
callq 0x2100
movq -0x48(%rbp), %rdi
callq 0x2380
nopl (%rax)