#include #include #include #if defined(TEST_TARGET_graph) #include #include #include #else #include "init.h" #include "command.h" #include "unitt.h" #include "kern.h" #include "graph.h" #endif /************************************************************************************/ /************************************* Unit Test ************************************/ /************************************************************************************/ // #define EXIT_TEST extern uint64_t unitt_clock(void); static int test_0(void) { for (int i = 0; i < 100; i++) { if (0) { #if defined (EXIT_TEST) exit(0); #endif return UNITT_E_FAIL; } } return UNITT_E_OK; } static void unitt_task(void) { static UNITT_TCASE rand_tests[] = { UNITT_TCASE(test_0), // UNITT_TCASE(test_1), // UNITT_TCASE(test_2), }; static UNITT suites[] = { { "xxx suite", rand_tests, sizeof(rand_tests) / sizeof(rand_tests[0]) , unitt_clock }, }; UNITT_EXE(suites); } /************************************************************************************/ /************************************* Base Test ************************************/ /************************************************************************************/ #define la(type, value) ((type[1]){value}) void graph_traverse_int(int index, void *data, int size) { printf("graph[%d] %d\r\n", index, *(int *)data); } static void test_create(void) { graph_t graph = NULL; int i = 25; int index = -1; graph = graph_create(100, 1); if (!graph) { printf("graph_create fail!\r\n"); } index = graph_add_vertex(graph, la(int, 12), sizeof(int)); printf("index %d\r\n", index); index = graph_add_vertex(graph, la(int, 13), sizeof(int)); printf("index %d\r\n", index); index = graph_add_vertex(graph, la(int, 15), sizeof(int)); printf("index %d\r\n", index); index = graph_add_vertex(graph, la(int, 23), sizeof(int)); printf("index %d\r\n", index); printf("graph_add_edge %d\r\n", graph_add_edge(graph, 0, 1, 0)); printf("graph_add_edge %d\r\n", graph_add_edge(graph, 0, 2, 0)); printf("graph_add_edge %d\r\n", graph_add_edge(graph, 2, 3, 0)); // graph_remove_edge(graph, 0, 2); // graph_remove_vertex(graph, 0); printf("ret %d\r\n", graph_vertex_set_data(graph, 1, la(int, 1024), sizeof(int))); printf("graph_vertex_data %d\r\n", *(int *)graph_vertex_data(graph, 1, NULL)); graph_dfs(graph, 0, graph_traverse_int); printf("----------------------\r\n"); graph_bfs(graph, 0, graph_traverse_int); graph_delete(graph); } static void test_add_vertex(void) { graph_t graph = NULL; graph = graph_create(10, 1); if (!graph) { printf("graph_create fail!\r\n"); } graph_add_vertex(graph, la(int, 12), sizeof(int)); graph_add_vertex(graph, la(int, 13), sizeof(int)); graph_add_vertex(graph, la(int, 15), sizeof(int)); graph_add_vertex(graph, la(int, 23), sizeof(int)); graph_ls(graph, graph_traverse_int); graph_delete(graph); } static void test_add_edge(void) { graph_t graph = NULL; graph = graph_create(10, 1); if (!graph) { printf("graph_create fail!\r\n"); } graph_add_vertex(graph, la(int, 12), sizeof(int)); graph_add_vertex(graph, la(int, 13), sizeof(int)); graph_add_vertex(graph, la(int, 15), sizeof(int)); graph_add_vertex(graph, la(int, 23), sizeof(int)); printf("---------------\r\n"); graph_dfs(graph, 0, graph_traverse_int); printf("---------------\r\n"); graph_add_edge(graph, 0, 1, 0); graph_add_edge(graph, 0, 2, 0); graph_add_edge(graph, 0, 3, 0); graph_add_edge(graph, 1, 0, 0); graph_add_edge(graph, 1, 2, 0); graph_add_edge(graph, 1, 3, 0); graph_add_edge(graph, 2, 3, 0); graph_dfs(graph, 0, graph_traverse_int); printf("---------------\r\n"); graph_delete(graph); } static void test_degree(void) { graph_t graph = NULL; graph = graph_create(10, 1); if (!graph) { printf("graph_create fail!\r\n"); } graph_add_vertex(graph, la(int, 100), sizeof(int)); graph_add_vertex(graph, la(int, 200), sizeof(int)); graph_add_vertex(graph, la(int, 300), sizeof(int)); graph_add_vertex(graph, la(int, 500), sizeof(int)); graph_add_edge(graph, 0, 1, 0); graph_add_edge(graph, 0, 2, 0); graph_add_edge(graph, 0, 3, 0); graph_add_edge(graph, 1, 0, 0); graph_add_edge(graph, 1, 2, 0); graph_add_edge(graph, 1, 3, 0); graph_add_edge(graph, 2, 3, 0); printf("graph_out_degree %d\r\n", graph_out_degree(graph, 3)); printf("graph_out_degree %d\r\n", graph_out_degree(graph, 2)); printf("graph_in_degree %d\r\n", graph_in_degree(graph, 0)); printf("graph_in_degree %d\r\n", graph_in_degree(graph, 2)); graph_delete(graph); } static void test_remove(void) { graph_t graph = NULL; graph = graph_create(100, 1); if (!graph) { printf("graph_create fail!\r\n"); } graph_add_vertex(graph, la(int, 100), sizeof(int)); graph_add_vertex(graph, la(int, 200), sizeof(int)); graph_add_vertex(graph, la(int, 300), sizeof(int)); graph_add_vertex(graph, la(int, 500), sizeof(int)); graph_add_edge(graph, 0, 1, 0); graph_add_edge(graph, 0, 2, 0); graph_add_edge(graph, 0, 3, 0); graph_add_edge(graph, 1, 0, 0); graph_add_edge(graph, 1, 2, 0); graph_add_edge(graph, 1, 3, 0); graph_add_edge(graph, 2, 3, 0); graph_remove_vertex(graph, 1); graph_remove_edge(graph, 0, 2); graph_dfs(graph, 0, graph_traverse_int); graph_delete(graph); } static void test_search(void) { graph_t graph = NULL; graph = graph_create(100, 1); if (!graph) { printf("graph_create fail!\r\n"); } graph_add_vertex(graph, la(int, 100), sizeof(int)); graph_add_vertex(graph, la(int, 200), sizeof(int)); graph_add_vertex(graph, la(int, 300), sizeof(int)); graph_add_vertex(graph, la(int, 500), sizeof(int)); graph_add_edge(graph, 0, 1, 0); graph_add_edge(graph, 0, 2, 0); graph_add_edge(graph, 0, 3, 0); graph_add_edge(graph, 1, 0, 0); graph_add_edge(graph, 1, 2, 0); graph_add_edge(graph, 1, 3, 0); graph_add_edge(graph, 2, 3, 0); graph_remove_vertex(graph, 1); graph_remove_edge(graph, 0, 2); printf("graph_ls ----------------------\r\n"); graph_ls(graph, graph_traverse_int); printf("graph_dfs ----------------------\r\n"); graph_dfs(graph, 0, graph_traverse_int); printf("graph_bfs ----------------------\r\n"); graph_bfs(graph, 0, graph_traverse_int); graph_delete(graph); } static void test_data(void) { graph_t graph = NULL; graph = graph_create(100, 1); if (!graph) { printf("graph_create fail!\r\n"); } graph_add_vertex(graph, la(int, 100), sizeof(int)); graph_add_vertex(graph, la(int, 200), sizeof(int)); graph_add_vertex(graph, la(int, 300), sizeof(int)); graph_add_vertex(graph, la(int, 500), sizeof(int)); graph_vertex_set_data(graph, 2, la(int, 1024), sizeof(int)); int size = 0; printf("graph_vertex_data[3].data = %d\r\n", *(int *)graph_vertex_data(graph, 3, &size)); printf("graph_vertex_data[3].size = %d\r\n", size); graph_ls(graph, graph_traverse_int); graph_delete(graph); } static void test_weight(void) { graph_t graph = NULL; graph = graph_create(100, 1); if (!graph) { printf("graph_create fail!\r\n"); } graph_add_vertex(graph, la(int, 100), sizeof(int)); graph_add_vertex(graph, la(int, 200), sizeof(int)); graph_add_vertex(graph, la(int, 300), sizeof(int)); graph_add_vertex(graph, la(int, 500), sizeof(int)); graph_add_edge(graph, 0, 1, 0); graph_add_edge(graph, 0, 2, 0); graph_add_edge(graph, 0, 3, 10); graph_add_edge(graph, 1, 0, 0); graph_add_edge(graph, 1, 2, 0); graph_add_edge(graph, 1, 3, 0); graph_add_edge(graph, 2, 3, 0); printf("graph_get_edge_weight = %d\r\n", graph_get_edge_weight(graph, 0, 3)); graph_set_edge_weight(graph, 0, 3, 1024); printf("graph_get_edge_weight = %d\r\n", graph_get_edge_weight(graph, 0, 3)); graph_delete(graph); } static void test_shortest_path(void) { graph_t graph = NULL; graph = graph_create(100, 1); if (!graph) { printf("graph_create fail!\r\n"); } graph_add_vertex(graph, la(int, 100), sizeof(int)); graph_add_vertex(graph, la(int, 200), sizeof(int)); graph_add_vertex(graph, la(int, 300), sizeof(int)); graph_add_vertex(graph, la(int, 500), sizeof(int)); graph_add_edge(graph, 0, 1, 3); graph_add_edge(graph, 0, 2, 2); graph_add_edge(graph, 0, 3, 5); graph_add_edge(graph, 1, 0, 6); graph_add_edge(graph, 1, 2, 3); graph_add_edge(graph, 1, 3, 2); graph_add_edge(graph, 2, 3, 1); graph_shortest_path(graph, 0); graph_delete(graph); } static void test_min_cover(void) { graph_t graph = NULL; graph = graph_create(100, 1); if (!graph) { printf("graph_create fail!\r\n"); } graph_add_vertex(graph, la(int, 100), sizeof(int)); graph_add_vertex(graph, la(int, 200), sizeof(int)); graph_add_vertex(graph, la(int, 300), sizeof(int)); graph_add_vertex(graph, la(int, 500), sizeof(int)); graph_add_edge(graph, 0, 1, 3); graph_add_edge(graph, 0, 2, 2); graph_add_edge(graph, 0, 3, 5); graph_add_edge(graph, 1, 0, 6); graph_add_edge(graph, 1, 2, 3); graph_add_edge(graph, 1, 3, 2); graph_add_edge(graph, 2, 3, 1); graph_min_vertex_cover(graph); graph_delete(graph); } static void test_others(void) { graph_t graph = NULL; graph = graph_create(100, 1); if (!graph) { printf("graph_create fail!\r\n"); } graph_add_vertex(graph, la(int, 100), sizeof(int)); graph_add_vertex(graph, la(int, 200), sizeof(int)); graph_add_vertex(graph, la(int, 300), sizeof(int)); graph_add_vertex(graph, la(int, 500), sizeof(int)); graph_add_edge(graph, 0, 1, 3); graph_add_edge(graph, 0, 2, 2); graph_add_edge(graph, 0, 3, 5); graph_add_edge(graph, 1, 0, 6); graph_add_edge(graph, 1, 2, 3); graph_add_edge(graph, 1, 3, 2); graph_add_edge(graph, 2, 3, 1); // graph_topological_sort(graph); // graph_shortest_path(graph, 0); // graph_minimum_spanning_tree(graph); // printf("graph_is_connected %d\r\n", graph_is_connected(graph)); // printf("graph_is_complete %d\r\n", graph_is_complete(graph)); // printf("graph_is_bipartite %d\r\n", graph_is_bipartite(graph)); // printf("graph_is_eulerian %d\r\n", graph_is_eulerian(graph)); // printf("graph_is_eulerian %d\r\n", graph_max_flow(graph, 0, 3)); // graph_articulation_points(graph); // graph_bridges(graph); graph_min_vertex_cover(graph); graph_dfs(graph, 0, graph_traverse_int); graph_delete(graph); } static void test_base(void) { // test_create(); // test_add_vertex(); // test_add_edge(); // test_remove(); // test_search(); // test_data(); // test_degree(); // test_weight(); // test_shortest_path(); test_min_cover(); } /************************************************************************************/ /************************************* Command ************************************/ /************************************************************************************/ static void usage(void) { printf( "Usage: graph [opt] [arg] ...\n" "\n" "options:\n" " -e Specifies the function to execute, the default is the test\n" " Test base function\n" " Unit test\n" " Test create and delete functions\n" " Test add_vertex function\n" " Test add_edge function\n" " Test remove function\n" " Test search function\n" " Test data function\n" " Test degree function\n" " Test weight function\n" " Test shortest_path function\n" " Test min_cover function\n" " -h Print help\n" " -v Print version\n" " -u [] Unit test period, unit ms, the default is 1000ms\n" "\n" ); } static int test(int argc, char *argv[]) { char *execute = NULL; int ut_period = 1000; /* reset getopt */ command_opt_init(); while (1) { int opt = command_getopt(argc, argv, "e:hvu::"); if (opt == -1) break; switch (opt) { case 'u' : if (command_optarg) ut_period = atoi(command_optarg); break; case 'e' : execute = command_optarg; break; case 'v' : printf("graph version %d.%d.%d\r\n", GRAPH_V_MAJOR, GRAPH_V_MINOR, GRAPH_V_PATCH); return 0; case '?': printf("Unknown option `%c`\r\n", command_optopt); return -1; case 'h' : default: usage(); return 0; } } if (execute) { if (!strcmp(execute, "base")) { test_base(); } else if (!strcmp(execute, "ut")) { srand((unsigned int)time(NULL)); #if defined(TEST_TARGET_graph) while (1) { unitt_task(); usleep(1000 * ut_period); } #else printf("create task %d\r\n", task_create(ut_period, unitt_task)); #endif } else if (!strcmp(execute, "create")) { test_create(); } else if (!strcmp(execute, "addv")) { test_add_vertex(); } else if (!strcmp(execute, "adde")) { test_add_edge(); } else if (!strcmp(execute, "remove")) { test_remove(); } else if (!strcmp(execute, "search")) { test_search(); } else if (!strcmp(execute, "data")) { test_data(); } else if (!strcmp(execute, "degree")) { test_degree(); } else if (!strcmp(execute, "weight")) { test_weight(); } else if (!strcmp(execute, "shortp")) { test_shortest_path(); } else if (!strcmp(execute, "minc")) { test_min_cover(); } } else { test_base(); } return 0; } /************************************************************************************/ /************************************ Test entry ************************************/ /************************************************************************************/ #if defined(TEST_TARGET_graph) int main(int argc, char *argv[]) { return test(argc, argv); } #else void test_graph(void) { command_export("graph", test); } init_export_app(test_graph); #endif