2017中興演算法挑戰賽(迪傑斯特拉)
阿新 • • 發佈:2019-01-08
/************************************************************ * * Shortest Path Search for ZTE Fantastic Algorithm * Author: chyeer * Datetime: 2017-05-02 * Description: multiple constrainted shortest path search * based on Shortested Path Faster Algorithm and * Simulated Anneling Algorithm * ************************************************************/ #include "zte.h" using namespace pan; vector pan::myV[maxn]; //adjacecy list used for topo structure of graph vector pan::constraints; // storage for multiple constraints vector pan::group; // storage for combination of multiple constraints vector pan::path; // storage for shortest path int pan::numNode, pan::numEdge; //vertexes, edges int pan::minPath[maxn]; // shortest path int pan::source[maxn]; // source[a]=b, the node before a is b int pan::start, pan::End; //srouce node, sink node int pan::S, pan::E; // Source Node: S, End Node: E bool pan::inQ[maxn]; // in queue or not int pan::wholeDis; // storage of the miniCost for the shortest path int pan::distance; // distance between two nodes vector pan::mustPassedNode; // Node set that must be passed vector> pan::forbidPassedEdge; // Edge set that can not be passed vector> pan::mustPassedEdge; // Edge set that must be passed void pan::LoadDataFromFile(const char *filename) { FILE *fp = fopen(filename, "r"); char *topo[MAX_LINE_LEN]; // Storage for all lines in file. if (fp == NULL) { printf("Fail to open file %s, %s.\n", filename, strerror(errno)); } printf("Open file %s OK.\n", filename); char line[MAX_LINE_LEN + 2]; unsigned int cnt = 0; // cnt: count line number of file. while (!feof(fp)) { line[0] = 0; if (fgets(line, MAX_LINE_LEN + 2, fp) == NULL) continue; if (line[0] == 0) continue; topo[cnt] = (char *)malloc(MAX_LINE_LEN + 2); strncpy(topo[cnt], line, MAX_LINE_LEN + 2 - 1); // copy file to topo. topo[cnt][MAX_LINE_LEN + 1] = 0; cnt++; } fclose(fp); printf("There are %d lines in file %s.\n", cnt, filename); int mustVertexNum, forbidEdgeNum, mustEdgeNum; int index = 0; sscanf(topo[index], "%d%d%d%d%d", &S, &E, &mustVertexNum, &forbidEdgeNum, &mustEdgeNum); index += 2; int vertex; for(int i=0; i tmp; for(int i=0; i>::iterator iter; for(iter=forbidPassedEdge.begin(); iter!=forbidPassedEdge.end(); iter++) { vector::iterator it; for(it=myV[iter->first].begin(); it!=myV[iter->first].end(); it++) { if(it->to == iter->second) { //it->cost = INF; //delete forbid edge myV[iter->first].erase(it); //cout << it->to << " " << it->cost << endl; break; } } for(it=myV[iter->second].begin(); it!=myV[iter->second].end(); it++) { if(it->to == iter->first) { //it->cost = INF; // delete forbid edge myV[iter->second].erase(it); //cout << it->to << " " << it->cost << endl; break; } } } wholeDis = 0; } void pan::loadConstraints() { node tmp; tmp.from = 14; tmp.to = 13; constraints.push_back(tmp); tmp.from = 12; tmp.to = -1; constraints.push_back(tmp); tmp.from = 7; tmp.to = -1; constraints.push_back(tmp); tmp.from = 4; tmp.to = 2; constraints.push_back(tmp); vector::iterator it; for(it=constraints.begin(); it!=constraints.end(); it++) { group.push_back(it->from); if(~it->to) group.push_back(it->to); } #if 0 for(size_t i=0; i& constraints, vector& group) { size_t index_out, index_in; int cost = INF; size_t location = 0; for(size_t i=0; i::iterator itera; for(itera=constraints.begin(); itera!=constraints.end(); itera++) { group.push_back(itera->from); if(~itera->to) group.push_back(itera->to); } #if 0 for(size_t i=0; i& constraints, vector& group) { constraints.clear(); group.clear(); vector::iterator iter; node tmp; for(iter=mustPassedNode.begin(); iter!=mustPassedNode.end(); iter++) { bool IN = false; for(size_t i=0; i>::iterator it; for(it=mustPassedEdge.begin(); it!=mustPassedEdge.end(); it++) { tmp.from = it->first; tmp.to = it->second; constraints.push_back(tmp); } vector::iterator itera; for(itera=constraints.begin(); itera!=constraints.end(); itera++) { group.push_back(itera->from); if(~itera->to) group.push_back(itera->to); } greedyAlgorithmForFindingInitialSolution(constraints, group); #if 0 for(size_t i=0; i"; cout << path[path.size()-1] << endl; #endif } void pan::simulatedAnnealingForGetNewSolution(vector& constraints, vector& group) { group.clear(); if(rand() % 2) { size_t index_x, index_y; index_x = rand() % constraints.size(); index_y = rand() % constraints.size(); while(index_x == index_y) { index_x = rand() % constraints.size(); index_y = rand() % constraints.size(); } swap(constraints[index_x], constraints[index_y]); } else { size_t index; while(1) { index = rand() % constraints.size(); if(~constraints[index].from && ~constraints[index].to) { swap(constraints[index].from, constraints[index].to); break; } } } vector::iterator it; for(it=constraints.begin(); it!=constraints.end(); it++) { //if(rand() % 2) // swap(it->from, it->to); if(~it->from) group.push_back(it->from); if(~it->to) group.push_back(it->to); } #if 0 while(!tmp.empty()) { index = rand() % tmp.size(); tmpNode = tmp[index]; if(rand() % 2) swap(tmpNode.from, tmpNode.to); if(~tmpNode.from) group.push_back(tmpNode.from); if(~tmpNode.to) group.push_back(tmpNode.to); tmp.erase(tmp.begin()+index); } #endif #if 0 vector::iterator iter; for(iter=group.begin(); iter!=group.end()-1; iter++) { cout << *iter << " "; } cout << *(group.end()-1) << endl; #endif } // kernel algorithm ---- Simulated Anneling Algorithm void pan::simulatedAnnealingForFindShortestPath(vector& constraints, vector& group) { double speed = 0.9999, T = 1000, t_min = 0.001; struct timeval t0, t1; gettimeofday(&t0, NULL); findInitialSolutionForSimulatedAnnealing(constraints, group); // find initial solution cout << "Initial cost: " << wholeDis << endl; int minCost = wholeDis; // cost of initial solution int bestCost = wholeDis; vector bestPath(path); vector tmpConstraints(constraints); vector bestConstraints(constraints); vector tmpGroup; vector bestGroup(group); int delta; int iteration = 0; while(T > t_min) { simulatedAnnealingForGetNewSolution(tmpConstraints, tmpGroup); constraints.assign(tmpConstraints.begin(), tmpConstraints.end()); group.assign(tmpGroup.begin(), tmpGroup.end()); findShortestPath(tmpGroup); delta = wholeDis - minCost; if(delta < 0) { //cout << "better: " << endl; tmpConstraints.assign(constraints.begin(), constraints.end()); tmpGroup.assign(group.begin(), group.end()); if(wholeDis < bestCost) { bestConstraints.assign(constraints.begin(), constraints.end()); bestGroup.assign(group.begin(), group.end()); bestCost = wholeDis; //cout << "bestCost: " << bestCost << endl; } minCost = wholeDis; //if(minCost == 13) // break; } else { if((int)(exp(delta/T)*100) <= (rand() % 101)) { //cout << "worse: " << endl; tmpConstraints.assign(constraints.begin(), constraints.end()); tmpGroup.assign(group.begin(), group.end()); } } T *= speed; iteration++; if(iteration == 10) break; } gettimeofday(&t1, NULL); double timeUse = t1.tv_sec - t0.tv_sec + (t1.tv_usec - t0.tv_usec)/1000000.0; findShortestPath(bestGroup); minCost = wholeDis; bestPath.assign(path.begin(), path.end()); #if 0 int iteration = 100; while(iteration) { simulatedAnnealingForGetNewSolution(constraints, group); findShortestPath(group); //cout << "wholeDis: " << wholeDis << " " << "minCost: " << minCost << endl; if(wholeDis < minCost) { bestPath.assign(path.begin(), path.end()); minCost = wholeDis; cout << "Cost: " << minCost << endl; } iteration--; } #endif cout << "The minimum cost is: " << minCost << endl; cout << "Total vertex num: " << bestPath.size() << endl; cout << "The best path is: "; vector::iterator it; for(it=bestPath.begin(); it!=bestPath.end()-1; it++) { cout << *it << "-->"; } cout << *it << endl; //cout << "Total iteration num: " << iteration << endl; cout << "Time elapse: " << timeUse << " s" << endl; } void pan::findShortestPath(vector& group) { wholeDis = 0; path.clear(); if(!group.empty()) { SPFA(S, group[0]); for(size_t i=0; i>::iterator iter; for(iter=mustPassedEdge.begin(); iter!=mustPassedEdge.end(); iter++) { if(group[i] == iter->first && group[i+1] == iter->second) { IN = true; //add path when the edge must be passed //path.push_back(group[i]); path.push_back(group[i+1]); //add cost vector::iterator it; for(it=myV[group[i]].begin(); it!=myV[group[i]].end(); it++) { if(it->to == group[i+1]) { wholeDis += it->cost; break; } } break; } if(group[i] == iter->second && group[i+1] == iter->first) { IN = true; //add path when the edge must be passed path.push_back(group[i+1]); //path.push_back(group[i]); //add cost vector::iterator it; for(it=myV[group[i+1]].begin(); it!=myV[group[i]].end(); it++) { if(it->to == group[i]) { wholeDis += it->cost; break; } } break; } } if(!IN) SPFA(group[i], group[i+1]); } SPFA(group[group.size()-1], E); } #if 0 cout << "Minimum Cost: " << wholeDis << endl; cout << "Path: "; vector::iterator it; for(it=path.begin(); it!=path.end()-1; it++) { cout << *it << "-->"; } cout << *it << endl; #endif } void pan::inputItial() { int i, from, to, cost; wholeDis = 0; for(i=0; i s; s.push(tmp); while(source[tmp]!=start) { tmp=source[tmp]; s.push(tmp); } while(!s.empty()) { //printf("-->%d",s.top()); path.push_back(s.top()); s.pop(); } //printf("\n"); //printf("Total cost : %d\n\n",minPath[end]); distance = minPath[end]; wholeDis += minPath[end]; } } void pan::SPFA(int start, int end) //Shortest Path Faster Algorithm { memset(inQ, false, sizeof(inQ)); inQ[start] = true; for(int j=0; j myQ; myQ.push(start); int now, to, cost; while(!myQ.empty()) { now=myQ.front(); myQ.pop(); for(size_t k=0; kcost) { source[to] = now; //record the source of to: now minPath[to] = cost; if(!inQ[to]) { inQ[to] = true; myQ.push(to); } } } inQ[now] = false; } output(start, end); } void pan::SaveDataToFile(const char *filename, const vector& path) { fstream fs; fs.open(filename, ios_base::out); fs << path.size() << endl << endl; for(size_t i=0; i