aboutsummaryrefslogblamecommitdiffstats
path: root/src/random_heuristic.c
blob: 529a1863ae8c0404e7c2828c27b3d73744e6234b (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11



                             
                  
 




                                                                  




                                                    

      



















                                                                                          






                                                          





































                                                  






                                                










                                                         


                                                                                                                      










                                                                                                        
 



                                                    

      




                                                                                          




                                                           
 


                            






                                                          

               
 








                                                  









                                              



                                    




                                                    
 
                                                
                                          
 

                             
 






                           
 
#include <stdlib.h>
#include "random_heuristic.h"
#include "structs.h"
#include "common.h"
#include <stdio.h>

struct front_item * random_heuristic(struct data * data) {
  struct front_item * front = new_front_item(0, 0, NULL, NULL);
  struct front_item * front_last = front;
  struct tree_item * tree = new_tree_item(0, 0, 0, 0, NULL, NULL);
  long int tree_size = 1;
  
  /* Choose tree node randomly */
  long int position = rand() % tree_size;
  struct tree_item * node = tree;
  for(int i = 0; i < position; i++,node=node->next);

  do {
    
    /* Check if node is leaf */
    if(node->depth == data->N) {
      front_last->next = new_front_item(node->values.p, node->values.w, front_last, NULL);
      front_last = front_last->next;
      
      struct tree_item * old = node;
      if(tree == old) {
        tree = node->next;
      }

      if(node->next != NULL) {
        node->next->prev = node->prev;
      }
      if(node->prev != NULL) {
        node->prev->next = node->next;
      }
      free(old);
      /* Reduce tree_size */
      tree_size--;
      
      if(tree != NULL) {
        /* Select new random node */
        position = rand() % tree_size;
        node = tree;
        for(int i = 0; i < position; i++,node=node->next);
      }

      continue;
    }
    
    /* Make left node (select item) */
    struct tree_item * left = new_tree_item(
      node->depth + 1,
      node->itemi + 1,
      node->values.w + data->items[node->itemi].w,
      node->values.p + data->items[node->itemi].p,
      node->prev,
      node
    );
    if(node->prev != NULL){
      node->prev->next = left;
    }

    /* Make right node (do not select item) */
    struct tree_item * right = new_tree_item(
      node->depth + 1,
      node->itemi + 1,
      node->values.w,
      node->values.p,
      left,
      node->next
    );
    if(node->next != NULL) {
      node->next->prev = right;
    }

    /* Adjust left->next to right */
    left->next = right;

    struct tree_item * old = node;
    if(node == tree) {
      tree = left;
    }
    free(old);
    
    /* Choose left or right randomly for node */
    if(rand() % 2 == 0) {
      node = left;
    } else {
      node = right;
    }

    /* Increment tree_size */
    tree_size++;
  } while(tree != NULL);
 
  /* Remove first item from front (only a placeholder) */
  front=front->next;
  free(front->prev);
  front->prev = NULL;

  return front;
}

struct online_return random_heuristic_online(struct data * data, struct front_item * front, struct tree_item * tree) {
  if(front == NULL) {
    front = new_front_item(0, 0, NULL, NULL);
  }
  struct front_item * front_last = front;
  for(;front_last->next != NULL; front_last=front_last->next);
  
  if(tree == NULL) {
    tree = new_tree_item(0, 0, 0, 0, NULL, NULL);
  }
  long int tree_size = 0;
  for(struct tree_item * tree_node = tree; tree_node != NULL; tree_node = tree_node->next, tree_size++);

  /* Choose tree node randomly */
  long int position = rand() % tree_size;
  struct tree_item * node = tree;
  for(int i = 0; i < position; i++,node=node->next);

  do {
    /* Check if node is leaf */
    if(node->depth == data->N) {
      front_last->next = new_front_item(node->values.p, node->values.w, front_last, NULL);
      front_last = front_last->next;
      
      if(node->prev != NULL) node->prev->next = node->next;
      if(node->next != NULL) node->next->prev = node->prev;
      
      if(tree == node) tree = node->next;
      free(node);

      /* Reduce tree_size */
      tree_size--;

      if(tree != NULL) {
        /* Select new random node */
        position = rand() % tree_size;
        node = tree;
        for(int i = 0; i < position; i++,node=node->next);
      }

      continue;
    }

    /* Make left node (select item) */
    struct tree_item * left = new_tree_item(
      node->depth + 1,
      node->itemi + 1,
      node->values.w + data->items[node->itemi].w,
      node->values.p + data->items[node->itemi].p,
      node->prev,
      node
    );

    /* Make right node (do not select item) */
    struct tree_item * right = new_tree_item(
      node->depth + 1,
      node->itemi + 1,
      node->values.w,
      node->values.p,
      left,
      node->next
    );

    /* Adjust left->next to right */
    left->next = right;

    if(node->prev != NULL) node->prev->next = left;
    if(node->next != NULL) node->next->prev = right;

    if(tree == node) tree = left;
    free(node);

    /* Choose left or right randomly for node */
    node = rand() % 2 == 0 ? left : right;

    /* Increment tree_size */
    tree_size++;

  } while(tree != NULL);

  struct online_return ret;
  ret.front = front;
  ret.tree = tree;
 
  return ret;
}