package tspreader import ( "bufio" "errors" "fmt" "log" "os" "strconv" "strings" ) type TspSpec struct { name string problemType string comment string dimension int edgeWeightType string edgeWeightFormat string data *TspData } type TspData struct { datatype string values*[][] float64 } func NewTspData() *TspSpec { return &TspSpec{name: "", problemType: "TSP", comment: "", dimension: 0, edgeWeightType: "", data: NewTspDataArray()} } func NewTspDataArray() *TspData { return &TspData{datatype: "EDGE_WEIGHT_SECTION", values: &[][]float64{}} } func (t TspSpec) String() string { return fmt.Sprintf("%s [%s] - %s %s %d", t.name, t.problemType, t.edgeWeightType, t.edgeWeightFormat, t.dimension) } func (t TspData) String() string { return fmt.Sprintf("Datatype: %s", t.datatype) } // Read Reads TSP data from .tsp file func Read(path string) (*TspSpec, error) { file, err := os.Open(path) if(err != nil) { log.Fatal(err) return nil, errors.New("unable to open file") } scanner := bufio.NewScanner(file) spec := NewTspData() dataLine := -1 arr := [][]float64{} for scanner.Scan() { line := scanner.Text() // handle Specification Headers if strings.Contains(line,":") { strs := strings.Split(line, ":") switch strings.ReplaceAll(strs[0]," ","") { case "NAME": { spec.name = strings.ReplaceAll(strs[1]," ","") } case "TYPE": { spec.problemType = strings.ReplaceAll(strs[1]," ","") } case "COMMENT": { spec.comment = strings.ReplaceAll(strs[1]," ","") } case "DIMENSION": { i, e := strconv.ParseInt(strings.ReplaceAll(strs[1]," ",""),10,64) if(e == nil) { spec.dimension = int(i) } } case "EDGE_WEIGHT_TYPE": { spec.edgeWeightType = strings.ReplaceAll(strs[1]," ","") } case "EDGE_WEIGHT_FORMAT": { spec.edgeWeightFormat = strings.ReplaceAll(strs[1]," ","") } } } else { // Sace Data as Multi Dimensional Array if dataLine == -1 { spec.data.datatype = strings.ReplaceAll(line," ","") dataLine++ } else { entries := strings.Split(line, " ") arr = append(arr, []float64{}) for _, e := range entries{ f, err := strconv.ParseFloat(e, 64) if err == nil { arr[dataLine] = append(arr[dataLine], f) } } dataLine++ } } } spec.data.values = &arr // return specification return spec, nil }