// File: pollo[P]graph-partitioning/partitioners.cpp
// Function: linear_deterministic_greedy(Graph const&, int, Partition*)
void linear_deterministic_greedy(const Graph& graph,
                                 int partitions_number,
                                 Partition* partition)
{
  vector<int> nodes;
  vector<double> partition_score(partitions_number);

  //get random sorted nodes
  graph.get_nodes_randomly(&nodes);

  //initialize partitions
  partition->set_size(nodes.size(), partitions_number);

  for (vector<int>::iterator node = nodes.begin();
       node != nodes.end();
       ++node) {

    //initialize partitions score
    for (int i=0; i<partitions_number; i++)
      partition_score[i] = 0;

    //compute partitions score
    for (vector<int>::const_iterator neighbor =
           graph.get_neighbors(*node).begin();
         neighbor != graph.get_neighbors(*node).end();
         ++neighbor)
    {
      int neighbor_partition = partition->get_node_partition(*neighbor);
      if (neighbor_partition >= 0) {
        partition_score[neighbor_partition]++;
      }
    }

    //weight partitions score
    for (int i=0; i<partitions_number; i++)
    {
      double C = ((double)nodes.size())/partitions_number;
      partition_score[i] *= 1 - partition->get_partition_size(i)/C;
    }

    //select best partition
    int selected_partition = -1;
    double score = 0;
    for (int i=0; i<partitions_number; i++)
    {
      if (partition_score[i] > score)
      {
        selected_partition = i;
        score = partition_score[i];
      }
      else if (partition_score[i] == score)
      {
        if (selected_partition == -1 ||
            partition->get_partition_size(i) <=
            partition->get_partition_size(selected_partition))
        {
          selected_partition = i;
        }
      }
    }

    //assign node to partition
    partition->set_node_partition(*node, selected_partition);
  }
}

