def read_tsplib(filename):
    "basic function for reading a symmetric problem in the TSPLIB format"
    "data is stored in an upper triangular matrix"
    "NOTE: some distance types are not handled yet"
    if filename[-3:] == ".gz":
        f = gzip.open(filename, "rt")
    else:
        f = open(filename)

    line = f.readline()
    while line.find("DIMENSION") == -1:
        line = f.readline()
    n = int(line.split()[-1])

    while line.find("EDGE_WEIGHT_TYPE") == -1:
        line = f.readline()

    if line.find("EUC_2D") != -1:
        dist = distL2
    elif line.find("MAN_2D") != -1:
        dist = distL1
    elif line.find("MAX_2D") != -1:
        dist = distLinf
    elif line.find("ATT") != -1:
        dist = distATT
    elif line.find("CEIL_2D") != -1:
        dist = distCEIL2D
    # elif line.find("GEO") != -1:
    #     print("geographic"
    #     dist = distGEO
    elif line.find("EXPLICIT") != -1:
        while line.find("EDGE_WEIGHT_FORMAT") == -1:
            line = f.readline()
        if line.find("LOWER_DIAG_ROW") != -1:
            while line.find("EDGE_WEIGHT_SECTION") == -1:
                line = f.readline()
            return read_explicit_lowerdiag(f,n)
        if line.find("UPPER_ROW") != -1:
            while line.find("EDGE_WEIGHT_SECTION") == -1:
                line = f.readline()
            return read_explicit_upper(f,n)
        if line.find("UPPER_DIAG_ROW") != -1:
            while line.find("EDGE_WEIGHT_SECTION") == -1:
                line = f.readline()
            return read_explicit_upperdiag(f,n)
        if line.find("FULL_MATRIX") != -1:
            while line.find("EDGE_WEIGHT_SECTION") == -1:
                line = f.readline()
            return read_explicit_matrix(f,n)
        print("error reading line " + line)
        raise(Exception)
    else:
        print("cannot deal with '%s' distances" % line)
        raise Exception

    while line.find("NODE_COORD_SECTION") == -1:
        line = f.readline()

    x,y = {},{}
    while 1:
        line = f.readline()
        if line.find("EOF") != -1 or not line: break
        (i,xi,yi) = line.split()
        x[i] = float(xi)
        y[i] = float(yi)

    V = x.keys()
    c = {}      # dictionary to hold n times n matrix
    for i in V:
        for j in V:
            c[i,j] = dist(x[i],y[i],x[j],y[j])

    return V,c,x,y
basic function for reading a symmetric problem in the TSPLIB format