Beispiel #1
0
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;
}
Beispiel #2
0
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;
	}
}
Beispiel #4
0
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;
}
Beispiel #5
0
// 中間ポートを利用する場合のルーティング(中間からシンクまで)
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;
}
Beispiel #6
0
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));
}
Beispiel #7
0
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;
}