double gauss_ziggurat(double sigma) { unsigned long U, sign, i, j; double x, y; while (1) { U = mt_genrand_int32(); i = U & 0x0000007F; /* 7 bit to choose the step */ sign = U & 0x00000080; /* 1 bit for the sign */ j = U>>8; /* 24 bit for the x-value */ x = j*wtab[i]; if (j < ktab[i]) break; if (i<127) { double y0, y1; y0 = ytab[i]; y1 = ytab[i+1]; y = y1+(y0-y1)*mt_genrand_real2(); } else { x = PARAM_R - log(1.0-mt_genrand_real2())/PARAM_R; y = exp(-PARAM_R*(x-0.5*PARAM_R))*mt_genrand_real2(); } if (y < exp(-0.5*x*x)) break; } return sign ? sigma*x : -sigma*x; }
void lwmsg_session_generate_cookie( LWMsgSessionCookie* cookie ) { mt m; uint32_t seed[3]; uint32_t s; int i; LWMsgTime now; lwmsg_time_now(&now); /* Add in 32 bits of data from the address of the cookie */ seed[0] = (uint32_t) (size_t) cookie; /* Add in 32 bits of data from the current pid */ seed[1] = (uint32_t) getpid(); /* Add in 32 bits of data from the current time */ seed[2] = (uint32_t) now.microseconds; mt_init_by_array(&m, seed, sizeof(seed) / sizeof(*seed)); for (i = 0; i < sizeof(cookie->bytes); i += sizeof(s)) { s = mt_genrand_int32(&m); memcpy(cookie->bytes + i, &s, sizeof(s)); } }
// Sets up a premutation table, not setting any seed. Useful with mt_init_by_array void snoise_setup_perm_noseed(snoise_permtable* p) { int i, j, k; for (i = 0 ; i < 256 ; i++) p->perm[i] = i; while (--i) { k = p->perm[i]; p->perm[i] = p->perm[j = (unsigned char)(mt_genrand_int32() & 0xff)]; p->perm[j] = k; } }
bool routing(const ap_int<8> trgt_line_id, const ap_uint<16> penalty_T, const ap_uint<16> penalty_C, const ap_uint<16> penalty_V, Board *board, ap_int<8> *output){ Line* trgt_line = board->line(trgt_line_id); trgt_line->track_index = 0; // ボードの初期化 IntraBox_4 my_board_1[MAX_BOXES][MAX_BOXES]; // ソース側のボード //#pragma HLS ARRAY_PARTITION variable=my_board_1 complete dim=1 IntraBox_4 my_board_2[MAX_BOXES][MAX_BOXES]; // シンク側のボード //#pragma HLS ARRAY_PARTITION variable=my_board_2 complete dim=2 IntraBox_4 init = { COST_MAX,COST_MAX,COST_MAX,COST_MAX, {false,false,false,false}, {false,false,false,false}, {false,false,false,false}, {false,false,false,false}}; for (ap_int<7> y = 0; y < board->getSizeY(); y++) { #pragma HLS LOOP_TRIPCOUNT min=10 max=40 avg=20 for (ap_int<7> x = 0; x < board->getSizeX(); x++) { #pragma HLS LOOP_TRIPCOUNT min=10 max=40 avg=20 ////#pragma HLS PIPELINE my_board_1[y][x] = init; my_board_2[y][x] = init; } } ap_int<7> start_x, start_y; IntraBox_4* start; Search qu[MAX_SEARCH]; //#pragma HLS ARRAY_PARTITION variable=qu cyclic factor=20 dim=0 ap_int<16> qu_head, qu_tail; ap_int<5> start_z = trgt_line->getSourceZ(); ap_int<5> end_z = trgt_line->getSinkZ(); /* ******************************** * Phase 1: ソース層の探索 ******************************** */ qu_head = 0; qu_tail = 0; // スタート地点の設定 start_x = trgt_line->getSourceX(); start_y = trgt_line->getSourceY(); start = &(my_board_1[start_y][start_x]); start->ne = 0; start->nw = 0; start->se = 0; start->sw = 0; // 北方向を探索 if(isInserted_1(start_x,start_y-1,start_z, board)){ Search trgt = {start_x,start_y-1,SOUTH}; qu[qu_tail] = trgt; qu_tail++; } // 東方向を探索 if(isInserted_1(start_x+1,start_y,start_z, board)){ Search trgt = {start_x+1,start_y,WEST}; qu[qu_tail] = trgt; qu_tail++; } // 南方向を探索 if(isInserted_1(start_x,start_y+1,start_z, board)){ Search trgt = {start_x,start_y+1,NORTH}; qu[qu_tail] = trgt; qu_tail++; } // 西方向を探索 if(isInserted_1(start_x-1,start_y,start_z, board)){ Search trgt = {start_x-1,start_y,EAST}; qu[qu_tail] = trgt; qu_tail++; } while (qu_head != qu_tail) { #pragma HLS LOOP_TRIPCOUNT min=100 max=100 avg=100 //#pragma HLS PIPELINE // これONにするとメモリ使用率100%になる Search trgt = qu[qu_head]; qu_head++; Box* trgt_box = board->box(trgt.x,trgt.y,start_z); IntraBox_4* trgt_ibox = &(my_board_1[trgt.y][trgt.x]); bool update = false; // コストの更新があったか? // コスト計算 if(trgt.d == SOUTH){ // 南から来た IntraBox_4* find_ibox = &(my_board_1[trgt.y+1][trgt.x]); // タッチ数 ap_int<8> touch_count = countLine(trgt.x,trgt.y,start_z, board) - trgt_box->getSouthNum(); if(touch_count < 0){ *output = 10; return false; /*cout << "error! (error: 10)" << endl; exit(10);*/ } // コスト ap_int<16> cost_se = (find_ibox->ne) + ML + touch_count * penalty_T; ap_int<16> cost_ne = (find_ibox->ne) + ML + touch_count * penalty_T + trgt_box->getEastNum() * penalty_C; ap_int<16> cost_sw = (find_ibox->nw) + ML + touch_count * penalty_T; ap_int<16> cost_nw = (find_ibox->nw) + ML + touch_count * penalty_T + trgt_box->getWestNum() * penalty_C; // 南東マス if(cost_se < trgt_ibox->se){ update = true; trgt_ibox->se = cost_se; (trgt_ibox->d_se).n = false; (trgt_ibox->d_se).e = false; (trgt_ibox->d_se).s = true; (trgt_ibox->d_se).w = false; } else if(cost_se == trgt_ibox->se){ (trgt_ibox->d_se).s = true; } // 北東マス if(cost_ne < trgt_ibox->ne){ update = true; trgt_ibox->ne = cost_ne; (trgt_ibox->d_ne).n = false; (trgt_ibox->d_ne).e = false; (trgt_ibox->d_ne).s = true; (trgt_ibox->d_ne).w = false; } else if(cost_ne == trgt_ibox->ne){ (trgt_ibox->d_ne).s = true; } // 南西マス if(cost_sw < trgt_ibox->sw){ update = true; trgt_ibox->sw = cost_sw; (trgt_ibox->d_sw).n = false; (trgt_ibox->d_sw).e = false; (trgt_ibox->d_sw).s = true; (trgt_ibox->d_sw).w = false; } else if(cost_sw == trgt_ibox->sw){ (trgt_ibox->d_sw).s = true; } // 北西マス if(cost_nw < trgt_ibox->nw){ update = true; trgt_ibox->nw = cost_nw; (trgt_ibox->d_nw).n = false; (trgt_ibox->d_nw).e = false; (trgt_ibox->d_nw).s = true; (trgt_ibox->d_nw).w = false; } else if(cost_nw == trgt_ibox->nw){ (trgt_ibox->d_nw).s = true; } } if(trgt.d == WEST){ // 西から来た IntraBox_4* find_ibox = &(my_board_1[trgt.y][trgt.x-1]); // タッチ数 ap_int<8> touch_count = countLine(trgt.x,trgt.y,start_z, board) - trgt_box->getWestNum(); if(touch_count < 0){ *output = 11; return false; /*cout << "error! (error: 11)" << endl; exit(11);*/ } // コスト ap_int<16> cost_nw = (find_ibox->ne) + ML + touch_count * penalty_T; ap_int<16> cost_ne = (find_ibox->ne) + ML + touch_count * penalty_T + trgt_box->getNorthNum() * penalty_C; ap_int<16> cost_sw = (find_ibox->se) + ML + touch_count * penalty_T; ap_int<16> cost_se = (find_ibox->se) + ML + touch_count * penalty_T + trgt_box->getSouthNum() * penalty_C; // 北西マス if(cost_nw < trgt_ibox->nw){ update = true; trgt_ibox->nw = cost_nw; (trgt_ibox->d_nw).n = false; (trgt_ibox->d_nw).e = false; (trgt_ibox->d_nw).s = false; (trgt_ibox->d_nw).w = true; } else if(cost_nw == trgt_ibox->nw){ (trgt_ibox->d_nw).w = true; } // 北東マス if(cost_ne < trgt_ibox->ne){ update = true; trgt_ibox->ne = cost_ne; (trgt_ibox->d_ne).n = false; (trgt_ibox->d_ne).e = false; (trgt_ibox->d_ne).s = false; (trgt_ibox->d_ne).w = true; } else if(cost_ne == trgt_ibox->ne){ (trgt_ibox->d_ne).w = true; } // 南西マス if(cost_sw < trgt_ibox->sw){ update = true; trgt_ibox->sw = cost_sw; (trgt_ibox->d_sw).n = false; (trgt_ibox->d_sw).e = false; (trgt_ibox->d_sw).s = false; (trgt_ibox->d_sw).w = true; } else if(cost_sw == trgt_ibox->sw){ (trgt_ibox->d_sw).w = true; } // 南東マス if(cost_se < trgt_ibox->se){ update = true; trgt_ibox->se = cost_se; (trgt_ibox->d_se).n = false; (trgt_ibox->d_se).e = false; (trgt_ibox->d_se).s = false; (trgt_ibox->d_se).w = true; } else if(cost_se == trgt_ibox->se){ (trgt_ibox->d_se).w = true; } } if(trgt.d == NORTH){ // 北から来た IntraBox_4* find_ibox = &(my_board_1[trgt.y-1][trgt.x]); // タッチ数 ap_int<8> touch_count = countLine(trgt.x,trgt.y,start_z, board) - trgt_box->getNorthNum(); if(touch_count < 0){ *output = 12; return false; /*cout << "error! (error: 12)" << endl; exit(12);*/ } // コスト ap_int<16> cost_ne = (find_ibox->se) + ML + touch_count * penalty_T; ap_int<16> cost_se = (find_ibox->se) + ML + touch_count * penalty_T + trgt_box->getEastNum() * penalty_C; ap_int<16> cost_nw = (find_ibox->sw) + ML + touch_count * penalty_T; ap_int<16> cost_sw = (find_ibox->sw) + ML + touch_count * penalty_T + trgt_box->getWestNum() * penalty_C; // 北東マス if(cost_ne < trgt_ibox->ne){ update = true; trgt_ibox->ne = cost_ne; (trgt_ibox->d_ne).n = true; (trgt_ibox->d_ne).e = false; (trgt_ibox->d_ne).s = false; (trgt_ibox->d_ne).w = false; } else if(cost_ne == trgt_ibox->ne){ (trgt_ibox->d_ne).n = true; } // 南東マス if(cost_se < trgt_ibox->se){ update = true; trgt_ibox->se = cost_se; (trgt_ibox->d_se).n = true; (trgt_ibox->d_se).e = false; (trgt_ibox->d_se).s = false; (trgt_ibox->d_se).w = false; } else if(cost_se == trgt_ibox->se){ (trgt_ibox->d_se).n = true; } // 北西マス if(cost_nw < trgt_ibox->nw){ update = true; trgt_ibox->nw = cost_nw; (trgt_ibox->d_nw).n = true; (trgt_ibox->d_nw).e = false; (trgt_ibox->d_nw).s = false; (trgt_ibox->d_nw).w = false; } else if(cost_nw == trgt_ibox->nw){ (trgt_ibox->d_nw).n = true; } // 南西マス if(cost_sw < trgt_ibox->sw){ update = true; trgt_ibox->sw = cost_sw; (trgt_ibox->d_sw).n = true; (trgt_ibox->d_sw).e = false; (trgt_ibox->d_sw).s = false; (trgt_ibox->d_sw).w = false; } else if(cost_sw == trgt_ibox->sw){ (trgt_ibox->d_sw).n = true; } } if(trgt.d == EAST){ // 東から来た IntraBox_4* find_ibox = &(my_board_1[trgt.y][trgt.x+1]); // タッチ数 ap_int<8> touch_count = countLine(trgt.x,trgt.y,start_z, board) - trgt_box->getEastNum(); if(touch_count < 0){ *output = 13; return false; /*cout << "error! (error: 13)" << endl; exit(13);*/ } // コスト ap_int<16> cost_ne = (find_ibox->nw) + ML + touch_count * penalty_T; ap_int<16> cost_nw = (find_ibox->nw) + ML + touch_count * penalty_T + trgt_box->getNorthNum() * penalty_C; ap_int<16> cost_se = (find_ibox->sw) + ML + touch_count * penalty_T; ap_int<16> cost_sw = (find_ibox->sw) + ML + touch_count * penalty_T + trgt_box->getSouthNum() * penalty_C; // 北東マス if(cost_ne < trgt_ibox->ne){ update = true; trgt_ibox->ne = cost_ne; (trgt_ibox->d_ne).n = false; (trgt_ibox->d_ne).e = true; (trgt_ibox->d_ne).s = false; (trgt_ibox->d_ne).w = false; } else if(cost_ne == trgt_ibox->ne){ (trgt_ibox->d_ne).e = true; } // 北西マス if(cost_nw < trgt_ibox->nw){ update = true; trgt_ibox->nw = cost_nw; (trgt_ibox->d_nw).n = false; (trgt_ibox->d_nw).e = true; (trgt_ibox->d_nw).s = false; (trgt_ibox->d_nw).w = false; } else if(cost_nw == trgt_ibox->nw){ (trgt_ibox->d_nw).e = true; } // 南東マス if(cost_se < trgt_ibox->se){ update = true; trgt_ibox->se = cost_se; (trgt_ibox->d_se).n = false; (trgt_ibox->d_se).e = true; (trgt_ibox->d_se).s = false; (trgt_ibox->d_se).w = false; } else if(cost_se == trgt_ibox->se){ (trgt_ibox->d_se).e = true; } // 南西マス if(cost_sw < trgt_ibox->sw){ update = true; trgt_ibox->sw = cost_sw; (trgt_ibox->d_sw).n = false; (trgt_ibox->d_sw).e = true; (trgt_ibox->d_sw).s = false; (trgt_ibox->d_sw).w = false; } else if(cost_sw == trgt_ibox->sw){ (trgt_ibox->d_sw).e = true; } } if(!update) continue; if(trgt_box->isTypeNumber() || trgt_box->isTypeVia()) continue; // 北方向 if(trgt.d!=NORTH && isInserted_1(trgt.x,trgt.y-1,start_z, board)){ Search next = {trgt.x,trgt.y-1,SOUTH}; qu[qu_tail] = next; qu_tail++; } // 東方向 if(trgt.d!=EAST && isInserted_1(trgt.x+1,trgt.y,start_z, board)){ Search next = {trgt.x+1,trgt.y,WEST}; qu[qu_tail] = next; qu_tail++; } // 南方向 if(trgt.d!=SOUTH && isInserted_1(trgt.x,trgt.y+1,start_z, board)){ Search next = {trgt.x,trgt.y+1,NORTH}; qu[qu_tail] = next; qu_tail++; } // 西方向 if(trgt.d!=WEST && isInserted_1(trgt.x-1,trgt.y,start_z, board)){ Search next = {trgt.x-1,trgt.y,EAST}; qu[qu_tail] = next; qu_tail++; } } /* ******************************** * Phase 2-1: シンク層の判定 ******************************** */ if(start_z != end_z){ qu_head = 0; qu_tail = 0; ap_int<8> sp_via_id = trgt_line->getSpecifiedVia(); if(sp_via_id >= 1 && sp_via_id <= board->getViaNum()){ Via* sp_via = board->via(sp_via_id); if(sp_via->getSourceZ()!=start_z || sp_via->getSinkZ()!=end_z){ *output = 20; return false; /*cout << "error! (error: 20)" << endl; exit(20);*/ } ap_int<7> sp_x = sp_via->getSourceX(); ap_int<7> sp_y = sp_via->getSourceY(); if(my_board_1[sp_y][sp_x].ne == COST_MAX || my_board_1[sp_y][sp_x].nw == COST_MAX || my_board_1[sp_y][sp_x].se == COST_MAX || my_board_1[sp_y][sp_x].sw == COST_MAX){ *output = 21; return false; /*cout << "error! (error: 21)" << endl; exit(21);*/ } } for(ap_int<8> i=1;i<=board->getViaNum();i++){ #pragma HLS LOOP_TRIPCOUNT min=5 max=45 avg=25 ////#pragma HLS PIPELINE Via* trgt_via = board->via(i); if(trgt_via->getSourceZ()!=start_z || trgt_via->getSinkZ()!=end_z) continue; if(sp_via_id > 0 && sp_via_id != i) continue; start_x = trgt_via->getSourceX(); start_y = trgt_via->getSourceY(); start = &(my_board_2[start_y][start_x]); // ソース層に COST_MAX のコスト値が含まれている場合は引き継がない (issue #82) if(my_board_1[start_y][start_x].ne == COST_MAX || my_board_1[start_y][start_x].nw == COST_MAX || my_board_1[start_y][start_x].se == COST_MAX || my_board_1[start_y][start_x].sw == COST_MAX) continue; start->ne = my_board_1[start_y][start_x].ne + trgt_via->getUsedLineNum() * penalty_V; start->nw = my_board_1[start_y][start_x].nw + trgt_via->getUsedLineNum() * penalty_V; start->se = my_board_1[start_y][start_x].se + trgt_via->getUsedLineNum() * penalty_V; start->sw = my_board_1[start_y][start_x].sw + trgt_via->getUsedLineNum() * penalty_V; // 北方向を探索 if(isInserted_2(start_x,start_y-1,end_z, board)){ Search trgt = {start_x,start_y-1,SOUTH}; qu[qu_tail] = trgt; qu_tail++; } // 東方向を探索 if(isInserted_2(start_x+1,start_y,end_z, board)){ Search trgt = {start_x+1,start_y,WEST}; qu[qu_tail] = trgt; qu_tail++; } // 南方向を探索 if(isInserted_2(start_x,start_y+1,end_z, board)){ Search trgt = {start_x,start_y+1,NORTH}; qu[qu_tail] = trgt; qu_tail++; } // 西方向を探索 if(isInserted_2(start_x-1,start_y,end_z, board)){ Search trgt = {start_x-1,start_y,EAST}; qu[qu_tail] = trgt; qu_tail++; } } } /* ******************************** * Phase 2-2: シンク層の探索 ******************************** */ while (qu_head != qu_tail) { #pragma HLS LOOP_TRIPCOUNT min=100 max=100 avg=100 //#pragma HLS PIPELINE // これONにするとメモリ使用率100%になる Search trgt = qu[qu_head]; qu_head++; Box* trgt_box = board->box(trgt.x,trgt.y,end_z); IntraBox_4* trgt_ibox = &(my_board_2[trgt.y][trgt.x]); bool update = false; // コストの更新があったか? // コスト計算 if(trgt.d == SOUTH){ // 南から来た IntraBox_4* find_ibox = &(my_board_2[trgt.y+1][trgt.x]); // タッチ数 ap_int<8> touch_count = countLine(trgt.x,trgt.y,end_z, board) - trgt_box->getSouthNum(); if(touch_count < 0){ *output = 10; return false; /*cout << "error! (error: 10)" << endl; exit(10);*/ } // コスト ap_int<16> cost_se = (find_ibox->ne) + ML + touch_count * penalty_T; ap_int<16> cost_ne = (find_ibox->ne) + ML + touch_count * penalty_T + trgt_box->getEastNum() * penalty_C; ap_int<16> cost_sw = (find_ibox->nw) + ML + touch_count * penalty_T; ap_int<16> cost_nw = (find_ibox->nw) + ML + touch_count * penalty_T + trgt_box->getWestNum() * penalty_C; // 南東マス if(cost_se < trgt_ibox->se){ update = true; trgt_ibox->se = cost_se; (trgt_ibox->d_se).n = false; (trgt_ibox->d_se).e = false; (trgt_ibox->d_se).s = true; (trgt_ibox->d_se).w = false; } else if(cost_se == trgt_ibox->se){ (trgt_ibox->d_se).s = true; } // 北東マス if(cost_ne < trgt_ibox->ne){ update = true; trgt_ibox->ne = cost_ne; (trgt_ibox->d_ne).n = false; (trgt_ibox->d_ne).e = false; (trgt_ibox->d_ne).s = true; (trgt_ibox->d_ne).w = false; } else if(cost_ne == trgt_ibox->ne){ (trgt_ibox->d_ne).s = true; } // 南西マス if(cost_sw < trgt_ibox->sw){ update = true; trgt_ibox->sw = cost_sw; (trgt_ibox->d_sw).n = false; (trgt_ibox->d_sw).e = false; (trgt_ibox->d_sw).s = true; (trgt_ibox->d_sw).w = false; } else if(cost_sw == trgt_ibox->sw){ (trgt_ibox->d_sw).s = true; } // 北西マス if(cost_nw < trgt_ibox->nw){ update = true; trgt_ibox->nw = cost_nw; (trgt_ibox->d_nw).n = false; (trgt_ibox->d_nw).e = false; (trgt_ibox->d_nw).s = true; (trgt_ibox->d_nw).w = false; } else if(cost_nw == trgt_ibox->nw){ (trgt_ibox->d_nw).s = true; } } if(trgt.d == WEST){ // 西から来た IntraBox_4* find_ibox = &(my_board_2[trgt.y][trgt.x-1]); // タッチ数 ap_int<8> touch_count = countLine(trgt.x,trgt.y,end_z, board) - trgt_box->getWestNum(); if(touch_count < 0){ *output = 11; return false; /*cout << "error! (error: 11)" << endl; exit(11);*/ } // コスト ap_int<16> cost_nw = (find_ibox->ne) + ML + touch_count * penalty_T; ap_int<16> cost_ne = (find_ibox->ne) + ML + touch_count * penalty_T + trgt_box->getNorthNum() * penalty_C; ap_int<16> cost_sw = (find_ibox->se) + ML + touch_count * penalty_T; ap_int<16> cost_se = (find_ibox->se) + ML + touch_count * penalty_T + trgt_box->getSouthNum() * penalty_C; // 北西マス if(cost_nw < trgt_ibox->nw){ update = true; trgt_ibox->nw = cost_nw; (trgt_ibox->d_nw).n = false; (trgt_ibox->d_nw).e = false; (trgt_ibox->d_nw).s = false; (trgt_ibox->d_nw).w = true; } else if(cost_nw == trgt_ibox->nw){ (trgt_ibox->d_nw).w = true; } // 北東マス if(cost_ne < trgt_ibox->ne){ update = true; trgt_ibox->ne = cost_ne; (trgt_ibox->d_ne).n = false; (trgt_ibox->d_ne).e = false; (trgt_ibox->d_ne).s = false; (trgt_ibox->d_ne).w = true; } else if(cost_ne == trgt_ibox->ne){ (trgt_ibox->d_ne).w = true; } // 南西マス if(cost_sw < trgt_ibox->sw){ update = true; trgt_ibox->sw = cost_sw; (trgt_ibox->d_sw).n = false; (trgt_ibox->d_sw).e = false; (trgt_ibox->d_sw).s = false; (trgt_ibox->d_sw).w = true; } else if(cost_sw == trgt_ibox->sw){ (trgt_ibox->d_sw).w = true; } // 南東マス if(cost_se < trgt_ibox->se){ update = true; trgt_ibox->se = cost_se; (trgt_ibox->d_se).n = false; (trgt_ibox->d_se).e = false; (trgt_ibox->d_se).s = false; (trgt_ibox->d_se).w = true; } else if(cost_se == trgt_ibox->se){ (trgt_ibox->d_se).w = true; } } if(trgt.d == NORTH){ // 北から来た IntraBox_4* find_ibox = &(my_board_2[trgt.y-1][trgt.x]); // タッチ数 ap_int<8> touch_count = countLine(trgt.x,trgt.y,end_z, board) - trgt_box->getNorthNum(); if(touch_count < 0){ *output = 12; return false; /*cout << "error! (error: 12)" << endl; exit(12);*/ } // コスト ap_int<16> cost_ne = (find_ibox->se) + ML + touch_count * penalty_T; ap_int<16> cost_se = (find_ibox->se) + ML + touch_count * penalty_T + trgt_box->getEastNum() * penalty_C; ap_int<16> cost_nw = (find_ibox->sw) + ML + touch_count * penalty_T; ap_int<16> cost_sw = (find_ibox->sw) + ML + touch_count * penalty_T + trgt_box->getWestNum() * penalty_C; // 北東マス if(cost_ne < trgt_ibox->ne){ update = true; trgt_ibox->ne = cost_ne; (trgt_ibox->d_ne).n = true; (trgt_ibox->d_ne).e = false; (trgt_ibox->d_ne).s = false; (trgt_ibox->d_ne).w = false; } else if(cost_ne == trgt_ibox->ne){ (trgt_ibox->d_ne).n = true; } // 南東マス if(cost_se < trgt_ibox->se){ update = true; trgt_ibox->se = cost_se; (trgt_ibox->d_se).n = true; (trgt_ibox->d_se).e = false; (trgt_ibox->d_se).s = false; (trgt_ibox->d_se).w = false; } else if(cost_se == trgt_ibox->se){ (trgt_ibox->d_se).n = true; } // 北西マス if(cost_nw < trgt_ibox->nw){ update = true; trgt_ibox->nw = cost_nw; (trgt_ibox->d_nw).n = true; (trgt_ibox->d_nw).e = false; (trgt_ibox->d_nw).s = false; (trgt_ibox->d_nw).w = false; } else if(cost_nw == trgt_ibox->nw){ (trgt_ibox->d_nw).n = true; } // 南西マス if(cost_sw < trgt_ibox->sw){ update = true; trgt_ibox->sw = cost_sw; (trgt_ibox->d_sw).n = true; (trgt_ibox->d_sw).e = false; (trgt_ibox->d_sw).s = false; (trgt_ibox->d_sw).w = false; } else if(cost_sw == trgt_ibox->sw){ (trgt_ibox->d_sw).n = true; } } if(trgt.d == EAST){ // 東から来た IntraBox_4* find_ibox = &(my_board_2[trgt.y][trgt.x+1]); // タッチ数 ap_int<8> touch_count = countLine(trgt.x,trgt.y,end_z, board) - trgt_box->getEastNum(); if(touch_count < 0){ *output = 13; return false; /*cout << "error! (error: 13)" << endl; exit(13);*/ } // コスト ap_int<16> cost_ne = (find_ibox->nw) + ML + touch_count * penalty_T; ap_int<16> cost_nw = (find_ibox->nw) + ML + touch_count * penalty_T + trgt_box->getNorthNum() * penalty_C; ap_int<16> cost_se = (find_ibox->sw) + ML + touch_count * penalty_T; ap_int<16> cost_sw = (find_ibox->sw) + ML + touch_count * penalty_T + trgt_box->getSouthNum() * penalty_C; // 北東マス if(cost_ne < trgt_ibox->ne){ update = true; trgt_ibox->ne = cost_ne; (trgt_ibox->d_ne).n = false; (trgt_ibox->d_ne).e = true; (trgt_ibox->d_ne).s = false; (trgt_ibox->d_ne).w = false; } else if(cost_ne == trgt_ibox->ne){ (trgt_ibox->d_ne).e = true; } // 北西マス if(cost_nw < trgt_ibox->nw){ update = true; trgt_ibox->nw = cost_nw; (trgt_ibox->d_nw).n = false; (trgt_ibox->d_nw).e = true; (trgt_ibox->d_nw).s = false; (trgt_ibox->d_nw).w = false; } else if(cost_nw == trgt_ibox->nw){ (trgt_ibox->d_nw).e = true; } // 南東マス if(cost_se < trgt_ibox->se){ update = true; trgt_ibox->se = cost_se; (trgt_ibox->d_se).n = false; (trgt_ibox->d_se).e = true; (trgt_ibox->d_se).s = false; (trgt_ibox->d_se).w = false; } else if(cost_se == trgt_ibox->se){ (trgt_ibox->d_se).e = true; } // 南西マス if(cost_sw < trgt_ibox->sw){ update = true; trgt_ibox->sw = cost_sw; (trgt_ibox->d_sw).n = false; (trgt_ibox->d_sw).e = true; (trgt_ibox->d_sw).s = false; (trgt_ibox->d_sw).w = false; } else if(cost_sw == trgt_ibox->sw){ (trgt_ibox->d_sw).e = true; } } if(!update) continue; if(trgt_box->isTypeNumber()) continue; // 北方向 if(trgt.d!=NORTH && isInserted_2(trgt.x,trgt.y-1,end_z, board)){ Search next = {trgt.x,trgt.y-1,SOUTH}; qu[qu_tail] = next; qu_tail++; } // 東方向 if(trgt.d!=EAST && isInserted_2(trgt.x+1,trgt.y,end_z, board)){ Search next = {trgt.x+1,trgt.y,WEST}; qu[qu_tail] = next; qu_tail++; } // 南方向 if(trgt.d!=SOUTH && isInserted_2(trgt.x,trgt.y+1,end_z, board)){ Search next = {trgt.x,trgt.y+1,NORTH}; qu[qu_tail] = next; qu_tail++; } // 西方向 if(trgt.d!=WEST && isInserted_2(trgt.x-1,trgt.y,end_z, board)){ Search next = {trgt.x-1,trgt.y,EAST}; qu[qu_tail] = next; qu_tail++; } } #if 0 if (debug_option) { /*** デバッグ用*/ cout << endl; cout << "LAYER So (line_id: " << trgt_line_id << ") (z: " << (start_z + 1) << ")" << endl; cout << "========" << endl; for(int y=0;y<board->getSizeY();y++){ for(int x=0;x<board->getSizeX();x++){ IntraBox_4* trgt_box = &(my_board_1[y][x]); if(trgt_box->nw > 10000){ cout << " +"; } else{ cout << setw(2) << trgt_box->nw; } if(trgt_box->ne > 10000){ cout << " +"; } else{ cout << setw(2) << trgt_box->ne; } cout << " "; } cout << endl; for(int x=0;x<board->getSizeX();x++){ IntraBox_4* trgt_box = &(my_board_1[y][x]); if(trgt_box->sw > 10000){ cout << " +"; } else{ cout << setw(2) << trgt_box->sw; } if(trgt_box->se > 10000){ cout << " +"; } else{ cout << setw(2) << trgt_box->se; } cout << " "; } cout << endl; } cout << "LAYER Si (line_id: " << trgt_line_id << ") (z: " << (end_z + 1) << ")" << endl; cout << "========" << endl; for(int y=0;y<board->getSizeY();y++){ for(int x=0;x<board->getSizeX();x++){ IntraBox_4* trgt_box = &(my_board_2[y][x]); if(trgt_box->nw > 10000){ cout << " +"; } else{ cout << setw(2) << trgt_box->nw; } if(trgt_box->ne > 10000){ cout << " +"; } else{ cout << setw(2) << trgt_box->ne; } cout << " "; } cout << endl; for(int x=0;x<board->getSizeX();x++){ IntraBox_4* trgt_box = &(my_board_2[y][x]); if(trgt_box->sw > 10000){ cout << " +"; } else{ cout << setw(2) << trgt_box->sw; } if(trgt_box->se > 10000){ cout << " +"; } else{ cout << setw(2) << trgt_box->se; } cout << " "; } cout << endl; } } #endif ap_int<7> now_x = trgt_line->getSinkX(); ap_int<7> now_y = trgt_line->getSinkY(); ap_uint<2> intra_box; ap_uint<2> next_direction_array[4]; #pragma HLS ARRAY_PARTITION variable=next_direction_array complete dim=0 ap_uint<3> next_direction_array_index = 0; ap_int<8> next_count; ap_uint<2> next_id; /* ******************************** * Phase 3-1: シンク層のバックトレース ******************************** */ if(start_z != end_z){ intra_box = NE; for (ap_uint<8> loop_count = 0; loop_count <= MAX_TRACKS; loop_count++) { //#pragma HLS PIPELINE // ONにするとLUTリソースオーバーする Point p = {now_x, now_y, end_z}; trgt_line->track[trgt_line->track_index] = p; (trgt_line->track_index)++; #if 0 if( debug_option ) { cout << "(" << now_x << "," << now_y << "," << end_z << ")"; } #endif if(board->box(now_x,now_y,end_z)->isTypeVia()) break; Direction trgt_d; switch(intra_box){ case NE: trgt_d = my_board_2[now_y][now_x].d_ne; break; case NW: trgt_d = my_board_2[now_y][now_x].d_nw; break; case SE: trgt_d = my_board_2[now_y][now_x].d_se; break; case SW: trgt_d = my_board_2[now_y][now_x].d_sw; break; default: ;//assert(!"Undefined Intra-Box"); break; } next_direction_array_index = 0; if(trgt_d.n) { next_direction_array[next_direction_array_index] = NORTH; next_direction_array_index++; } if(trgt_d.e) { next_direction_array[next_direction_array_index] = EAST; next_direction_array_index++; } if(trgt_d.s) { next_direction_array[next_direction_array_index] = SOUTH; next_direction_array_index++; } if(trgt_d.w) { next_direction_array[next_direction_array_index] = WEST; next_direction_array_index++; } next_count = /*(int)*/mt_genrand_int32(0, next_direction_array_index - 1); next_id = next_direction_array[next_count]; switch(next_id){ case NORTH: now_y = now_y - 1; // 北へ if(intra_box == NE || intra_box == SE) intra_box = SE; if(intra_box == NW || intra_box == SW) intra_box = SW; break; case EAST: now_x = now_x + 1; // 東へ if(intra_box == NE || intra_box == NW) intra_box = NW; if(intra_box == SE || intra_box == SW) intra_box = SW; break; case SOUTH: now_y = now_y + 1; // 南へ if(intra_box == NE || intra_box == SE) intra_box = NE; if(intra_box == NW || intra_box == SW) intra_box = NW; break; case WEST: now_x = now_x - 1; // 西へ if(intra_box == NE || intra_box == NW) intra_box = NE; if(intra_box == SE || intra_box == SW) intra_box = SE; break; } } } /* ******************************** * Phase 3-2: ソース層のバックトレース ******************************** */ intra_box = NE; for (ap_uint<8> loop_count = 0; loop_count <= MAX_TRACKS; loop_count++) { //#pragma HLS PIPELINE // ONにするとLUTリソースオーバーする Point p = {now_x, now_y, start_z}; trgt_line->track[trgt_line->track_index] = p; (trgt_line->track_index)++; #if 0 if( debug_option ){ cout << "(" << now_x << "," << now_y << "," << start_z << ")"; } #endif if(now_x==trgt_line->getSourceX() && now_y==trgt_line->getSourceY()) break; Direction trgt_d; switch(intra_box){ case NE: trgt_d = my_board_1[now_y][now_x].d_ne; break; case NW: trgt_d = my_board_1[now_y][now_x].d_nw; break; case SE: trgt_d = my_board_1[now_y][now_x].d_se; break; case SW: trgt_d = my_board_1[now_y][now_x].d_sw; break; default: ;//assert(!"Undefined Intra-Box"); break; } next_direction_array_index = 0; if(trgt_d.n) { next_direction_array[next_direction_array_index] = NORTH; next_direction_array_index++; } if(trgt_d.e) { next_direction_array[next_direction_array_index] = EAST; next_direction_array_index++; } if(trgt_d.s) { next_direction_array[next_direction_array_index] = SOUTH; next_direction_array_index++; } if(trgt_d.w) { next_direction_array[next_direction_array_index] = WEST; next_direction_array_index++; } next_count = /*(int)*/mt_genrand_int32(0, next_direction_array_index - 1); next_id = next_direction_array[next_count]; switch(next_id){ case NORTH: now_y = now_y - 1; // 北へ if(intra_box == NE || intra_box == SE) intra_box = SE; if(intra_box == NW || intra_box == SW) intra_box = SW; break; case EAST: now_x = now_x + 1; // 東へ if(intra_box == NE || intra_box == NW) intra_box = NW; if(intra_box == SE || intra_box == SW) intra_box = SW; break; case SOUTH: now_y = now_y + 1; // 南へ if(intra_box == NE || intra_box == SE) intra_box = NE; if(intra_box == NW || intra_box == SW) intra_box = NW; break; case WEST: now_x = now_x - 1; // 西へ if(intra_box == NE || intra_box == NW) intra_box = NE; if(intra_box == SE || intra_box == SW) intra_box = SE; break; } } #if 0 if( debug_option ) { cout << endl; } #endif /* ******************************** * Phase 4: ターゲットラインのトラックを整理 ******************************** */ routing_arrange(trgt_line); // delete は高位合成できないから放置。 /*for(int y=0;y<board->getSizeY();y++){ for(int x=0;x<board->getSizeX();x++){ delete my_board_1[y][x]; delete my_board_2[y][x]; } }*/ *output = 0; return true; }
// 中間ポートを利用する場合のルーティング(中間からシンクまで) bool routingIToSink(int trgt_line_id){ Line* trgt_line = board->line(trgt_line_id); vector<vector<IntraBox*> > my_board(board->getSizeY(), vector<IntraBox*>(board->getSizeX())); IntraBox init = { INT_MAX,INT_MAX,INT_MAX,INT_MAX, {false,false,false,false}, {false,false,false,false}, {false,false,false,false}, {false,false,false,false}}; for(int y=0;y<board->getSizeY();y++){ for(int x=0;x<board->getSizeX();x++){ my_board[y][x] = new IntraBox; *(my_board[y][x]) = init; } } // 通れないマスを規定 vector<Point>* trgt_track = trgt_line->getTrack(); map<int,map<int,bool> > can_pass; for(int y=-1;y<=board->getSizeY();y++){ for(int x=-1;x<=board->getSizeX();x++){ can_pass[y][x] = true; } } for(int i=0;i<(int)(trgt_track->size());i++){ int tmp_x = (*trgt_track)[i].x; int tmp_y = (*trgt_track)[i].y; can_pass[tmp_y][tmp_x] = false; can_pass[tmp_y][tmp_x-1] = false; can_pass[tmp_y][tmp_x+1] = false; can_pass[tmp_y-1][tmp_x] = false; can_pass[tmp_y+1][tmp_x] = false; } // ソースから中間までの経路を一時保存 vector<Point> before_track; for(int i=0;i<(int)(trgt_track->size());i++){ before_track.push_back((*trgt_track)[i]); } trgt_track->clear(); int start_x = trgt_line->getInterX(); int start_y = trgt_line->getInterY(); IntraBox* start = my_board[start_y][start_x]; start->ne = 0; start->nw = 0; start->se = 0; start->sw = 0; queue<Search> qu; // 北方向 if(can_pass[start_y-1][start_x] && isInserted(start_x,start_y-1,SOUTH) && isFixed(start_x,start_y,NORTH,-1,trgt_line_id)){ Search trgt = {start_x,start_y-1,SOUTH,-1}; qu.push(trgt); } // 東方向 if(can_pass[start_y][start_x+1] && isInserted(start_x+1,start_y,WEST) && isFixed(start_x,start_y,EAST,-1,trgt_line_id)){ Search trgt = {start_x+1,start_y,WEST,-1}; qu.push(trgt); } // 南方向 if(can_pass[start_y+1][start_x] && isInserted(start_x,start_y+1,NORTH) && isFixed(start_x,start_y,SOUTH,-1,trgt_line_id)){ Search trgt = {start_x,start_y+1,NORTH,-1}; qu.push(trgt); } // 西方向 if(can_pass[start_y][start_x-1] && isInserted(start_x-1,start_y,EAST) && isFixed(start_x,start_y,WEST,-1,trgt_line_id)){ Search trgt = {start_x-1,start_y,EAST,-1}; qu.push(trgt); } while(!qu.empty()){ Search trgt = qu.front(); qu.pop(); //cout << "(" << trgt.x << "," << trgt.y << ")" << endl; Box* trgt_box = board->box(trgt.x,trgt.y); IntraBox* trgt_ibox = my_board[trgt.y][trgt.x]; bool update = false; int turn_count = 0; if(trgt.c != trgt.d) turn_count++; // コスト計算 if(trgt.d == SOUTH){ // 南から来た IntraBox* find_ibox = my_board[trgt.y+1][trgt.x]; // タッチ数 int touch_count = countLineNum(trgt.x,trgt.y) - trgt_box->getSouthNum(); if(touch_count < 0){ cout << "error! (error: 24)" << endl; exit(24); } // コスト int cost_se = (find_ibox->ne) + ML + touch_count * penalty_T + turn_count * BT; int cost_ne = (find_ibox->ne) + ML + touch_count * penalty_T + trgt_box->getEastNum() * penalty_C + turn_count * BT; int cost_sw = (find_ibox->nw) + ML + touch_count * penalty_T + turn_count * BT; int cost_nw = (find_ibox->nw) + ML + touch_count * penalty_T + trgt_box->getWestNum() * penalty_C + turn_count * BT; // 南東マス if(cost_se < trgt_ibox->se){ update = true; trgt_ibox->se = cost_se; (trgt_ibox->d_se).n = false; (trgt_ibox->d_se).e = false; (trgt_ibox->d_se).s = true; (trgt_ibox->d_se).w = false; } else if(cost_se == trgt_ibox->se){ (trgt_ibox->d_se).s = true; } // 北東マス if(cost_ne < trgt_ibox->ne){ update = true; trgt_ibox->ne = cost_ne; (trgt_ibox->d_ne).n = false; (trgt_ibox->d_ne).e = false; (trgt_ibox->d_ne).s = true; (trgt_ibox->d_ne).w = false; } else if(cost_ne == trgt_ibox->ne){ (trgt_ibox->d_ne).s = true; } // 南西マス if(cost_sw < trgt_ibox->sw){ update = true; trgt_ibox->sw = cost_sw; (trgt_ibox->d_sw).n = false; (trgt_ibox->d_sw).e = false; (trgt_ibox->d_sw).s = true; (trgt_ibox->d_sw).w = false; } else if(cost_sw == trgt_ibox->sw){ (trgt_ibox->d_sw).s = true; } // 北西マス if(cost_nw < trgt_ibox->nw){ update = true; trgt_ibox->nw = cost_nw; (trgt_ibox->d_nw).n = false; (trgt_ibox->d_nw).e = false; (trgt_ibox->d_nw).s = true; (trgt_ibox->d_nw).w = false; } else if(cost_nw == trgt_ibox->nw){ (trgt_ibox->d_nw).s = true; } } if(trgt.d == WEST){ // 西から来た IntraBox* find_ibox = my_board[trgt.y][trgt.x-1]; // タッチ数 int touch_count = countLineNum(trgt.x,trgt.y) - trgt_box->getWestNum(); if(touch_count < 0){ cout << "error! (error: 25)" << endl; exit(25); } // コスト int cost_nw = (find_ibox->ne) + ML + touch_count * penalty_T + turn_count * BT; int cost_ne = (find_ibox->ne) + ML + touch_count * penalty_T + trgt_box->getNorthNum() * penalty_C + turn_count * BT; int cost_sw = (find_ibox->se) + ML + touch_count * penalty_T + turn_count * BT; int cost_se = (find_ibox->se) + ML + touch_count * penalty_T + trgt_box->getSouthNum() * penalty_C + turn_count * BT; // 北西マス if(cost_nw < trgt_ibox->nw){ update = true; trgt_ibox->nw = cost_nw; (trgt_ibox->d_nw).n = false; (trgt_ibox->d_nw).e = false; (trgt_ibox->d_nw).s = false; (trgt_ibox->d_nw).w = true; } else if(cost_nw == trgt_ibox->nw){ (trgt_ibox->d_nw).w = true; } // 北東マス if(cost_ne < trgt_ibox->ne){ update = true; trgt_ibox->ne = cost_ne; (trgt_ibox->d_ne).n = false; (trgt_ibox->d_ne).e = false; (trgt_ibox->d_ne).s = false; (trgt_ibox->d_ne).w = true; } else if(cost_ne == trgt_ibox->ne){ (trgt_ibox->d_ne).w = true; } // 南西マス if(cost_sw < trgt_ibox->sw){ update = true; trgt_ibox->sw = cost_sw; (trgt_ibox->d_sw).n = false; (trgt_ibox->d_sw).e = false; (trgt_ibox->d_sw).s = false; (trgt_ibox->d_sw).w = true; } else if(cost_sw == trgt_ibox->sw){ (trgt_ibox->d_sw).w = true; } // 南東マス if(cost_se < trgt_ibox->se){ update = true; trgt_ibox->se = cost_se; (trgt_ibox->d_se).n = false; (trgt_ibox->d_se).e = false; (trgt_ibox->d_se).s = false; (trgt_ibox->d_se).w = true; } else if(cost_se == trgt_ibox->se){ (trgt_ibox->d_se).w = true; } } if(trgt.d == NORTH){ // 北から来た IntraBox* find_ibox = my_board[trgt.y-1][trgt.x]; // タッチ数 int touch_count = countLineNum(trgt.x,trgt.y) - trgt_box->getNorthNum(); if(touch_count < 0){ cout << "error! (error: 26)" << endl; exit(26); } // コスト int cost_ne = (find_ibox->se) + ML + touch_count * penalty_T + turn_count * BT; int cost_se = (find_ibox->se) + ML + touch_count * penalty_T + trgt_box->getEastNum() * penalty_C + turn_count * BT; int cost_nw = (find_ibox->sw) + ML + touch_count * penalty_T + turn_count * BT; int cost_sw = (find_ibox->sw) + ML + touch_count * penalty_T + trgt_box->getWestNum() * penalty_C + turn_count * BT; // 北東マス if(cost_ne < trgt_ibox->ne){ update = true; trgt_ibox->ne = cost_ne; (trgt_ibox->d_ne).n = true; (trgt_ibox->d_ne).e = false; (trgt_ibox->d_ne).s = false; (trgt_ibox->d_ne).w = false; } else if(cost_ne == trgt_ibox->ne){ (trgt_ibox->d_ne).n = true; } // 南東マス if(cost_se < trgt_ibox->se){ update = true; trgt_ibox->se = cost_se; (trgt_ibox->d_se).n = true; (trgt_ibox->d_se).e = false; (trgt_ibox->d_se).s = false; (trgt_ibox->d_se).w = false; } else if(cost_se == trgt_ibox->se){ (trgt_ibox->d_se).n = true; } // 北西マス if(cost_nw < trgt_ibox->nw){ update = true; trgt_ibox->nw = cost_nw; (trgt_ibox->d_nw).n = true; (trgt_ibox->d_nw).e = false; (trgt_ibox->d_nw).s = false; (trgt_ibox->d_nw).w = false; } else if(cost_nw == trgt_ibox->nw){ (trgt_ibox->d_nw).n = true; } // 南西マス if(cost_sw < trgt_ibox->sw){ update = true; trgt_ibox->sw = cost_sw; (trgt_ibox->d_sw).n = true; (trgt_ibox->d_sw).e = false; (trgt_ibox->d_sw).s = false; (trgt_ibox->d_sw).w = false; } else if(cost_sw == trgt_ibox->sw){ (trgt_ibox->d_sw).n = true; } } if(trgt.d == EAST){ // 東から来た IntraBox* find_ibox = my_board[trgt.y][trgt.x+1]; // タッチ数 int touch_count = countLineNum(trgt.x,trgt.y) - trgt_box->getEastNum(); if(touch_count < 0){ cout << "error! (error: 27)" << endl; exit(27); } // コスト int cost_ne = (find_ibox->nw) + ML + touch_count * penalty_T + turn_count * BT; int cost_nw = (find_ibox->nw) + ML + touch_count * penalty_T + trgt_box->getNorthNum() * penalty_C + turn_count * BT; int cost_se = (find_ibox->sw) + ML + touch_count * penalty_T + turn_count * BT; int cost_sw = (find_ibox->sw) + ML + touch_count * penalty_T + trgt_box->getSouthNum() * penalty_C + turn_count * BT; // 北東マス if(cost_ne < trgt_ibox->ne){ update = true; trgt_ibox->ne = cost_ne; (trgt_ibox->d_ne).n = false; (trgt_ibox->d_ne).e = true; (trgt_ibox->d_ne).s = false; (trgt_ibox->d_ne).w = false; } else if(cost_ne == trgt_ibox->ne){ (trgt_ibox->d_ne).e = true; } // 北西マス if(cost_nw < trgt_ibox->nw){ update = true; trgt_ibox->nw = cost_nw; (trgt_ibox->d_nw).n = false; (trgt_ibox->d_nw).e = true; (trgt_ibox->d_nw).s = false; (trgt_ibox->d_nw).w = false; } else if(cost_nw == trgt_ibox->nw){ (trgt_ibox->d_nw).e = true; } // 南東マス if(cost_se < trgt_ibox->se){ update = true; trgt_ibox->se = cost_se; (trgt_ibox->d_se).n = false; (trgt_ibox->d_se).e = true; (trgt_ibox->d_se).s = false; (trgt_ibox->d_se).w = false; } else if(cost_se == trgt_ibox->se){ (trgt_ibox->d_se).e = true; } // 南西マス if(cost_sw < trgt_ibox->sw){ update = true; trgt_ibox->sw = cost_sw; (trgt_ibox->d_sw).n = false; (trgt_ibox->d_sw).e = true; (trgt_ibox->d_sw).s = false; (trgt_ibox->d_sw).w = false; } else if(cost_sw == trgt_ibox->sw){ (trgt_ibox->d_sw).e = true; } } if(!update) continue; // 北方向 if(trgt.d!=NORTH && can_pass[trgt.y-1][trgt.x] && isInserted(trgt.x,trgt.y-1,SOUTH) && isFixed(trgt.x,trgt.y,NORTH,trgt.d,trgt_line_id)){ Search next = {trgt.x,trgt.y-1,SOUTH,trgt.d}; qu.push(next); } // 東方向 if(trgt.d!=EAST && can_pass[trgt.y][trgt.x+1] && isInserted(trgt.x+1,trgt.y,WEST) && isFixed(trgt.x,trgt.y,EAST,trgt.d,trgt_line_id)){ Search next = {trgt.x+1,trgt.y,WEST,trgt.d}; qu.push(next); } // 南方向 if(trgt.d!=SOUTH && can_pass[trgt.y+1][trgt.x] && isInserted(trgt.x,trgt.y+1,NORTH) && isFixed(trgt.x,trgt.y,SOUTH,trgt.d,trgt_line_id)){ Search next = {trgt.x,trgt.y+1,NORTH,trgt.d}; qu.push(next); } // 西方向 if(trgt.d!=WEST && can_pass[trgt.y][trgt.x-1] && isInserted(trgt.x-1,trgt.y,EAST) && isFixed(trgt.x,trgt.y,WEST,trgt.d,trgt_line_id)){ Search next = {trgt.x-1,trgt.y,EAST,trgt.d}; qu.push(next); } } // cout << endl; // for(int y=0;y<board->getSizeY();y++){ // for(int x=0;x<board->getSizeX();x++){ // IntraBox* trgt_box = my_board[y][x]; // if(trgt_box->nw > 10000){ // cout << " +"; // } // else{ // cout << setw(2) << trgt_box->nw; // } // if(trgt_box->ne > 10000){ // cout << " +"; // } // else{ // cout << setw(2) << trgt_box->ne; // } // cout << " "; // } // cout << endl; // for(int x=0;x<board->getSizeX();x++){ // IntraBox* trgt_box = my_board[y][x]; // if(trgt_box->sw > 10000){ // cout << " +"; // } // else{ // cout << setw(2) << trgt_box->sw; // } // if(trgt_box->se > 10000){ // cout << " +"; // } // else{ // cout << setw(2) << trgt_box->se; // } // cout << " "; // } // cout << endl; // } // バックトレース int now_x = trgt_line->getSinkX(); int now_y = trgt_line->getSinkY(); int intra_box = -1; vector<int> adj_cost(8); if(now_y!=0){ adj_cost[0] = my_board[now_y-1][now_x]->sw; // 北,南西 adj_cost[1] = my_board[now_y-1][now_x]->se; // 北,南東 } else{ adj_cost[0] = INT_MAX; adj_cost[1] = INT_MAX; } if(now_x!=(board->getSizeX()-1)){ adj_cost[2] = my_board[now_y][now_x+1]->nw; // 東,北西 adj_cost[3] = my_board[now_y][now_x+1]->sw; // 東,南西 } else{ adj_cost[2] = INT_MAX; adj_cost[3] = INT_MAX; } if(now_y!=(board->getSizeY()-1)){ adj_cost[4] = my_board[now_y+1][now_x]->ne; // 南,北東 adj_cost[5] = my_board[now_y+1][now_x]->nw; // 南,北西 } else{ adj_cost[4] = INT_MAX; adj_cost[5] = INT_MAX; } if(now_x!=0){ adj_cost[6] = my_board[now_y][now_x-1]->se; // 西,南東 adj_cost[7] = my_board[now_y][now_x-1]->ne; // 西,北東 } else{ adj_cost[6] = INT_MAX; adj_cost[7] = INT_MAX; } vector<int> min_direction_array; int min_cost = INT_MAX, threshold_cost = 10000, min_direction_array_size; for (int trying = 0; trying < 5; trying++) { for (int a = 0; a < 8; a++) { if (adj_cost[a] > threshold_cost) { continue; } if (adj_cost[a] < min_cost) { min_direction_array.clear(); min_direction_array.push_back(a); min_cost = adj_cost[a]; } else if(adj_cost[a] == min_cost){ min_direction_array.push_back(a); } } min_direction_array_size = (int)(min_direction_array.size()); if (min_direction_array_size != 0) { break; } threshold_cost *= 10; } if (min_direction_array_size == 0) { for (int i = 0; i < (int)(before_track.size()); i++) { trgt_track->push_back(before_track[i]); } return false; } int adj_count = (int)mt_genrand_int32(0, min_direction_array_size - 1); int adj_id = min_direction_array[adj_count]; //cout << min_cost << endl; //bool p_n = false; //bool p_e = false; //bool p_s = false; //bool p_w = false; switch(adj_id){ case 0: // 北,南西 now_y = now_y - 1; intra_box = SW; //p_n = true; break; case 1: // 北,南東 now_y = now_y - 1; intra_box = SE; //p_n = true; break; case 2: // 東,北西 now_x = now_x + 1; intra_box = NW; //p_e = true; break; case 3: // 東,南西 now_x = now_x + 1; intra_box = SW; //p_e = true; break; case 4: // 南,北東 now_y = now_y + 1; intra_box = NE; //p_s = true; break; case 5: // 南,北西 now_y = now_y + 1; intra_box = NW; //p_s = true; break; case 6: // 西,南東 now_x = now_x - 1; intra_box = SE; //p_w = true; break; case 7: // 西,北東 now_x = now_x - 1; intra_box = NE; //p_w = true; break; } while(now_x!=start_x || now_y!=start_y){ //cout << now_x << "," << now_y << endl; Point p = {now_x, now_y}; trgt_line->pushPointToTrack(p); Direction trgt_d; switch(intra_box){ case NE: trgt_d = my_board[now_y][now_x]->d_ne; break; case NW: trgt_d = my_board[now_y][now_x]->d_nw; break; case SE: trgt_d = my_board[now_y][now_x]->d_se; break; case SW: trgt_d = my_board[now_y][now_x]->d_sw; break; default: assert(!"Undefined Intra-Box"); break; } vector<int> next_direction_array; if(trgt_d.n) next_direction_array.push_back(NORTH); if(trgt_d.e) next_direction_array.push_back(EAST); if(trgt_d.s) next_direction_array.push_back(SOUTH); if(trgt_d.w) next_direction_array.push_back(WEST); //cout << (int)(next_direction_array.size()) << endl; int next_count = (int)mt_genrand_int32(0, (int)(next_direction_array.size()) - 1); int next_id = next_direction_array[next_count]; switch(next_id){ case NORTH: now_y = now_y - 1; // 北へ if(intra_box == NE || intra_box == SE) intra_box = SE; if(intra_box == NW || intra_box == SW) intra_box = SW; //p_n = true; p_e = false; p_s = false; p_w = false; break; case EAST: now_x = now_x + 1; // 東へ if(intra_box == NE || intra_box == NW) intra_box = NW; if(intra_box == SE || intra_box == SW) intra_box = SW; //p_n = false; p_e = true; p_s = false; p_w = false; break; case SOUTH: now_y = now_y + 1; // 南へ if(intra_box == NE || intra_box == SE) intra_box = NE; if(intra_box == NW || intra_box == SW) intra_box = NW; //p_n = false; p_e = false; p_s = true; p_w = false; break; case WEST: now_x = now_x - 1; // 西へ if(intra_box == NE || intra_box == NW) intra_box = NE; if(intra_box == SE || intra_box == SW) intra_box = SE; //p_n = false; p_e = false; p_s = false; p_w = true; break; } } // ターゲットラインのトラックを整理する bool retry = true; while (retry) { retry = false; // トラックを一時退避 (コピー) する vector<Point> tmp_track; for (int i = 0; i < (int)(trgt_track->size()); i++) { tmp_track.push_back((*trgt_track)[i]); } // 冗長部分を排除してトラックを整理 trgt_track->clear(); for (int i = 0; i < (int)(tmp_track.size()); i++) { if ((int)(tmp_track.size()) - 2 <= i) { trgt_track->push_back(tmp_track[i]); continue; } if (tmp_track[i].x == tmp_track[i + 2].x && tmp_track[i].y == tmp_track[i + 2].y) { retry = true; i++; continue; } trgt_track->push_back(tmp_track[i]); } } // 中間ポートと中間からソースまでの経路を追加 Point trgt_point = {trgt_line->getInterX(), trgt_line->getInterY()}; trgt_track->push_back(trgt_point); for(int i=0;i<(int)(before_track.size());i++){ trgt_track->push_back(before_track[i]); } // 表示 // map<int,map<int,int> > for_print; // for(int y=0;y<board->getSizeY();y++){ // for(int x=0;x<board->getSizeX();x++){ // Box* trgt_box = board->box(x,y); // if(trgt_box->isTypeBlank()){ // for_print[y][x] = -1; // } // else{ // for_print[y][x] = trgt_box->getNumber(); // } // } // } // for(int i=0;i<(int)(trgt_track->size());i++){ // int point = (*trgt_track)[i]; // int point_x = point % board->getSizeX(); // int point_y = point / board->getSizeX(); // for_print[point_y][point_x] = -2; // } // for(int y=0;y<board->getSizeY();y++){ // for(int x=0;x<board->getSizeX();x++){ // if(for_print[y][x] == -2) cout << "@"; // else if(for_print[y][x] == -1) cout << "+"; // else{ // if(for_print[y][x] < 10){ // cout << for_print[y][x]; // } // else{ // cout << changeIntToChar(for_print[y][x]); // } // } // } // cout << endl; // } for(int y=0;y<board->getSizeY();y++){ for(int x=0;x<board->getSizeX();x++){ delete my_board[y][x]; } } return true; }
static NTSTATUS SrvTree2AcquireFileId_inlock( PLWIO_SRV_TREE_2 pTree, PSMB2_FID pFid ) { NTSTATUS ntStatus = 0; SMB2_FID candidateFid = { .ullPersistentId = 0xFFFFFFFFFFFFFFFFLL, .ullVolatileId = pTree->ullNextAvailableFid }; BOOLEAN bFound = FALSE; BOOLEAN bInLock = FALSE; union { ULONG64 ullFileId; struct { ULONG ulFileId1; ULONG ulFileId2; } fileIdParts; } fileId; do { PLWIO_SRV_FILE_2 pFile = NULL; /* 0 is never a valid fid */ if ((candidateFid.ullVolatileId == 0) || (candidateFid.ullVolatileId == UINT64_MAX)) { candidateFid.ullVolatileId = 1; } ntStatus = LwRtlRBTreeFind( pTree->pFileCollection, &candidateFid, (PVOID*)&pFile); if (ntStatus == STATUS_NOT_FOUND) { ntStatus = STATUS_SUCCESS; bFound = TRUE; } else { candidateFid.ullVolatileId++; } BAIL_ON_NT_STATUS(ntStatus); } while ( (candidateFid.ullVolatileId != pTree->ullNextAvailableFid) && !bFound); if (!bFound) { ntStatus = STATUS_TOO_MANY_OPENED_FILES; BAIL_ON_NT_STATUS(ntStatus); } LWIO_LOCK_MUTEX(bInLock, gSrvElements.pMutex); fileId.fileIdParts.ulFileId1 = mt_genrand_int32(&gSrvElements.randGen); fileId.fileIdParts.ulFileId2 = mt_genrand_int32(&gSrvElements.randGen); candidateFid.ullPersistentId = fileId.ullFileId; LWIO_UNLOCK_MUTEX(bInLock, gSrvElements.pMutex); *pFid = candidateFid; /* Increment by 1 by make sure to deal with wraparound */ candidateFid.ullVolatileId++; pTree->ullNextAvailableFid = candidateFid.ullVolatileId ? candidateFid.ullVolatileId : 1; cleanup: return ntStatus; error: pFid->ullPersistentId = 0LL; pFid->ullVolatileId = 0LL; goto cleanup; } static int SrvTree2FileCompare( PVOID pKey1, PVOID pKey2 ) { PSMB2_FID pFid1 = (PSMB2_FID)pKey1; PSMB2_FID pFid2 = (PSMB2_FID)pKey2; return memcmp((PBYTE)pFid1, (PBYTE)pFid2, sizeof(SMB2_FID)); }
int main(int argc, char *argv[]){ // Options char *in_filename = NULL; // 問題ファイル名 char *out_filename = NULL; // 出力解答ファイル名 char *fix_filename = NULL; // 固定セル情報ファイル名 int outer_loops = O_LOOP; // 外ループ回数 bool fixed = false; // 固定フラグ // Options 取得 struct option longopts[] = { {"loop", required_argument, NULL, 'l'}, {"fixfile", required_argument, NULL, 'x'}, {"output", required_argument, NULL, 'o'}, {"fix-flag", no_argument, NULL, 'f'}, {"version", no_argument, NULL, 'v'}, {"help", no_argument, NULL, 'h'}, {0, 0, 0, 0} }; int opt, optidx; while ((opt = getopt_long(argc, argv, "l:o:fvh", longopts, &optidx)) != -1) { switch (opt) { case 'l': outer_loops = atoi(optarg); break; case 'x': fix_filename = optarg; break; case 'o': out_filename = optarg; break; case 'f': fixed = true; break; case 'v': version(); case 'h': case ':': case '?': default: usage(); } } if (argc <= optind) { usage(); } in_filename = argv[optind]; assert(in_filename != NULL); clock_t start_time, finish_time; start_time = clock(); initialize(in_filename); // 問題盤の生成 printBoard(); // 問題盤の表示 // 固定セルの生成 (機械学習の結果に基づく) if (fix_filename != NULL) { setFixFlagFromFile(fix_filename); printFixFlag(); } // 固定フラグの生成 else if (fixed) { generateFixFlag(); printFixFlag(); } // 乱数の初期化 mt_init_genrand((unsigned long)time(NULL)); // ペナルティの初期化 penalty_T = 0; penalty_C = 0; // 初期ルーティング for(int i=1;i<=board->getLineNum();i++){ // 数字が隣接する場合スキップ if(board->line(i)->getHasLine() == false) continue; if(!routing(i)){ cerr << "Cannot solve!! (error: 1)" << endl; exit(1); } } for(int i=1;i<=board->getLineNum();i++){ // 数字が隣接する場合スキップ if(board->line(i)->getHasLine() == false) continue; recording(i); } // 中間ポートを利用するか? // 利用している間,ライン不通過回数をカウントしない bool use_intermediate_port = false; // 中間ポートに設定するマスとそれを利用する数字 int inter_x, inter_y, inter_line = -1; // 探索スタート!! for (int m = 2; m <= outer_loops + 1; m++) { // 外ループ if(!use_intermediate_port){ // 中間ポートを利用しない場合 if ((m - 1) % 100 == 0) { cout << "loop " << (m-1) << endl; } if(m>INIT){ resetCandidate(); } } else{ // 中間ポートを利用する場合 if ((m - 1) % 100 == 0) { cout << "loop " << (m-1) << "+" << endl; } } // 解導出フラグ bool complete = false; for (int n = 1; n <= I_LOOP; n++) { // 内ループ if (INIT < m && !use_intermediate_port){ checkLineNonPassed(); } // 問題のおいて数字が隣接していないラインを選択する int id; do { id = (int)mt_genrand_int32(1, board->getLineNum()); } while (board->line(id)->getHasLine() == false); //cout << "(" << m << "," << n << ")Re-route Line" << id << endl; // 経路の削除 deleting(id); // ペナルティの設定 penalty_T = (int)(NT * (mt_genrand_int32(0, m - 1))); penalty_C = (int)(NC * (mt_genrand_int32(0, m - 1))); // 中間ポートを利用しない場合 if ( !((board->line(id))->isIntermediateUsed()) ) { // 経路の探索 if ( !routing(id) ) { cerr << "Cannot solve!! (error: 2)" << endl; // 失敗したらプログラム終了 exit(2); } // 経路の記録 recording(id); } // 中間ポートを利用する場合 else { // 経路の探索 (INTTRY 回) bool success = false; for (int count = 0; count < INTTRY; count++) { if (routingSourceToI(id)) { success = routingIToSink(id); break; } } // 中間ポート利用に失敗した場合,通常経路探索した後に内ループ脱出 if ( !success ) { if ( !routing(id) ) { cerr << "Cannot solve!! (error: 3)" << endl; // 失敗したらプログラム終了 exit(3); } recording(id); break; } // 経路の記録 recording(id); } // 終了判定(解導出できた場合,正解を出力) if(isFinished()){ finish_time = clock(); printSolution(); if (out_filename != NULL) { printSolutionToFile(out_filename); cout << "--> Saved to " << out_filename << endl << endl; } cout << "SUMMARY" << endl; cout << "-------" << endl; cout << " - filename: " << in_filename << endl; cout << " - size: " << board->getSizeX() << " x " << board->getSizeY() << endl; cout << " - iterations: " << (m - 1) << endl; cout << " - CPU time: " << ((double)(finish_time - start_time) / (double)CLOCKS_PER_SEC) << " sec" << endl; complete = true; break; } } if(complete) break; // 正解出力後は外ループも脱出 // 中間ポートを使用した次のループでは,中間ポートを利用しない if(use_intermediate_port){ use_intermediate_port = false; board->line(inter_line)->setIntermediateUnuse(); continue; } // 不通過マスの調査->中間ポートを利用するか? int candidate_count = 0; // 候補数 inter_x = -1; inter_y = -1; for(int y=0;y<board->getSizeY();y++){ for(int x=0;x<board->getSizeX();x++){ Box* trgt_box = board->box(x,y); if(trgt_box->isCandidate()){ candidate_count++; //cout << "(" << x << "," << y << ")"; // 不通過マス } } } //cout << endl; if(candidate_count==0) continue; // 候補数0なら利用しない // 候補の中から中間ポートに設定するマスをランダムに選択 int c_d = (int)mt_genrand_int32(0, candidate_count - 1); // 選択は候補の中で何番目か? int n_d = 0; // 何番目なのかをカウントする用の変数 bool flag = false; // 二重ループのためフラグが必要 for(int y=0;y<board->getSizeY();y++){ for(int x=0;x<board->getSizeX();x++){ Box* trgt_box = board->box(x,y); if(!trgt_box->isCandidate()){ continue; } if(n_d==c_d){ flag = true; inter_x = x; inter_y = y; break; } n_d++; } if(flag) break; } // 中間ポートの四方を見て,中間ポートを利用する数字をランダムに選択 checkCandidateLine(inter_x,inter_y); // 候補となるラインを調査 candidate_count = 0; // 候補数 inter_line = -1; for(int i=1;i<=board->getLineNum();i++){ Line* trgt_line = board->line(i); if(trgt_line->isCandidate()){ candidate_count++; //if(candidate_count>1) cout << ", "; //cout << i; } } //cout << endl; if(candidate_count==0) continue; // 候補数0なら利用しない c_d = (int)mt_genrand_int32(0, candidate_count - 1); // 選択は候補の中で何番目か? n_d = 0; // 何番目なのかをカウントする用の変数 for(int i=1;i<=board->getLineNum();i++){ Line* trgt_line = board->line(i); if(!trgt_line->isCandidate()) continue; if(n_d==c_d){ inter_line = i; break; } n_d++; } //cout << "Set (" << inter_x << "," << inter_y << ") InterPort of Line " << inter_line << endl; Line* line_i = board->line(inter_line); line_i->setIntermediateUse(); line_i->setIntermediatePort(inter_x,inter_y); use_intermediate_port = true; // m--; // 使うかどうか思案中・・・ // ペナルティ更新(旧) //penalty_T = (int)(NT * m); //penalty_C = (int)(NC * m); } // 解導出できなかった場合 if(!isFinished()){ for(int i=1;i<=board->getLineNum();i++){ printLine(i); } cerr << "Cannot solve!! (error: 4)" << endl; exit(4); } //デバッグ用 //for(int y=0;y<board->getSizeY();y++){ //for(int x=0;x<board->getSizeX();x++){ //cout << "(" << x << "," << y << ") "; //Box* trgt_box = board->box(x,y); //cout << " N:" << trgt_box->getNorthNum(); //cout << " E:" << trgt_box->getEastNum(); //cout << " S:" << trgt_box->getSouthNum(); //cout << " W:" << trgt_box->getWestNum(); //cout << endl; //} //} //for(int i=1;i<=board->getLineNum();i++){ // calcCost(i); //} delete board; return 0; }