0

I'm writing a program for an extended project to simulate the travelling salesman problem. So far I have written it to allow the user to enter a route, as well as 'solving' a route using a nearest neighbour algorithm. I am now trying to write a brute force algorithm to solve for a selection of cities, from 3 cities up to about 13/14. The program is for the purpose of showing how the increase in number of cities leads to an exponential/factorial increase in the time taken to calculate the shortest route. I have tried to write a recursive function but cannot get my head around how it would work. I am in desperate need of some guidance as to how to do this. Any help would be appreciated.

1 Answers1

2

Since there is no tag with Delphi version, then any version suits the TopicStarter just fine. I would base thus draft on XE2 version then. I also would assume that each town is only visited once. I would assume that there is a road network rather than a private airplane, that is between any chosen cities A and B there may be direct path or may not (connection only through other cities).

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 looks like I cannot comment my answer now in Android. So my reply is: this questions as is now falls into a triangle between "do my homework", "write a textbook or at least an essay" and "throw a bunch of vague nice ideas, correct per se, but none of which would be detailed and complete enough to be called an answer". I only started the answer to try new SO app, and only go on for it does not have options to delete the answer.

Arioch 'The
  • 15,799
  • 35
  • 62