2017中兴算法挑战赛(迪杰斯特拉)

来源:互联网 发布:马哥linux培训 编辑:程序博客网 时间:2024/05/29 12:16

和刚刚结束的2017华为软件精英挑战赛相比,中兴的题目不难,花了两天时间随便搞了一下(其实也没多长时间,因为是周末,还打了农药偷笑),没什么意思,结果刚刚揭晓,58分,评价是“算法尚可,代码一般”,GG,写的太水,大佬莫笑~

赛题:

最强大脑中的收官蜂巢迷宫变态级挑战,相信大家都叹为观止!最强大脑收官战打响后,收视率节节攀升,就连蚁后也不时出题难为一下她的子民们。在动物世界中,称得上活地图的,除了蜜蜂,蚂蚁当仁不让。在复杂多变的蚁巢中, 蚂蚁总是能以最快、最高效的方式游历在各个储藏间(存储食物)。今天,她看完最新一期节目,又发布了一项新任务:小蚁同学,我需要玉米库的玉米,再要配点水果,去帮我找来吧。小蚁正准备出发,蚁后又说:哎呀,回来,我还没说完呢,还有若干要求如下:

1.小蚁同学,你需要尽可能以最少的花费拿到食物(附件图中路线上的数值表示每两个储物间的花费);

2.小蚁同学,你最多只能经过9个储藏间拿到食物(包含起止两个节点,多次通过同一节点按重复次数计算);

3.小蚁同学,你必须经过玉米间,水果间(附件图中标绿色节点);

4.别忘了,食蚁兽也在路上活动呢,一旦与食蚁兽相遇,性命危矣!不过小蚁微信群公告已经公布了敌人信息(附件图中标红色路段);

5.最后,千万别忘了,还有两段路是必须经过的,那里有我准备的神秘礼物等着你呢(附件图中标绿色路段)。

这下小蚁犯难了,这和它们平时找食物的集体活动规则不一样嘛,看来这次需要单独行动了。要怎么选路呢?小蚁经过一番苦思冥想,稿纸堆了一摞,啊,终于找到了!亲爱的同学们,你们能否也设计一种通用的路径搜索算法,来应对各种搜索限制条件,找到一条最优路径,顺利完成蚁后布置的任务呢?


注:

1、蚁巢,有若干个储藏间(附件图中圆圈表示),储藏间之间有诸多路可以到达(各储藏间拓扑图见附件);

2、节点本身通行无花费;

3、该图为无向图,可以正反两方向通行,两方向都会计费,并且花费相同;

4、起止节点分别为附件图中S点和E点。

5、最优路径:即满足限制条件的路径。


算法思路:

贪心算法求解初始解+分段求解最短路+模拟退火算法逐步寻优(实践证明,对于这个对这个问题,贪心算法求出的初始解基本接近最优解,所以说这个比赛很水啦。。。。)


源代码:

/************************************************************ * * 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 *************************************************************/#ifndef ZTE_H#define ZTE_H#include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std;namespace pan{    const int maxn = 1001;    const int INF = 1<<10;    const int MAX_LINE_LEN = 50000;    struct edge   //edge    {        int to;        int cost;    };    struct node    {        int from;        int to;    };    extern vector myV[maxn];  // adjacecy list used for topo structure of graph    extern vector constraints;  // storage for multiple constraints    extern vector group;  // storage for combination of multiple constraints    extern vector path;  // storage for shortest path    extern int numNode, numEdge;  // vertexes, edges    extern int minPath[maxn];  // shortest path    extern int source[maxn];  // source[a]=b, the node before a is b    extern int start, End;  // srouce node, sink node    extern int S, E;  // Source Node: S, End Node: E    extern bool inQ[maxn];  // in queue or not    extern int wholeDis;  // storage of the miniCost for the shortest path    extern int distance;  // distance between two nodes    extern vector mustPassedNode;  // Node set that must be passed    extern vector> forbidPassedEdge; // Edge set that can not be passed    extern vector> mustPassedEdge;  // Edge set that must be passed    void LoadDataFromFile(const char* filename); // load basic graph data    void loadConstraints(); // used for adding constraints    void inputItial();  // input data from screen    void output(int start, int end);  // compute shortest path    void SPFA(int start, int end);  // shortest path faster algorithm    void greedyAlgorithmForFindingInitialSolution(vector& constraints,            vector& group);  // greedy algorithm for finding initial solution    void findInitialSolutionForSimulatedAnnealing(vector& constraints,            vector& group);  // get initial solution for simulated anneling    void simulatedAnnealingForGetNewSolution(vector& constraints,            vector& group);  // get a new solution for simulated anneling    void simulatedAnnealingForFindShortestPath(vector& constraints,            vector& group);  // simulated anneling algorithm    void findShortestPath(vector& group); // find shortest path    void SaveDataToFile(const char* filename, const vector& path);}#endif // ZTE_H
/************************************************************ * * 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 graphvector pan::constraints;   // storage for multiple constraintsvector pan::group;  // storage for combination of multiple constraintsvector pan::path;  // storage for shortest pathint pan::numNode, pan::numEdge; //vertexes, edgesint pan::minPath[maxn]; // shortest pathint pan::source[maxn];  // source[a]=b, the node before a is bint pan::start, pan::End;  //srouce node, sink nodeint pan::S, pan::E;  // Source Node: S, End Node: Ebool pan::inQ[maxn];  // in queue or notint pan::wholeDis;  // storage of the miniCost for the shortest pathint pan::distance;  // distance between two nodesvector pan::mustPassedNode;  // Node set that must be passedvector> pan::forbidPassedEdge;  // Edge set that can not be passedvector> pan::mustPassedEdge;  // Edge set that must be passedvoid 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 Algorithmvoid 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
/************************************************************ * * 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"#include using namespace pan;int main(int argc, char *argv[]){#if 0    freopen("C:\\Users\\Administrator\\Desktop\\case4.txt", "r+" , stdin);    while(scanf("%d%d",&numNode,&numEdge)==2,numNode || numEdge)    {        inputItial();        while(scanf("%d%d",&start,&End)==2,start!=-1 && End!=-1)        {            SPFA(start, End);        }    }    loadConstraints();    findShortestPath(group);    simulatedAnnealingForFindShortestPath(constraints, group);#endif    srand(time(NULL));    //if(argc == 1)    //    cout << "Not enough argument!" << endl;    LoadDataFromFile("C:\\Users\\Administrator\\Desktop\\case4.txt");    simulatedAnnealingForFindShortestPath(constraints, group);    //findInitialSolutionForSimulatedAnnealing(constraints, group);    //greedyAlgorithmForFindingInitialSolution(constraints, group);    SaveDataToFile("C:\\Users\\Administrator\\Desktop\\result0.txt", path);    system("pause");    return 0;}

 实验:


官网样例(18节点):必经点:2 必经边:2

运行结果:


样例1(100节点):必经点:10 必经边:5

运行结果:


样例2(300节点):必经点:30 必经边:15

运行结果:


样例3(1000节点):必经点:100 必经边:50

运行结果:



注:以上用例是ShooterIT大神提供,初写博客,太水,大佬勿喷~

原创粉丝点击