// Assembly:
subq $0x118, %rsp            # imm = 0x118
movq %rdi, 0x110(%rsp)
movl %esi, 0x10c(%rsp)
movq %rdx, 0x100(%rsp)
leaq 0xe8(%rsp), %rdi
callq 0x2a30
movslq 0x10c(%rsp), %rax
movq %rax, 0x58(%rsp)
leaq 0xcf(%rsp), %rdi
movq %rdi, 0x60(%rsp)
callq 0xa170
movq 0x58(%rsp), %rsi
movq 0x60(%rsp), %rdx
leaq 0xd0(%rsp), %rdi
callq 0xa180
jmp 0x9143
leaq 0xcf(%rsp), %rdi
callq 0xa200
movq 0x110(%rsp), %rdi
leaq 0xe8(%rsp), %rsi
callq 0x32d0
jmp 0x9167
movq 0x100(%rsp), %rax
movq %rax, 0x50(%rsp)
leaq 0xe8(%rsp), %rdi
callq 0x4560
movq 0x50(%rsp), %rdi
movl %eax, %esi
movl 0x10c(%rsp), %edx
callq 0x80d0
jmp 0x9196
leaq 0xe8(%rsp), %rdi
callq 0x3e80
movq %rax, 0xb0(%rsp)
leaq 0xe8(%rsp), %rdi
callq 0x3eb0
movq %rax, 0xa8(%rsp)
leaq 0xb0(%rsp), %rdi
leaq 0xa8(%rsp), %rsi
callq 0x6420
testb $0x1, %al
jne 0x91de
jmp 0x9591
movl $0x0, 0xa4(%rsp)
movl 0xa4(%rsp), %eax
cmpl 0x10c(%rsp), %eax
jge 0x9274
movslq 0xa4(%rsp), %rsi
leaq 0xd0(%rsp), %rdi
callq 0xa210
xorps %xmm0, %xmm0
movsd %xmm0, (%rax)
movl 0xa4(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xa4(%rsp)
jmp 0x91e9
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xc0(%rsp)
movl %eax, 0xbc(%rsp)
leaq 0xcf(%rsp), %rdi
callq 0xa200
jmp 0x95b3
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xc0(%rsp)
movl %eax, 0xbc(%rsp)
leaq 0xd0(%rsp), %rdi
callq 0xa230
jmp 0x95b3
movq 0x110(%rsp), %rax
movq %rax, 0x40(%rsp)
leaq 0xb0(%rsp), %rdi
callq 0x5840
movq 0x40(%rsp), %rdi
movl (%rax), %esi
callq 0x3280
movq %rax, 0x48(%rsp)
jmp 0x92a1
movq 0x48(%rsp), %rdi
callq 0x3f50
movq %rax, 0x98(%rsp)
movq 0x110(%rsp), %rax
movq %rax, 0x30(%rsp)
leaq 0xb0(%rsp), %rdi
callq 0x5840
movq 0x30(%rsp), %rdi
movl (%rax), %esi
callq 0x3280
movq %rax, 0x38(%rsp)
jmp 0x92e0
movq 0x38(%rsp), %rdi
callq 0x3fc0
movq %rax, 0x90(%rsp)
leaq 0x98(%rsp), %rdi
leaq 0x90(%rsp), %rsi
callq 0x3f80
testb $0x1, %al
jne 0x930d
jmp 0x9387
movq 0x100(%rsp), %rax
movq %rax, 0x20(%rsp)
leaq 0x98(%rsp), %rdi
callq 0x3ff0
movq 0x20(%rsp), %rdi
movl (%rax), %esi
callq 0x81a0
movl %eax, 0x2c(%rsp)
jmp 0x9339
movl 0x2c(%rsp), %eax
movl %eax, 0x8c(%rsp)
cmpl $0x0, 0x8c(%rsp)
jl 0x9373
movslq 0x8c(%rsp), %rsi
leaq 0xd0(%rsp), %rdi
callq 0xa210
movsd 0x3025(%rip), %xmm0     # 0xc390
addsd (%rax), %xmm0
movsd %xmm0, (%rax)
jmp 0x9375
leaq 0x98(%rsp), %rdi
callq 0x4540
jmp 0x92b3
movl $0x0, 0x88(%rsp)
movl 0x88(%rsp), %eax
cmpl 0x10c(%rsp), %eax
jge 0x9466
leaq 0xe8(%rsp), %rdi
callq 0x4560
movq %rax, %xmm0
movaps 0x2fb1(%rip), %xmm1     # 0xc370
punpckldq %xmm1, %xmm0    # xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
movapd 0x2fb5(%rip), %xmm1     # 0xc380
subpd %xmm1, %xmm0
movaps %xmm0, %xmm1
unpckhpd %xmm0, %xmm0            # xmm0 = xmm0[1,1]
addsd %xmm1, %xmm0
cvtsi2sdl 0x10c(%rsp), %xmm1
divsd %xmm1, %xmm0
movsd %xmm0, 0x80(%rsp)
movq 0x100(%rsp), %rdi
movl 0x88(%rsp), %esi
callq 0x81d0
movl %eax, 0x1c(%rsp)
jmp 0x940a
movl 0x1c(%rsp), %eax
cvtsi2sd %eax, %xmm1
divsd 0x80(%rsp), %xmm1
movsd 0x2f6d(%rip), %xmm0     # 0xc390
subsd %xmm1, %xmm0
movsd %xmm0, 0x10(%rsp)
movslq 0x88(%rsp), %rsi
leaq 0xd0(%rsp), %rdi
callq 0xa210
movsd 0x10(%rsp), %xmm0
mulsd (%rax), %xmm0
movsd %xmm0, (%rax)
movl 0x88(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x88(%rsp)
jmp 0x9392
movl $0xffffffff, 0x7c(%rsp) # imm = 0xFFFFFFFF
xorps %xmm0, %xmm0
movsd %xmm0, 0x70(%rsp)
movl $0x0, 0x6c(%rsp)
movl 0x6c(%rsp), %eax
cmpl 0x10c(%rsp), %eax
jge 0x9553
movslq 0x6c(%rsp), %rsi
leaq 0xd0(%rsp), %rdi
callq 0xa210
movsd (%rax), %xmm0
ucomisd 0x70(%rsp), %xmm0
jbe 0x94d4
movl 0x6c(%rsp), %eax
movl %eax, 0x7c(%rsp)
movslq 0x6c(%rsp), %rsi
leaq 0xd0(%rsp), %rdi
callq 0xa210
movsd (%rax), %xmm0
movsd %xmm0, 0x70(%rsp)
jmp 0x9541
movslq 0x6c(%rsp), %rsi
leaq 0xd0(%rsp), %rdi
callq 0xa210
movsd (%rax), %xmm0
ucomisd 0x70(%rsp), %xmm0
jne 0x953f
jp 0x953f
cmpl $-0x1, 0x7c(%rsp)
je 0x9535
movq 0x100(%rsp), %rdi
movl 0x6c(%rsp), %esi
callq 0x81d0
movl %eax, 0xc(%rsp)
jmp 0x9512
movq 0x100(%rsp), %rdi
movl 0x7c(%rsp), %esi
callq 0x81d0
movl %eax, 0x8(%rsp)
jmp 0x9529
movl 0xc(%rsp), %eax
movl 0x8(%rsp), %ecx
cmpl %ecx, %eax
jg 0x953d
movl 0x6c(%rsp), %eax
movl %eax, 0x7c(%rsp)
jmp 0x953f
jmp 0x9541
jmp 0x9543
movl 0x6c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x6c(%rsp)
jmp 0x947f
movq 0x100(%rsp), %rax
movq %rax, (%rsp)
leaq 0xb0(%rsp), %rdi
callq 0x5840
movq (%rsp), %rdi
movl (%rax), %esi
movl 0x7c(%rsp), %edx
callq 0x8140
jmp 0x957d
jmp 0x957f
leaq 0xb0(%rsp), %rdi
callq 0x5810
jmp 0x91ab
leaq 0xd0(%rsp), %rdi
callq 0xa230
leaq 0xe8(%rsp), %rdi
callq 0x2ad0
addq $0x118, %rsp            # imm = 0x118
retq
leaq 0xe8(%rsp), %rdi
callq 0x2ad0
movq 0xc0(%rsp), %rdi
callq 0x2270
nopl (%rax)