获取最近的路径图

时间:2013-11-05 17:59:30

标签: c++ algorithm graph

我有一个定向图 其中

1 - From 
2 - To
3 - Start time (HH:mm, casted to integer) 60 => 01:00
4 - difference between endtime, always > 0;



1 2 60 120
1 2 720 125
1 2 900 120
1 3 390 90
1 3 1040 95
2 3 780 180
2 3 1260 180
2 4 240 240
2 4 300 240
2 4 1080 240
3 1 165 90
3 1 1430 90
3 2 1432 180
3 5 1431 249
4 2 1080 240
4 3 720 60

让我们忘记开始时间列,但是最简单的算法来获取最近路径,从1到5,这意味着,通过获得第四列总和较小的最近路径。

要提到:我没有真正的节点制作,我只是有关于边缘的信息,我在数组中写的像

edges[ ''counter'' ] [0] = from;
edges[ ''counter'' ] [1] = to;
edges[ ''counter'' ] [2] = timeToInt(time);
edges[ ''counter'' ] [3] = timeToInt(endTime) - edges[ ''counter'' ] [2];

我听说过Dijkstra algorithm,但是如何实施。

2 个答案:

答案 0 :(得分:0)

您的编程语言与此无关,这纯粹是一个算法问题。您的一些好选择包括:

  • Dijkstra's algorithm,如果所有边都有非负成本,就像您的示例中一样。 Dijkstra的速度很快,而且很容易实现。在Boost中有an implementation,谷歌搜索应该会有很多实现。
  • A*,这真是各种Dijkstra的。更快,但启发式,所以可以提供一个不是最好的解决方案,也许更难实现。我强烈建议在实施基本Dijkstra之后,在某些时候实施A *作为练习。再一次,A * exists in Boost
  • Bellman-Ford,如果你需要扩展到负边缘权重。同样present in Boost,只是触摸更难。

答案 1 :(得分:0)

我误解了规则,我不得不采取可能的最近的航班......

// lets find all airports which allows flights from home city and so on..
int min;// minimum value
int minc;// minimal coordinate
int mine;//real position of edge in array
int fakehome = 0;// temprorary position for house
int lastmine = -1;//last position, so can compare times
//cout << timeToInt(begintime);
cout << home << " " << begintime<< endl;
fout << home << " " << begintime<< endl;
while(home != aim)// loop while we havent reached aim/target airport
{
    min = 1440;// 24(hours) * 60 is unreachable value, so 1440 minuts ok
    minc = ports;// max could be count(of airports)
    mine = edges_counter;// array position of edge
    //lastmine = -1;
    for(int i =0;i< edges_counter;i++)
    {
        //if(edges[i][0] == home) cout << edges[i][0] << " " << edges[i][1] <<  " " << edges[i][2] << " " << edges[i][3] << " " << endl;
        if(min > edges[i][2] && edges[i][0] == home && edges[i][4] == 0)
        {
            if(lastmine != -1 && (edges[lastmine][2]+edges[lastmine][3]) < edges[i][2])
            {
                min = edges[i][2];
                minc = edges[i][1];
                mine = i;
                fakehome = edges[i][1];
            }
            else if(lastmine == -1 && timeToInt(saklaiks) < edges[i][2])
            {
                min = edges[i][2];
                minc = edges[i][1];
                mine = i;
                fakehome = edges[i][1];
            }
        }
    }


    if(mine != edges_counter)
    {
        //cout << setw(3) <<  mine << " ";
        intToTime(edges[mine][2],time);
        cout << home << "->" << fakehome << " " << time;
        fout << home << "->" << fakehome << " " << time;
        intToTime((edges[mine][2]+edges[mine][3]), time);
        cout << "-"  << time<< endl;
        fout << "-"  << time<< endl;
        intToTime((edges[mine][2]+edges[mine][3]),begintime);
        home = fakehome;
        edges[mine][4] = 1;
    }
    lastmine = mine;
}

但是有一个问题..

如果

为飞行提供无限循环并且无法达到目标。如何检查?

If is given 
3 (how much airports)
1 3 (have to go from 1 to 3)
00:00 (start time)

1 2 01:00-02:00 (from 1 to 2 there is flight that takes 1 hour)
2 1 03:00-04:00 (from 2 to 1 there's also flight that takes 1 hour)
2 3 12:00-13:00 (...)

但是由于2-> 1飞行比2> 3更快,所以从未到达2> 3 任何想法在打印第一个元素之前知道循环,导致它打印像

1->2 ...
2->1 ...
1->2 ...

等等.. 我必须打印:“不可能”。