aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexandre Jesus <adbjesus@gmail.com>2016-09-23 09:34:49 +0100
committerAlexandre Jesus <adbjesus@gmail.com>2016-09-23 09:34:49 +0100
commit6c620091ec068c31e4ed5e7e480b5abdd2329b0f (patch)
tree74e1de882b838c0da5f08cf32aaa46a9993ed25f
parent7963cc3c89b8c03a073d17f58833ad191a3903a9 (diff)
downloadlibuknapsack-6c620091ec068c31e4ed5e7e480b5abdd2329b0f.tar.gz
libuknapsack-6c620091ec068c31e4ed5e7e480b5abdd2329b0f.zip
Add random heuristic method
-rw-r--r--CMakeLists.txt5
-rw-r--r--src/main/random_heuristic.c36
-rw-r--r--src/random_heuristic.c82
3 files changed, 121 insertions, 2 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index da3c722..5144b83 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -41,6 +41,7 @@ set(INCLUDE_FILES
${INCLUDE_DIR}/dfs.h
${INCLUDE_DIR}/structs.h
${INCLUDE_DIR}/common.h
+ ${INCLUDE_DIR}/random_heuristic.h
)
set(SRC_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src)
@@ -48,6 +49,7 @@ set(SRC_FILES
${SRC_DIR}/nem_ull.c
${SRC_DIR}/dfs.c
${SRC_DIR}/common.c
+ ${SRC_DIR}/random_heuristic.c
)
set(MAIN_SRC_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src/main)
@@ -58,11 +60,14 @@ add_library(uknapsack STATIC ${SRC_FILES})
add_executable(nem_ull ${MAIN_SRC_DIR}/nem_ull.c)
add_executable(dfs ${MAIN_SRC_DIR}/dfs.c)
+add_executable(random_heuristic ${MAIN_SRC_DIR}/random_heuristic.c)
target_link_libraries(nem_ull uknapsack)
target_link_libraries(dfs uknapsack)
+target_link_libraries(random_heuristic uknapsack)
install(TARGETS nem_ull DESTINATION bin)
install(TARGETS dfs DESTINATION bin)
+install(TARGETS random_heuristic DESTINATION bin)
install(TARGETS uknapsack DESTINATION lib)
install(FILES ${INCLUDE_FILES} DESTINATION include)
diff --git a/src/main/random_heuristic.c b/src/main/random_heuristic.c
new file mode 100644
index 0000000..9f3c683
--- /dev/null
+++ b/src/main/random_heuristic.c
@@ -0,0 +1,36 @@
+#include <stdio.h>
+#include <time.h>
+#include <stdlib.h>
+#include "common.h"
+#include "structs.h"
+#include "random_heuristic.h"
+
+int main(int argc, char * argv[]){
+ struct data * d;
+ struct front_item * b;
+
+ if(argc!=2){
+ printf("Wrong number of arguments!\n");
+ printf("Example usage: %s data_file\n",argv[0]);
+ return 0;
+ }
+
+ d = input(argv[1]);
+
+ /* srand() and qsort data */
+ srand(time(NULL));
+ qsort(d->items, d->N, sizeof(struct item), cmp_items_ratio);
+
+ clock_t t = clock();
+ b = random_heuristic(d);
+
+ t = clock() - t;
+ printf("%f,%d\n",((float)t)/CLOCKS_PER_SEC,len_front(b));
+
+ print_front(b);
+
+ free_front(b);
+ free_data(d);
+
+ return 0;
+}
diff --git a/src/random_heuristic.c b/src/random_heuristic.c
index 4e3e47f..bd3efa5 100644
--- a/src/random_heuristic.c
+++ b/src/random_heuristic.c
@@ -3,7 +3,85 @@
#include "structs.h"
#include "common.h"
-struct front_item * random_heuristic(struct data * d) {
-
+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;
+
+ do {
+ /* 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);
+
+ /* 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--;
+
+ 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);
+
+ /* 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;
return NULL;
}