Victor Ferman
/
frdm_rtos_knapsack
Soving knapsack problem
main.cpp
- Committer:
- vferman
- Date:
- 2022-03-28
- Revision:
- 1:39e36a5c11e0
- Parent:
- 0:1ea8993f6b18
File content as of revision 1:39e36a5c11e0:
#include "mbed.h" #include "rtos.h" #include <queue> //#define DELAY_INSIDE //#define DELAY_BTWN #define DELAY_DISPLAY #define DELAY_INSIDE_TIME 1000 #define DELAY_BTWN_TIME 311 #define DELAY_DISPLAY_TIME 100 #define ARRAY_SIZE 16 #define THREAD_ARRAY_SIZE 10 typedef struct{ int tid; int pid; int cap; int weights[ARRAY_SIZE]; int values[ARRAY_SIZE]; int ts_begin; int ts_end; int proc_time; int n; }problema; typedef struct{ int tid; int pid; int cap; int weights[ARRAY_SIZE]; int values[ARRAY_SIZE]; int ts_begin; int ts_end; int proc_time; int opt; }solucion; Timer t; DigitalOut led1(LED1); // Red DigitalOut led2(LED2); // Green DigitalOut led3(LED3); // Blue osMutexDef (mutex_leds);//mutex for LEDs osMutexDef (mutex_p); //problem queue mutex osMutexDef (mutex_s); //solution queue mutex osMutexId (mutex_leds_id); // LED mutex ID osMutexId (mutex_p_id); // problem queue mutex ID osMutexId (mutex_s_id); // solution queue mutex ID queue <problema> problem_q; queue <solucion> solution_q; Serial pc(USBTX, USBRX); #ifdef DEBUG int printP(problema p){ int i; printf("\n#P \t#T \tCap \t#items"); printf("\n%i \t%i \t%i \t%i\n",p.pid,p.tid,p.cap,p.n); printf(" Weights \tValues\n"); printf(" ------- \t------\n"); i=0; while (p.weights[i]>-5 && p.values[i]>-5 && i<30){ printf("%i. %i \t%i\n", i+1, p.weights[i],p.values[i]); i++; } printf("\n"); return 1; } int printS(solucion s){ int i; printf("\n#S \t#T \tCap \tOpt Val \tBegin \t\tEnd \t\tProc"); printf("\n%i \t%i \t%i \t%i \t\t%ius \t%ius \t%ius\n", s.pid, s.tid, s.cap, s.opt, s.ts_begin, s.ts_end, s.proc_time); printf(" Weights \tValues \t(included items)\n"); printf(" ------- \t------\n"); i=0; while (s.weights[i]>-5 && s.values[i]>-5 && i<30){ printf("%i. %i \t%i\n", i+1, s.weights[i],s.values[i]); i++; } printf("\n"); return 1; } #else #endif int printF(solucion s){ int i; printf("\n#"); printf("%i,", s.tid); printf("%i,", s.pid); printf("%i", s.cap); i=0; while (s.weights[i]>=0 && s.values[i]>=0 && i<30){ printf(",%i,%i", s.weights[i],s.values[i]); i++; } printf(",%i", s.ts_begin); printf(",%i", s.ts_end); printf(",%i", s.proc_time); printf("*"); return 1; } int my_atoi(char *str) { int res = 0; // Initialize result // Iterate through all characters of input string and update result for (int i = 0; str[i] != '\0'; ++i) res = res*10 + str[i] - '0'; return res; } // A utility function that returns maximum of two integers int max(int a, int b) { return (a > b)? a : b; } // Returns the maximum value that can be put in a knapsack of capacity W solucion knapSackP(problema p, int t){ solucion s; s.ts_begin=t;//t.read_us(); int i, w,index=0; int K[p.n+1][p.cap+1]; // Build table K[][] in bottom up manner for (i = 0; i <= p.n; i++){ for (w = 0; w <= p.cap; w++){ if (i==0 || w==0) K[i][w] = 0; else if (p.weights[i-1] <= w) K[i][w] = max(p.values[i-1] + K[i-1][w-p.weights[i-1]], K[i-1][w]); else K[i][w] = K[i-1][w]; } } s.opt = K[p.n][p.cap]; w = p.cap; for (i=p.n; i>0; i--){ if(K[i][w] != K[i-1][w]){ //printf("(p.weights=%i,val=%i)-> ",p.weights[i-1],val[i-1]); s.weights[index]=p.weights[i-1]; s.values[index++]=p.values[i-1]; w=w-p.weights[i-1]; } } s.weights[index]=-5; s.values[index]=-5; return s; } void led_func(uint32_t n){ uint32_t temp = ~((n%7)+1); led3 = temp&(uint32_t)1; led2 = (temp&(uint32_t)2)>>1; led1 = (temp&(uint32_t)4)>>2; } void led_thread(void const *argument) { uint32_t cont =0; while (true) { osMutexWait(mutex_leds_id, osWaitForever); //request lock led_func(cont); osMutexRelease(mutex_leds_id); //unlock Thread::wait((uint32_t)argument ); cont++; } } void worker_thread(void const *argument){ problema p; solucion s; while (true) { osMutexWait(mutex_p_id, 1000); if (!problem_q.empty()){ p = problem_q.front(); problem_q.pop(); osMutexRelease(mutex_p_id); #ifdef DEBUG p.tid = (uint32_t)argument; printf("-------------------------------------------------------"); printP(p); #endif //printf("\nT1:%i\n",t.read_us()); s = knapSackP(p,t.read_us()); s.ts_end=t.read_us(); //printf("\nT2:%i\n",t.read_us()); s.proc_time=s.ts_end-s.ts_begin; s.tid = (uint32_t)argument; s.pid = p.pid; s.cap = p.cap; #ifdef DEBUG printS(s); #endif osMutexWait(mutex_s_id, 1000); solution_q.push(s); osMutexRelease(mutex_s_id); osMutexWait(mutex_leds_id, 1000); //request lock led_func((uint32_t)argument); osMutexRelease(mutex_leds_id); //unlock }else{ osMutexRelease(mutex_p_id); } osThreadYield(); #ifdef DELAY_INSIDE Thread::wait(DELAY_INSIDE_TIME); #endif } } int main(){ t.start(); problema *problemas_array; //array to store the parsed problems Thread *threads_array[THREAD_ARRAY_SIZE]; //array to instance the threads char buffer[4]; //buffer to atoi convertion solucion s; // var to pop the solutions from solution queue char input_char; //received char form serial input char stage = 0; //State of the parsing loop char parseFlag =1; //flag to exit the input loop char displayFlag =1; //flag to exit the display solution loop int i; //used to indexing alog the differents arrays int number_threads; //number of threads recived int number_threads_temp; //used to verify if we have recived the number of threads char problema_counter; //problem counter char item_counter; // char buffer_counter; //used to indexing the buffer used to atoi convertion pc.baud (115200); //Baudrate while (true) { problemas_array =(problema *) malloc(10*sizeof(problema)) ; problema_counter=0; number_threads=0; item_counter=0; buffer_counter=0; buffer[0]='\0'; buffer[3]='\0'; i=0; parseFlag=1; displayFlag =1; stage = 0; while(parseFlag){ //input loop input_char = getchar(); //receive char from Serial //Parsing the message if (input_char=='&'){ //start of message buffer[0]='\0'; buffer_counter=0; problema_counter=0; item_counter=0; number_threads=0; stage = 1; //printf("Stage %i\n", stage); }else if (input_char=='#'){ //end of threads number buffer[0]='\0'; buffer_counter=0; stage = 2; //printf("Stage %i\n", stage); }else if (input_char >= '0' && input_char <= '9'){ //number received buffer[buffer_counter++]=input_char; buffer[buffer_counter]='\0'; }else if (input_char=='*'){ //end of line if (stage==1){ number_threads_temp = my_atoi(&buffer[0]); number_threads = (number_threads_temp>0 && number_threads_temp<=10)? number_threads_temp: 5; //printf("Number of threads = %i\n", number_threads); //printf("Problema = %i\n", problema_counter); buffer[0]='\0'; buffer_counter=0; }else if (stage==4){ problemas_array[problema_counter].values[item_counter++]=my_atoi(&buffer[0]); problema_counter++; item_counter=0; //printf("4Problema = %i\n", problema_counter); }else if (stage==5){ problemas_array[problema_counter].values[item_counter++]=my_atoi(&buffer[0]); problemas_array[problema_counter].values[item_counter]=-5; problemas_array[problema_counter].weights[item_counter]=-5; problemas_array[problema_counter].n=item_counter; problema_counter++; item_counter=0; //printf("Problema = %i\n", problema_counter); } }else if (input_char==','){ //delimiter do the message if (stage==2){ problemas_array[problema_counter].pid = my_atoi(&buffer[0]); stage=3; //printf("Stage %i\n", stage); }else if (stage==3){ problemas_array[problema_counter].cap = my_atoi(&buffer[0]); stage=4; //printf("Stage %i\n", stage); } else if (stage==4){ problemas_array[problema_counter].weights[item_counter]=my_atoi(&buffer[0]); stage=5; //printf("Stage %i\n", stage); }else if (stage==5){ problemas_array[problema_counter].values[item_counter++]=my_atoi(&buffer[0]); stage=4; //printf("Stage %i\n", stage); } buffer[0]='\0'; buffer_counter=0; }else if (input_char=='\n'){ //newline received buffer[0]='\0'; buffer_counter=0; }else if (input_char=='X'){ //end of message buffer[0]='\0'; buffer_counter=0; stage=0; //printf("\nNumber of threads = %i\n", number_threads); fflush(stdout); fflush(stdin); parseFlag =0; //exit form input loop } } //printf("\nNumber of threads = %i", number_threads); //printf("\nNumber of problems = %i", problema_counter); printf("\n Parse Finished \n"); osMutexWait(mutex_p_id, osWaitForever); //request lock for (i=0; i<problema_counter; i++){ problem_q.push(problemas_array[i]); } osMutexRelease(mutex_p_id); //unlock free(problemas_array); i=0; while (i<number_threads){ threads_array[i]= new Thread(worker_thread,(void *)(i)); #ifdef DELAY_BTWN Thread::wait(DELAY_BTWN_TIME); #endif i++; } #ifdef DELAY_DISPLAY Thread::wait(DELAY_DISPLAY_TIME); #endif while(displayFlag){ displayFlag=0; printf("\n&%i*",number_threads); while(!solution_q.empty()){ osMutexWait(mutex_s_id, osWaitForever); if (!solution_q.empty()){ s = solution_q.front(); solution_q.pop(); printF(s); } osMutexRelease(mutex_s_id); } } //i=0; //while (i<number_threads) threads_array[i]; free(threads_array); //osMutexWait(mutex_leds_id, osWaitForever); //request lock // led_func(6); //osMutexRelease(mutex_leds_id); //unlock } }