summaryrefslogblamecommitdiffstats
path: root/src/nem_ull.c
blob: 2605e69fc308b549883b0847b33f21bf03082002 (plain) (tree)
1
2
3
4
5
6
7
                   
                  




                                             




                                
        
 

                                            
 
                      

























                                                                                 
   
 
                   

 













































                                                                                 
                                                                                 



                                
               





                                                    
                                            




                                                    
                    





































                                                          
                          






                                                                                         
                        











                                                         
           






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

struct front_item * nem_ull(struct data * d){
  struct front_item * front;
  struct front_item * ret_front;
  struct front_item * it;
  struct front_item * tmp;
  struct front_item * jt;
  int i;

  front = new_front_item(0,0,NULL,NULL);
  ret_front = new_front_item(0,0,NULL,NULL);

  for(i=0;i<d->N;++i){
    front = nem_ull_step(front,d,i);
    
    it = ret_front;
    jt = front;
    while(it != NULL && jt != NULL) {
      if(it->i.p == jt->i.p && it->i.w == jt->i.w) {
        jt = jt->next;
        if(it->next == NULL) break;
        it = it->next;
      } else if(it->i.p < jt->i.p || (it->i.p == jt->i.p && it->i.w < jt->i.w)) {
        if(it->next == NULL) break;
        it = it->next;
      } else if(it->i.p > jt->i.p || (it->i.p == jt->i.p && it->i.w > jt->i.w)) {
        tmp = new_front_item(jt->i.p, jt->i.w, it->prev, it);
        tmp->time = jt->time;
        tmp->prev->next = tmp;
        tmp->next->prev = tmp;
        jt = jt->next;
      }
    }

    for(; jt != NULL; jt = jt->next) {
      it->next = new_front_item(jt->i.p, jt->i.w, it, NULL);
      it->next->time = jt->time;
      it = it->next;
    }
  }

  return ret_front;
}

struct front_item * nem_ull_online_shuffle(struct data * d, int rand_i){
  struct front_item * front;
  struct front_item * ret_front;
  struct front_item * it;
  struct front_item * tmp;
  struct front_item * jt;
  int i;

  ret_front = new_front_item(0,0,NULL,NULL);
  front = new_front_item(0,0,NULL,NULL);

  for(i=0;i<d->N;++i){
    if (i == rand_i) {
      shuffle_items(d, i);
    }
    front = nem_ull_step(front,d,i);

    it = ret_front;
    jt = front;
    while(it != NULL && jt != NULL) {
      if(it->i.p == jt->i.p && it->i.w == jt->i.w) {
        jt = jt->next;
        if(it->next == NULL) break;
        it = it->next;
      } else if(it->i.p < jt->i.p || (it->i.p == jt->i.p && it->i.w < jt->i.w)) {
        if(it->next == NULL) break;
        it = it->next;
      } else if(it->i.p > jt->i.p || (it->i.p == jt->i.p && it->i.w > jt->i.w)) {
        tmp = new_front_item(jt->i.p, jt->i.w, it->prev, it);
        tmp->time = jt->time;
        tmp->prev->next = tmp;
        tmp->next->prev = tmp;
        jt = jt->next;
      }
    }

    for(; jt != NULL; jt = jt->next) {
      it->next = new_front_item(jt->i.p, jt->i.w, it, NULL);
      it->next->time = jt->time;
      it = it->next;
    }
  }

  return ret_front;
}

struct front_item * nem_ull_step(struct front_item * b, struct data * d, int it){
  unsigned long int i,l0t,l1t,n;
  double pmax;
  struct item * l0;
  struct item * l1;
  clock_t * c0;
  struct front_item * p = b;

  for(n=0;p!=NULL;p=p->next,++n);
  p = b;

  l0 = (struct item *)malloc(n*sizeof(struct item));
  c0 = (clock_t *)malloc(n*sizeof(clock_t));
  l1 = (struct item *)malloc(n*sizeof(struct item));

  for(i=0;i<n;++i){
    l0[i].p=p->i.p;
    l0[i].w=p->i.w;
    c0[i] = p->time;

    l1[i].p=p->i.p + d->items[it].p;
    l1[i].w=p->i.w + d->items[it].w;

    b = p;
    p = p->next;
    free(b);
  }

  pmax = -1;
  l0t = 0;
  l1t = 0;
  p = new_front_item(0,0,NULL,NULL);

  while(1){
    for(;l0t<n;++l0t){
      if(l0[l0t].p > pmax){
        break;
      }
    }

    for(;l1t<n;++l1t){
      if(l1[l1t].p > pmax){
        break;
      }
    }

    if(l0t == n){
      for(;l1t<n;++l1t){
        p = new_front_item(l1[l1t].p, l1[l1t].w, p, NULL);
        p->prev->next = p;
      }
      break;
    }

    if(l1t == n){
      for(;l0t<n;++l0t){
        p = new_front_item(l0[l0t].p, l0[l0t].w, p, NULL);
        p->time = c0[l0t];
        p->prev->next = p;
      }
      break;
    }

    if((l0[l0t].w < l1[l1t].w) || ((l0[l0t].w == l1[l1t].w) && (l0[l0t].p > l1[l1t].p))){
      p = new_front_item(l0[l0t].p, l0[l0t].w , p, NULL);
      p->time = c0[l0t];
      p->prev->next = p;
      pmax = l0[l0t].p;
      ++l0t;
    } else {
      p = new_front_item(l1[l1t].p, l1[l1t].w , p, NULL);
      p->prev->next = p;
      pmax = l1[l1t].p;
      ++l1t;
    }
  }

  free(l0);
  free(c0);
  free(l1);

  for(;p->prev!=NULL;p=p->prev);
  p=p->next;
  free(p->prev);
  p->prev=NULL;
  return p;
}