0
def basic_greedy():

    start = 1
    mindist = d_dict[(1,2)]
    m = 0

    while len(tour)!=size:
        tour.append(start)
        for k in range(len(cities)):
            if cities[k] not in tour:
                if d_dict[(start,cities[k])]<mindist:
                    mindist = d_dict[(start,cities[k])]
                    m = k
        start = cities[m]

    return tour

This is my code for basic greedy search in Python. start is the start city, tour is a list that shall contain cities in order they are visited, cities is a list containing all cities from 1 to size (1,2,3,4.....12..size) where size is the number of cities. d_dict is a dictionary containing distances between every possible pair of cities. mindist and m are just temporary variables to keep track of nearest neighbours etc.

I expect the code to start from city 1, move to the nearest neighbour, then to the nearest till every city is covered once. I expect the output of this code to be something along the lines of [1,5,3,8,4,6,2,7] for cities 1 to 8 (some combination of visiting all the cities exactly once) but I get [1,7,7,7,7,7,7,7]. What's wrong?

Albert Rothman
  • 998
  • 2
  • 9
  • 27
singhuist
  • 302
  • 1
  • 6
  • 17
  • 2
    Does d_dict include distances between cities and themselves? It looks like you might end up in an endless line of 7, because 7 is closest to itself. Also you probably want to reset mindist before the start of the next loop; what happens if I go city1 to city2 and it is 1 unit of distance away and then to get anywhere from city2 is >1unit of distance. – Albert Rothman Jan 19 '17 at 18:46
  • @AlbertRothman Just resetting mindist worked :D I just included mindist = 99 at the beginning. Rest is as it is. Thank you so much! – singhuist Jan 19 '17 at 20:24
  • 1
    glad that worked. To make it even better you could search over the dictionary and find the largest distance and then add one to that and use it as mindist at the start of each loop; that way your large distance is not hard coded (so you can add cities that are farther than 99 and still get a solution). – Albert Rothman Jan 19 '17 at 21:49

2 Answers2

1

Issues: In general, the problem is ill-defined. The code is in-complete. However, let me provide some basic pointers. Hope it helps. Here goes...

  1. You need to break out of the for-loop as soon as a city is found and added (seems like the case, check, re-check carefully).
  2. The code is incomplete. For instance: (a) How do you get access to the list tour? (b) size not defined
  3. Make sure you do not re-consider or add cities that are already visited in tour list (seems like the case, check, re-check carefully).
  4. It is advised to use graph/node techniques to implement such greedy search.
Ehsan
  • 1,338
  • 14
  • 13
0
def basic_greedy():
    # greedy search algorithm
    d_dict = {1: [(1, 2), (2, 15), (3, 30)], 2: [(1, 30), (7, 10)]}  # dict of lists of tuples such that nodei : [ (neighbourj, distancej), .... ]
    currentCity = 1
    tour = []   # list of covered nodes
    tour.append(currentCity)
    distanceTravelled = 0   # distance travelled in tour
    while len(set([neighbourCity for (neighbourCity, distance) in d_dict.get(currentCity, [])]).difference(set(tour))) > 0:  # set(currentCityNeighbours) - set(visitedNodes)
        # way 1 starts
        minDistanceNeighbour = None
        minDistance = None
        for eachNeighbour, eachNeighbourdDistance in d_dict[currentCity]:
            if eachNeighbour != currentCity and eachNeighbour not in tour:
                if minDistance is not None:
                    if minDistance > eachNeighbourdDistance:
                        minDistance = eachNeighbourdDistance
                        minDistanceNeighbour = eachNeighbour
                else:
                    minDistance = eachNeighbourdDistance
                    minDistanceNeighbour = eachNeighbour
        nearestNeigbhourCity = (minDistanceNeighbour, minDistance)
        # way 1 ends
        # way 2 starts
        # nearestNeigbhourCity = min(d_dict[currentCity], key=lambda someList: someList[1] if someList[0] not in tour else 1000000000)  # else part returns some very large number
        # way 2 ends
        tour.append(nearestNeigbhourCity[0])
        currentCity = nearestNeigbhourCity[0]
        distanceTravelled += nearestNeigbhourCity[1]
    print(tour)
    print(distanceTravelled)

Is this what you were asking for ? I might have changed the structure of the distance dict and some other variables too, but that doesn't affect the greedy approach logic, hope this works for you ... Edited my answer, as in the first time I was finding nearestNeighbourCity among all neighbours of the currentCity but now I am finding nearestNeighbourCity among all unvisited neighbours of current city, and for I have done that using 2 ways way 1 and way 2

tkhurana96
  • 919
  • 7
  • 25