蛮力算法解决Delphi中的TSP问题

时间:2014-01-28 20:51:28

标签: algorithm delphi brute-force traveling-salesman

我正在编写一个扩展项目的程序来模拟旅行商问题。到目前为止,我已经写了它以允许用户输入路线,以及使用最近邻居算法“解决”路线。我现在正在尝试编写一个强力算法来解决从3个城市到大约13/14的城市选择。该计划旨在说明城市数量的增加如何导致计算最短路线所花费的时间呈指数/因子增长。我试图写一个递归函数,但无法理解它是如何工作的。我迫切需要一些关于如何做到这一点的指导。任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:2)

由于没有Delphi版本的标签,所以任何版本都适合TopicStarter。那么我的基础是XE2版本。我还假设每个城镇只参观过一次。我认为有一个公路网而不是私人飞机,在任何选定的城市A和B之间可能有直接路径或可能没有(仅通过其他城市连接)。

type TCity = class
   public 
        Name : string;
        Routes : TList<TCity>; // available roads to/from this place
        LeftFor : integer; // where did the merchant went next; -1 if did not arrived or left, used to iterate all the paths

       CameFrom: TCity; // nil initially
 ..... 
End; // writing this draft from phone ( testing official StackOverflow Android app) would not write boilerplate with creating/free in internal objects - do it yourself

Type TPath = TArray<TCity>; // for your app you would add segments and total cost and whatever 
Var World: TArray<TCity >;  // fill cities and links yourself
        AllPaths: TList<TPath>; // create yourself
        Current: TList<TCity >; // create yourself

  Procedure SaveResult;
  Begin AllPaths.Add( Current.ToArray) end;

  Function TryNextCity: boolean;
  Var c1,c2: TCity; I : integer;
  Begin
       c1 := Current.Last; // where we are
       While true do begin
           Inc( c1.LeftFor) ;
          If c1.LeftFor >= c1.Routes.Count // tried all ways? 
             Then Exit( false );

           c2 := c1.Routes (. c1.LeftFor .);
           if c2 = c1.CameFrom then continue;
           if c2.LeftFor >= 0  then continue; // already were there

            AddCity(c2);
            Exit( True) ;
       End;
     End;

  Procedure AddCity( const City: TCity) ;
  Begin
      Assert ( not Current.Contains( City) ) ;
      If Current.Count = 0
          then City.CameFrom := nil //starting point
          else City.CameFrom := Current.Last;
      City.LeftFor := -1;
      Current.Add(City) ;
 End;

   Procedure Withdraw;
   Begin
        Assert ( Current.Count > 0);
        With Current.Last do begin 
             CameFrom := nil;
              LeftFor := -1;
        End;
        Current.Delete( Current.Count - 1) ;
     End;

     Procedure Recurs;
     Var DeadEnd : boolean;
     Begin 
          DeadEnd := true;
          while TryNextCity()  do begin
                DeadEnd := false;
                Recurs();
          end;
          if DeadEnd then SaveResult();
          Withdraw ();
      End;

      Procedure RunBruteForce;
      Var c: TCity ;
      Begin
           AllPaths.Clear;
           For c in world do begin
                Current.Clear;
                AddCity( c );
                Recurs();
             End;
          End;

PS。 @MartynA看起来我现在无法在Android中评论我的答案。所以我的回答是:现在这个问题落入了“做我的家庭作业”,“写一本教科书或至少是一篇文章”和“抛出一堆模糊不错的想法,本身正确,但没有一个会在足够详细和完整,可称为答案“。 我只是开始尝试新的SO应用程序的答案,只是继续它没有删除答案的选项。