extern "C" INT ConnectCovise (MULTIGRID *theMG, char *hostname) { COVISE_HEADER covise; Host *remotehost=new Host(hostname); int quit_loop; printf("CoviseIF: trying to connect to %s\n", hostname); int wait_for_header=FALSE; if (covise_connection==NULL) { covise_connection = new ClientConnection(remotehost, DFLT_PORT, 0, (sender_type)0, 0); printf("CoviseIF: new ClientConnection =%08x\n"); if (! covise_connection->is_connected()) { delete covise_connection; covise_connection=NULL; } else { wait_for_header=TRUE; } } if (covise_connection!=NULL && covise_connection->is_connected()) { printf("CoviseIF: ok, connected to %s\n", hostname); Message* msg = new Message(); int i; if (covise_connection->check_for_input()||wait_for_header) { printf("CoviseIF: input from %s\n", hostname); quit_loop = FALSE; do { covise_connection->recv_msg(msg); printf("CoviseIF: received msg from %s, type %d\n", hostname, msg->type); switch (msg->type) { case (covise_msg_type)0 : { TokenBuffer tb(msg); int headerRequest,gridRequest,numSolutions,solutions[MAX_SOLUTIONS]; tb >> headerRequest; tb >> gridRequest; tb >> numSolutions; for(i=0; i<numSolutions; i++) tb >> solutions[i]; if (headerRequest) { printf("CoviseIF: headerRequest\n"); TokenBuffer rtb; FillCoviseHeader(theMG, &covise); rtb << MT_UGHEADER; rtb << covise.min_level; rtb << covise.max_level; rtb << covise.n_vertices; rtb << covise.n_elems; rtb << covise.n_conns; rtb << covise.num_solutions; for(i=0; i<covise.num_solutions; i++) { printf("CoviseIF: sol #%d: comp=%d name=%s\n", i, covise.solutions[i].n_components, covise.solutions[i].name); rtb << covise.solutions[i].n_components; rtb << covise.solutions[i].name; } Message rmsg(rtb); rmsg.type = (covise_msg_type)0; covise_connection->send_msg(&rmsg); } if (gridRequest) { printf("CoviseIF: gridRequest\n"); SendSurfaceGrid(theMG, &covise); } if (numSolutions>0) { printf("CoviseIF: solRequest, numSol=%d\n", numSolutions); for(i=0; i<numSolutions; i++) { SendSolution(theMG,&covise,solutions[i]); } } } break; /* 'continue without sending grid or solution' message */ case (covise_msg_type)1 : { printf("CoviseIF: continue\n"); quit_loop = TRUE; } break; case SOCKET_CLOSED : case CLOSE_SOCKET : case EMPTY : { printf("CoviseIF: SOCKET_CLOSED\n"); delete covise_connection; covise_connection = NULL; quit_loop = TRUE; } break; case QUIT : { printf("CoviseIF: QUIT\n"); delete covise_connection; covise_connection = NULL; quit_loop = TRUE; /* TODO exit UG itself */ } break; } } while (!quit_loop); }
void Search(std::vector<int> startNeighbor, int*** srcShitAry, int** srcShitDataAry, int* srcShitSizeAry, const int width, const int height, const int stonesNum, const int* srcMap, const int maxFreeSize){ RESTART : aStack.clear(); int freeSize = maxFreeSize; int* map = new int[(width+1) * height]; //対象領域だけを考慮したマップ for(int i = 0; i < (width+1)*height; i++) map[i] = srcMap[i]; int*** shitAry = srcShitAry; //起点配列表現をした糞(ズク)の配列 int** shitDataAry = srcShitDataAry; int* shitSizeAry = srcShitSizeAry; /* int*** shitAry = new int**[stonesNum]; //起点配列表現をした糞(ズク)の配列 int** shitDataAry = new int*[stonesNum]; int* shitSizeAry = new int[stonesNum]; for(int s = 0; s < stonesNum; s++){ //糞(ズク)配列のコピー shitAry[s] = new int*[8]; for(int i = 0; i < 8; i++){ if(srcShitAry[s][i] == 0) { shitAry[s][i] = 0; continue; } shitAry[s][i] = new int[17]; for(int j = 0; j < 17; j++){ shitAry[s][i][j] = srcShitAry[s][i][j]; } } //糞(ズク)データ配列のコピー shitDataAry[s] = new int[8]; for(int i = 0; i < 8; i++){ shitDataAry[s] = srcShitDataAry[s]; } //サイズ配列のコピー shitSizeAry[s] = srcShitSizeAry[s]; }*/ int areaAry[1025]; //下の方でつかいまわしている int subAreaMap[2048]; int putPoints[17]; int putAryLength; int putShitNum = 0; int startKn = 0; std::stack<WideData*> bdStack; int DEBUG_COUNT = 0; int kn = 0; int tmlCount = 0; while(1){ //幅優先探索用のコード bool startFlag = false; if(bdStack.size() == 0){ kn = startKn; startFlag = true; startKn++; if(startKn == stonesNum){ break; } } else { PUT_PROCESS: kn = bdStack.top()->GetShitNumber(); int remove = RemoveShit(map, kn, shitSizeAry[kn], width, height); freeSize += remove; if(remove != 0) { putShitNum--; aStack.pop_back(); } if(!bdStack.top()->Exist()) { delete bdStack.top(); bdStack.pop(); continue; } //実配置処理 wdElement* data = bdStack.top()->GetNext(); while(data->deadArea > minScore || (data->deadArea == minScore && data->needShitNum+putShitNum >= minScore_minShitNum)){ if(!bdStack.top()->Exist()){ delete bdStack.top(); bdStack.pop(); goto PUT_PROCESS; } data = bdStack.top()->GetNext(); } int st = data->st; int placePoint = data->basePoint; int DUMMY; PutShit(map, kn, shitAry[kn][st], placePoint, width+1, height, &DUMMY); putShitNum++; freeSize -= shitSizeAry[kn]; Answer_t ans; ans.basePoint=placePoint; ans.state=st; ans.shitNumber=kn; aStack.push_back(ans); if(kn == stonesNum-1){ goto TERMINAL; } #ifdef DEBUG_CODE #ifdef CHECK_CODE printf("\tshit : %d(%c)\n", kn, kn+49); DEBUG_printMap(map, width+1, height); printf("free : %d\n", freeSize); printf("dead : %d\n", data->deadArea); DEBUG_waitKey(); #endif #endif kn++; while(kn < stonesNum && shitSizeAry[kn] > data->maxAreaSize){ //サイズ的に置けない糞(ズク)をスキップ kn++; #ifdef DEBUG_CODE #ifdef CHECK_CODE printf("%d skipped\n\n", kn); #endif #endif } if(kn == stonesNum) { goto TERMINAL; } //int deadArea = CalcDeadArea(map, width+1, height, freeSize, &(shitSizeAry[kn]), stonesNum-kn, areaAry, &needShitNum); /* if(minScore < data->deadArea || (minScore == data->deadArea && minScore_minShitNum <= data->needShitNum+putShitNum)){ continue; }*/ } //配置処理ここまで BREADTH_MAKE: std::vector<wdElement*>* breadthData = new std::vector<wdElement*>(); for(int st = 0; st < 8; st++){ const int* shit = shitAry[kn][st]; if(shitAry[kn][st] == 0) continue; //ベースポイント配列作成 std::vector<int> baseAry; if(startFlag){ baseAry = startNeighbor; } else { std::vector<int>* neighbor = CalcNeighborPoint(map, width+1, height); //ココ for(int s = 0; shit[s] != -1; s++){ for(int n = 0; n < neighbor->size(); n++){ int value = (*neighbor)[n] - shit[s]; for(int i = 0; i < baseAry.size(); i++){ if(value == baseAry[i]){ goto NEXT; } } baseAry.push_back(value); NEXT:; } } delete neighbor; } //全てのベースポイントを探索 for(int i = 0; i < baseAry.size(); i++){ int basePoint = baseAry[i]; /* printf("%d\n", basePoint); bool a = DEBUG_JudgePutable(map, shit, basePoint, width, height, putPoints, &putAryLength); DEBUG_printPutShitOnMap(map, putPoints, putAryLength, width, height); DEBUG_waitKey(); */ if(JudgePutable(map, shit, basePoint, width, height)){ int neighborNum; PutShit(map, kn, shitAry[kn][st], basePoint, width+1, height, &neighborNum); freeSize -= shitSizeAry[kn]; int needShitNum = 0; int fit; int checkArea = CheckSubArea(map, width+1, height, freeSize, areaAry, subAreaMap, &fit); int deadArea = CalcDeadArea(map, width+1, height, freeSize, &(shitSizeAry[kn]), stonesNum-kn, areaAry, &needShitNum); //doko RemoveShit(map, kn, shitSizeAry[kn], width, height); freeSize += shitSizeAry[kn]; //ここでやれるだろ if(minScore < deadArea || (minScore == deadArea && minScore_minShitNum <= needShitNum+putShitNum)){ continue; } wdElement* temp = new wdElement(); temp->st = st; temp->basePoint = basePoint; temp->fit = fit; temp->fit2 = neighborNum; temp->deadArea = deadArea; temp->maxAreaSize = checkArea; temp->needShitNum = needShitNum; breadthData->push_back(temp); } } } if(breadthData->size() == 0){ //置けないなら #ifdef DEBUG_CODE #ifdef CHECK_CODE printf("%d cannot place\n\n", kn); #endif #endif delete breadthData; kn++; if(kn == stonesNum) goto TERMINAL; goto BREADTH_MAKE; } else { InsertSort(breadthData, breadthData->size()); // for(int i = 0; i < breadthData->size(); i++){ #ifdef DEBUG_CODE #ifdef CHECK_CODE printf("shit %d(%c) place pattern\n", kn, kn+49); #endif #endif for(int i = 0; i < breadthData->size() && (breadthData->data())[i]->rank == 0; i++){ wdElement* elm = breadthData->data()[i]; #ifdef DEBUG_CODE #ifdef CHECK_CODE printf("\t%d | %d-(%d, %d) : %d [%d %d]", elm->rank, elm->st, elm->basePoint%(width+1), elm->basePoint/(width+1), elm->deadArea, elm->fit, elm->fit2); DEBUG_waitKey(); #endif #endif } bdStack.push(new WideData(kn, breadthData, startFlag)); } continue; TERMINAL: #ifdef DEBUG_CODE #ifdef CHECK_CODE printf("\t<<<terminal>>>\n\n"); #endif #endif int score = CalcScore(map, width, height); bool update = false; if(minScore > score){ update = true; } else if(minScore == score){ if(minScore_minShitNum > putShitNum){ update = true; } } if(update){ minScore = score; minScore_minShitNum = putShitNum; #ifdef DEBUG_CODE //DEBUG_printMap(map, width+1, height); LARGE_INTEGER end; QueryPerformanceCounter( &end ); printf("score(%d,%d)\n", minScore, minScore_minShitNum); printf("time : %d\n", (end.QuadPart - start.QuadPart)/liFreq.QuadPart); #endif bestAnsStack = aStack; MAX_TERMINAL_COUNT = HIGH_COUNT; SendSolution(&bestAnsStack, stonesNum, shitDataAry, width+1); tmlCount = 0; } else { tmlCount++; #ifdef CHECK_CODE if(tmlCount%100 == 0){ printf("%d : %d\n", tmlCount/100, kn); } #endif int maxCount = MAX_TERMINAL_COUNT; if(tmlCount == maxCount){ //十万回終端を探索しても解が改善されないなら //koko while(bdStack.size() > 1){ delete bdStack.top(); bdStack.pop(); } while(aStack.size() > 1){ aStack.pop_back(); } freeSize += RemoveShitNums(map, startKn, width, height); //状態をクリア /* RemoveAllShit(map, width, height); freeSize = 0; */ putShitNum = 1; tmlCount = 0; // #ifdef DEBUG_CODE if(MAX_TERMINAL_COUNT == HIGH_COUNT){ printf("focus end : %d\n", MAX_TERMINAL_COUNT); } else { printf("replace : %d\n", MAX_TERMINAL_COUNT); } #ifdef CHECK_CODE DEBUG_printMap(map, width+1, height); printf("free : %d\n", freeSize); DEBUG_waitKey(); #endif #endif MAX_TERMINAL_COUNT = LOW_COUNT; continue; } } if(bdStack.size() == 0) break; if(bdStack.top()->GetShitNumber() == stonesNum-1){ //置いた糞(ズク)が最後なら delete bdStack.top(); bdStack.pop(); int remove = RemoveShit(map, kn, shitSizeAry[kn], width, height); freeSize += remove; if(remove != 0) putShitNum--; aStack.pop_back(); } } delete map; goto RESTART; }