std::vector<typename Graph::key_type> find_shortest_path(const Graph &graph, const typename Graph::key_type &start, const typename Graph::key_type &end, std::vector<typename Graph::key_type> path = std::vector<typename Graph::key_type>()) { path.push_back(start); if (start == end) { return path; } auto it = graph.find(start); if (std::end(graph) == it) { return std::vector<typename Graph::key_type>(); } std::vector<typename Graph::key_type> shortest; for (auto node : it->second) { if (std::find(std::begin(path), std::end(path), node) == std::end(path)) { auto new_path = find_shortest_path(graph, node, end, path); if (!new_path.empty()) { if (shortest.empty() || (new_path.size() < shortest.size())) { shortest = new_path; } } } } return shortest; }
int main (void) { maze_t<10, 10> A = {{ {{-1, 0, 0, 0, 0, 0,-1,-1, 0, 1}}, {{ 0, 0,-1, 0, 0, 0, 0, 0, 0, 0}}, {{-1, 0,-1, 0, 0,-1,-1, 0,-1,-1}}, {{ 0, 0, 0,-1,-1,-1, 0, 0,-1, 0}}, {{ 0,-1,-1, 0, 0, 0, 0, 0, 0, 0}}, {{ 0,-1,-1, 0, 0,-1, 0,-1,-1, 0}}, {{ 0, 0, 0, 0,-1, 0, 0, 0, 0, 0}}, {{-1, 0,-1, 0,-1, 0,-1, 0, 0, 0}}, {{-1, 0,-1,-1, 0, 0, 0,-1,-1,-1}}, {{ 0, 0, 0, 0, 0, 0, 0,-1,-1, 0}}, }}; //auto exit = find_exit(std::make_tuple(9,0), A); auto shortest_path = find_shortest_path(A, std::make_tuple(9,0)); //std::cout << exit << std::endl; std::cout << shortest_path << std::endl; return 0; }
int main(int argc, char **argv) { FILE *fp; Graph *graph; char *filename = "duom.txt"; fp = fopen(filename, "r"); if (fp == NULL) { fprintf(stderr,"Failed to open file filename\n"); return -1; } graph = initialise_graph(graph); read_file (graph, fp); make_adjacent_list(graph); find_shortest_path(graph, 0); print_path (graph, 0, graph->size - 1); return 0; }
//implemetation of functions int start_finding(int start_x, int start_y) { int inter = 0; int token = 0; int cur_x = start_x, cur_y = start_y; int dir = SOUTH; int ppath = -1; int npop = 0; //how many points should be poped struct POINT *cur_p = NULL; struct POINT *tmp_p = NULL; int ret = 0; #ifdef DEBUG inter = Robot_GetIntersections(); #else inter = get_intersection(); #endif cur_p = mark_point(cur_x, cur_y, inter); dir = get_direction(cur_p); #ifdef DEBUG printf("start point: "); print_point(cur_p); printf("\n"); #endif while(token < TOKEN_COUNT) { #ifdef DEBUG //inter = Robot_GetIntersections(); //print_intersection(inter); #endif if(points[cur_x][cur_y].detected == 0) cur_p = mark_point(cur_x, cur_y, inter); else cur_p = &points[cur_x][cur_y]; push(cur_p); //print_stack(); if(dir = get_direction(cur_p)) { //update current point switch(dir) { case EAST: cur_x += 1; break; case SOUTH: cur_y -= 1; break; case WEST: cur_x -= 1; break; case NORTH: cur_y += 1; break; } #ifdef DEBUG print_direction(cur_p, dir); ret = aud_move(cur_p, dir); #else //move one step display_clear(0); display_goto_xy(0, 0); display_int(cur_p->x, 2); display_goto_xy(3, 0); display_int(cur_p->y, 2); display_goto_xy(7, 0); display_int(cur_x, 2); display_goto_xy(10, 0); display_int(cur_y, 2); display_goto_xy(0, 1); display_int(g_dir, 3); display_goto_xy(5, 1); display_int(dir, 3); display_goto_xy(0, 2); display_int(cur_p->inter&0xF0, 3); display_update(); ret = move(cur_x, cur_y); #endif #ifdef DEBUG inter = Robot_GetIntersections(); #else inter = get_intersection(); #endif cur_p = mark_point(cur_x, cur_y, inter); #ifdef DEBUG print_point(cur_p); #endif if(ret == ROBOT_SUCCESS) { #ifndef DEBUG #endif } else if(ret == ROBOT_TOKENFOUND) { tmp_p = &points[cur_x][cur_y]; if(tmp_p->has_token == 0) { tmp_p->has_token = 1; token++; #ifdef DEBUG printf("[%d. token]\n", token); #endif } else { #ifdef DEBUG printf("[not a new token]\n"); #endif } if(token == TOKEN_COUNT) { //all token were found, go back to start point #ifdef DEBUG printf("going back to start point......\n"); #endif push(cur_p); ppath = find_shortest_path(cur_p->x, cur_p->y, START_X, START_Y); if(ppath) { //going back to last open point ppath--; while(ppath >= 0) { tmp_p = shortest_path[ppath]; dir = calc_direction(cur_p->x, cur_p->y, tmp_p->x, tmp_p->y); #ifdef DEBUG print_point(tmp_p); printf("\n"); ROBOT_MOVE(tmp_p->x, tmp_p->y); #else display_clear(0); display_goto_xy(0, 0); display_int(cur_p->x, 2); display_goto_xy(3, 0); display_int(cur_p->y, 2); display_goto_xy(7, 0); display_int(tmp_p->x, 2); display_goto_xy(10, 0); display_int(tmp_p->y, 2); display_goto_xy(0, 1); display_int(g_dir, 3); display_goto_xy(5, 1); display_int(dir, 3); display_goto_xy(0, 2); display_int(cur_p->inter&0xF0, 3); display_update(); move(tmp_p->x, tmp_p->y); #endif cur_p = tmp_p; ppath--; } //delete the path in stack pop(npop + 1); cur_p = tmp_p; cur_x = cur_p->x; cur_y = cur_p->y; } #ifdef DEBUG printf("task finished!\n"); #else beep(); #endif break; } } else { #ifdef DEBUG printf("move failed!\n"); #endif } } else { //there is no ways forward, go back to nearest open point tmp_p = get_last_open_point(); npop = stack_pointer - get_stack_index(tmp_p->x, tmp_p->y); #ifdef DEBUG printf("going back to (%d, %d)\n", tmp_p->x, tmp_p->y); #endif if(tmp_p) { if((tmp_p->x == START_X) && (tmp_p->y == START_Y) && !IS_OPEN_POINT(points[tmp_p->x][tmp_p->y])) { #ifdef DEBUG return 0; #else stop_robot(); beep(); return 0; #endif } ppath = find_shortest_path(cur_p->x, cur_p->y, tmp_p->x, tmp_p->y); if(ppath) { //going back to last open point ppath--; while(ppath >= 0) { tmp_p = shortest_path[ppath]; dir = calc_direction(cur_p->x, cur_p->y, tmp_p->x, tmp_p->y); #ifdef DEBUG ROBOT_MOVE(tmp_p->x, tmp_p->y); #else display_clear(0); display_goto_xy(0, 0); display_int(cur_p->x, 2); display_goto_xy(3, 0); display_int(cur_p->y, 2); display_goto_xy(7, 0); display_int(tmp_p->x, 2); display_goto_xy(10, 0); display_int(tmp_p->y, 2); display_goto_xy(0, 1); display_int(g_dir, 3); display_goto_xy(5, 1); display_int(dir, 3); display_goto_xy(0, 2); display_int(cur_p->inter&0xF0, 3); display_update(); move(tmp_p->x, tmp_p->y); #endif cur_p = tmp_p; ppath--; } //delete the path in stack pop(npop + 1); cur_p = tmp_p; cur_x = cur_p->x; cur_y = cur_p->y; } else { //was already at every point and back to start point //task should be ended //that means, not enough token can be found #ifdef DEBUG printf("task ended without enough token were found.\n"); #endif break; } } } #ifdef DEBUG printf("\n"); #endif } return 0; }
int main() { int **graph,n,m,problem,capacity,i,j,from,to,weight,source,destination,temp,send=0,take=0; vertex *station; scanf("%d%d%d%d",&capacity,&n,&problem,&m); station=(vertex *)malloc((n+1)*sizeof(vertex)); graph=(int **)malloc((n+1)*sizeof(int *)); for(i=1;i<=n;i++) { scanf("%d",&(station[i].condition)); } for(i=0;i<=n;i++) { graph[i]=(int *)malloc((n+1)*sizeof(int)); station[i].known=0; station[i].distance=-1; } for(i=0;i<=n;i++) { for(j=0;j<=n;j++) { graph[i][j]=-1; } } for(i=0;i<m;i++) { scanf("%d%d%d",&from,&to,&weight); graph[from][to]=weight; graph[to][from]=weight; } if(station[problem].condition<capacity/2) { source=problem;//实际起点为0 station[source].distance=0; find_shortest_path(graph,station,n,compare); source=0; destination=problem; } else { source=0;//实际起点为problem station[source].distance=0; find_shortest_path(graph,station,n,compare); source=problem; destination=0; } temp=source; if(source==0) { temp=station[temp].parent; while(temp!=destination) { if(station[temp].condition>capacity/2) { send-=station[temp].condition-capacity/2; } else { send+=capacity/2-station[problem].condition; } temp=station[temp].parent; } send+=capacity/2-station[problem].condition; if(send<0) { take-=send; take=0; } } else { temp=station[temp].parent; while(temp!=destination) { if(station[temp].condition<capacity/2) { take-=capacity/2-station[temp].condition; } else { take+=station[temp].condition-capacity/2; } temp=station[temp].parent; } take+=station[problem].condition-capacity/2; if(take<0) { send-=take; take=0; } } printf("%d ",send); temp=source; printf("%d",temp); while(temp!=destination) { temp=station[temp].parent; printf("->%d",temp); } printf(" %d\n",take); }
void CG::solve_lp(double epsilon){ bool no_delete = valid_solution(); if (no_delete) { // if there is no need to delete nodes cout << "CG::solve_lp() no need to delete nodes" << endl; return; } cout << "problem size: " << n_vertex_ << endl; double max_weight = 0; for (int ii = 0; ii < n_vertex_; ii++) { if (g_[ii].weight > max_weight) { max_weight = g_[ii].weight; } } // find the initial solution, which is the longest path in terms of the weights assigned for (int ii = 0; ii < n_vertex_; ii++) { g_[ii].dual_val = 1 + max_weight - g_[ii].weight; } double dummy1; vector<int> initial_path; find_shortest_path(dummy1, initial_path); for (vector<int>::iterator iter1 = initial_path.begin(); iter1 != initial_path.end(); ++iter1) { g_[*iter1].total_flow = 1; } double lambda = compute_lambda(); double alpha = (4 / (lambda * epsilon)) * log(2 * n_vertex_ / epsilon); double delta = epsilon / (4 * alpha); double crt_left = 0.0; double crt_lambda = lambda; int iteration = -1; while (true) { iteration++; compute_dual_vals(alpha); double middle = 0; // middle corresponds to \vec{z}^tA\vec{y} for (int ii = 0; ii < n_vertex_; ii++) { middle = middle + g_[ii].dual_val * g_[ii].total_flow; } double right = 0; // right corresponds to \lambda\vec{z}^t\vec{b} for (int ii = 0; ii < n_vertex_; ii++) { right = right + crt_lambda * g_[ii].dual_val * g_[ii].weight; } vector<int> opt_path; double left; // left corresponds to \vec{z}^tA\vec{y} find_shortest_path(left, opt_path); crt_left = left; if (iteration % 1000 == 0) { cout << "iteration " << iteration << " left:" << left << " middle:" << middle << " right:" << right << " sol:" << 1 / crt_lambda << endl; } // check if the following condition is met or not // \vec{z}^tA\vec{y} - C(\vec{z}) \le \epsilon(\vec{z}^tA\vec{y} + \lambda\vec{z}^t\vec{b}) if ((middle - left) < epsilon * (middle + right) ) { cout << "converged!" << endl; cout << "iteration " << iteration << " left:" << left << " middle:" << middle << " right:" << right << " sol:" << 1 / crt_lambda << endl; break; } else { update_solution(delta, opt_path); crt_lambda = compute_lambda(); if (crt_lambda < 0.5 * lambda) { lambda = crt_lambda; alpha = 4 / (lambda * epsilon) * log(2 * n_vertex_ / epsilon); delta = epsilon / (4 * alpha); } } } // compute the normalized dual solution for (int ii = 0; ii < n_vertex_; ii++) { g_[ii].nor_dual_val = g_[ii].dual_val / crt_left; if (g_[ii].nor_dual_val > 1) { g_[ii].nor_dual_val = 1; } } // as the last step, round the fractional solution to integral solutions round_lp(); }
//------------------------------------------------------------------------------ int compute(int start, int goal) { return find_shortest_path(start, goal); }
static void* pthread_main (void *arg) { int* arr = (int*)arg; int thrn = *(arr); arr++; int num_elem = *(arr);arr++; #ifdef DEBUG printf ("starting thread %d num elem %d\n", thrn, num_elem); #endif int i; _depth = num_nodes + 1; for (i = 0; i < num_elem; i++){ #ifdef DEBUG printf ("iterating thread %d elem #%d\n", thrn, arr[i]); #endif _update_path = num_nodes; bmap_init_static (num_nodes); _node_to_start = arr[i]; _stop_cnt = 0; _found_min = (_global_found_min == ULONG_MAX ? ULONG_MAX: _global_found_min + 1); #ifdef DEBUG _stat_cut_by_weight = _stat_cut_by_presence = _stat_evaluated = _stat_found_hash = 0; #endif GraphPath *path = path_new (); Bitmap *bitmap = bmap_new (); int res = find_shortest_path (bitmap, &path); #ifdef DEBUG printf ("MAX: %lu -> %lu (weight:%lu, presence:%lu, eval:%lu, hash:%lu)\n", _found_min, path->total_weight, _stat_cut_by_weight, _stat_cut_by_presence, _stat_evaluated, _stat_found_hash); bmap_print_hash (); #endif if (res){ /* begin critical section */ pthread_mutex_lock (&_mutex); if (path->total_weight < _global_found_min){ match_cnt = 0; if (best_found_path) path_free (best_found_path); best_found_path = path_clone (path); _global_found_min = path->total_weight; } if (path->total_weight == _global_found_min){ match_cnt++; } if (match_cnt >= MINIMUM_NUMBER_MATCHES_RESULTS){ print_solution (best_found_path); exit(0); } pthread_mutex_unlock (&_mutex); /* end critical section */ } path_free (path); bmap_free (bitmap); _depth += 2; } bmap_free_static (); return 0; }
static int find_shortest_path (Bitmap *bitmap, GraphPath **path_r) /* current optimal path */ { GraphPath *path = *path_r; GraphPath *found_path = NULL; int cur_path_size = path->num_edges; int j,i; size_t num_p; int status = 1; int two_pass_mode = (cur_path_size < num_nodes); GraphNode **idc = alloca ( (path->num_edges + 1)*sizeof (GraphNode*) ); path_transform_to_reverse_nodes_aray (path, &idc, &num_p); _loop_enter: for (j = 0 ; j < num_p ;j++) { GraphNode *curnode = idc[j]; for (i = 0; i < curnode->num_edges; i++) { GraphEdge *curedge = curnode->edges[i]; GraphNode *node_to = curedge->node_ptr; if (path->total_weight + curedge->weight >= _found_min){ #ifdef DEBUG _stat_cut_by_weight++; #endif continue; //don't go this way } if (two_pass_mode && status && bmap_get_in (bitmap, node_to->arr_idx)){ continue; } if (two_pass_mode && !status && !bmap_get_in (bitmap, node_to->arr_idx)){ continue; } if (bmap_get (bitmap, curnode->arr_idx, node_to->arr_idx)){ #ifdef DEBUG _stat_cut_by_presence++; #endif continue; //already passed by this edge } _stop_cnt++; if (_stop_cnt > MAXIMUM_SEARCH_ITERATION){ //up until third level if (cur_path_size < _update_path){ _update_path -= 2; // printf ("max path update: %d\n", _update_path); _stop_cnt = 0; } goto _loop_exit; } #ifdef DEBUG _stat_evaluated++; #endif void *bitmap_n = bmap_clone (bitmap); // printf ("before(%d,%d): ",i,j); // path_print_short (path); path_add (path, curedge); bmap_set (bitmap_n, curnode->arr_idx, node_to->arr_idx); // printf ("after(%d,%d) : ",i,j); // path_print_short (path); int path_found = bmap_check_full (bitmap_n) && path_check_valid (path); GraphPath *hpath = NULL; if (path_found == 0){ //try to check solution in hash table hpath = bmap_hash_path_search_optimal (bitmap_n); if (hpath == NULL){ if (path->num_edges <= _depth ) path_found = find_shortest_path (bitmap_n, &path); }else { #ifdef DEBUG _stat_found_hash++; #endif if (hpath != BMAP_HASH_PATH_EMPTY ){ hpath = path_clone (hpath); //rearrange path ensure_order_paths (path, hpath, cur_path_size); path_free (path); path = hpath; path_found = 1; }else{ path_found = 0; } } } if (path_found == 1 && (found_path == NULL || path->total_weight < found_path->total_weight)) { path_free (found_path); found_path = path_clone (path); if (hpath == NULL && found_path->num_edges - cur_path_size > 1) bmap_hash_path_add_optimal (bitmap_n, found_path); }else{ if (hpath == NULL && cur_path_size < num_nodes + 2) bmap_hash_path_add_optimal (bitmap_n, NULL); } path_shrink_to_size (path, cur_path_size); bmap_free (bitmap_n); } } if(two_pass_mode && status && cur_path_size < num_nodes){ status = 0; goto _loop_enter; } _loop_exit: if (found_path != NULL){ _update_path = found_path->num_edges; // printf ("FOUND: "); // path_print_short (found_path); path_free (path); if (found_path->total_weight < _found_min){ _stop_cnt = 0; #ifdef DEBUG printf (" update max: %lu -> %lu (weight:%lu, presence:%lu, eval:%lu, hash:%lu)\n", _found_min, found_path->total_weight, _stat_cut_by_weight, _stat_cut_by_presence, _stat_evaluated, _stat_found_hash); #endif _found_min = found_path->total_weight; } *path_r = found_path; return 1; } return 0; }
//------------------------------------------------------------------------------ int main(int argc, char *argv[]) { if(argc < 4){ printf("# Usage: ./a.out start goal filename [runmode]\n"); return -1; } FILE* fp = fopen(argv[3], "r"); if(fp == NULL){ printf("no such file\n"); return -1; } unsigned int start = atoi(argv[1]); unsigned int goal = atoi(argv[2]); int runmode = 0; if(argc > 4){ runmode = atoi(argv[4]); } printf("runmode: %d\n", runmode); if(fscanf(fp, "%d %d\n", &number_of_nodes, &number_of_edges) != 2){ exit(-1); } if(number_of_nodes > MAX_NODES || number_of_edges > (MAX_PAGES * PAGE_SIZE)){ printf("Graph size exceeds the maximum memory capacity."); return -1; } node_index = 0; page_index = 0; addr_table_entry_index = 0; if(runmode == 0){ node_array = (Node*) malloc(sizeof(Node) * number_of_nodes); if(node_array == NULL){ printf("can not allocate a memory for node_array.\n"); exit(-1); } page_array = (Page*) malloc(sizeof(Page) * number_of_edges); if(page_array == NULL){ printf("can not allocate a memory for page_array.\n"); exit(-1); } id_table = (Uint*) malloc(sizeof(Uint) * number_of_nodes); if(id_table == NULL){ printf("can not allocate a memory for id_table.\n"); exit(-1); } addr_table = (Nodechain**) malloc(sizeof(Nodechain*) * HASH_SIZE); if(addr_table == NULL){ printf("can not allocate a memory for addr_table.\n"); exit(-1); } addr_table_entry = (Nodechain*) malloc(sizeof(Nodechain) * number_of_nodes); if(addr_table_entry == NULL){ printf("can not allocate a memory for addr_table_entry.\n"); exit(-1); } pqueue_ptr = (Heapelement*) malloc(sizeof(Heapelement) * (number_of_nodes+1)); if(pqueue_ptr == NULL){ printf("can not allocate a memory for pqueue_ptr.\n"); exit(-1); } } else{ umem_open(); printf("# UMEM is opened.\n"); node_array = (Node*) umem_malloc(sizeof(Node) * number_of_nodes); if(node_array == NULL){ printf("can not allocate a memory for node_array.\n"); exit(-1); } page_array = (Page*) umem_malloc(sizeof(Page) * number_of_edges); if(page_array == NULL){ printf("can not allocate a memory for page_array.\n"); exit(-1); } id_table = (Uint*) umem_malloc(sizeof(Uint) * number_of_nodes); if(id_table == NULL){ printf("can not allocate a memory for id_table.\n"); exit(-1); } addr_table = (Nodechain**) umem_malloc(sizeof(Nodechain*) * HASH_SIZE); if(addr_table == NULL){ printf("can not allocate a memory for addr_table.\n"); exit(-1); } addr_table_entry = (Nodechain*) umem_malloc(sizeof(Nodechain) * number_of_nodes); if(addr_table_entry == NULL){ printf("can not allocate a memory for addr_table_entry.\n"); exit(-1); } pqueue_ptr = (Heapelement*) umem_malloc(sizeof(Heapelement) * (number_of_nodes+1)); if(pqueue_ptr == NULL){ printf("can not allocate a memory for pqueue_ptr.\n"); exit(-1); } } init_queue(&pqueue, pqueue_ptr); Uint i; for(i=0; i<number_of_nodes; i++){ id_table[i] = 0; } for(i=0; i<HASH_SIZE; i++){ addr_table[i] = NULL; } Uint from, to, cost; while(fscanf(fp, "%d %d %d\n", &from, &to, &cost) == 3){ add_edge(from, to, cost); //add_edge(to, from, cost); // undirected graph } /* while(fscanf(stdin, "%d %d %d\n", &from, &to, &cost) == 3){ add_edge(from, to, cost); //add_edge(to, from, cost); // undirected graph } */ printf("start:%d goal:%d\r\n", start, goal); printf("num_nodes:%d num_edges:%d\r\n", number_of_nodes, number_of_edges); struct timeval s, e; Uint sum_of_cost; Uint cycles; if(runmode == 0 || runmode == 1){ gettimeofday(&s, NULL); sum_of_cost = find_shortest_path(start, goal); gettimeofday(&e, NULL); cycles = 0; }else{ printf("# with PyCoRAM\n"); Node* start_addr = get_node(start); Node* goal_addr = get_node(goal); umem_cache_clean((char*)node_array, sizeof(Node) * number_of_nodes); umem_cache_clean((char*)page_array, sizeof(Node) * number_of_edges); pycoram_open(); unsigned int pqueue_ptr_offset = umem_get_physical_address((void*)pqueue_ptr); unsigned int start_addr_offset = umem_get_physical_address((void*)start_addr); unsigned int goal_addr_offset = umem_get_physical_address((void*)goal_addr); pycoram_write_4b(pqueue_ptr_offset); pycoram_write_4b(start_addr_offset); pycoram_write_4b(goal_addr_offset); gettimeofday(&s, NULL); pycoram_read_4b(&sum_of_cost); pycoram_read_4b(&cycles); gettimeofday(&e, NULL); pycoram_close(); //sleep(1); } double exec_time = (e.tv_sec - s.tv_sec) + (e.tv_usec - s.tv_usec) * 1.0E-6; if(sum_of_cost < MAX_INT){ walk_result(sum_of_cost, start, goal); } printf("exectuion time=%lf\n", exec_time); if(runmode == 0){ free(node_array); free(page_array); free(id_table); free(addr_table); free(addr_table_entry); }else{ umem_close(); } return 0; }