【发布时间】:2017-10-14 13:02:13
【问题描述】:
所以我有一个这样的文件:
NAME : a280
COMMENT : drilling problem (Ludwig)
TYPE : TSP
DIMENSION: 280
EDGE_WEIGHT_TYPE : EUC_2D
NODE_COORD_SECTION
1 288 149
2 288 129
3 270 133
4 256 141
5 256 157
6 246 157
7 236 169
8 228 169
9 228 161
10 220 169
11 212 169
12 204 169
13 196 169
14 188 169
15 196 161
等等……
数字是城市解决 TSP 的绳索。我正在尝试用 Golang 写这个。现在实例可以像 200 个城市,甚至 40.000 个城市。我想得到最好的解决方案,所以我想我应该同时处理这个文件。我有以下代码:
package main
import (
"bufio"
"fmt"
"os"
"regexp"
"strings"
)
func getCords(queue chan string) {
cords := regexp.MustCompile(`\s*\d+\s+\d+\s+\d+`)
for line := range queue {
if cords.MatchString(line) {
fmt.Println(line)
}
}
}
func readFile(fileName string) {
cords := make(chan string)
file := strings.NewReader(fileName)
go func() {
scanner := bufio.NewScanner(file)
for scanner.Scan() {
cords <- scanner.Text()
}
close(cords)
}()
}
// Menu - main program menu
func Menu() {
reader := bufio.NewReader(os.Stdin)
fmt.Println("================== Projektowanie efektywnych algorytmów ==================")
fmt.Println("================== Zadanie nr 1 - Algorytm xyz ==================")
// Wczytywanie pliku z danymi
// Format: Lp. X Y
fmt.Printf("\nPodaj nazwę pliku: ")
fileName, err := reader.ReadString('\n')
if err != nil {
fmt.Println(err)
return
}
readFile(fileName)
}
func main() {
Menu()
}
在getCords函数中,我需要使用正则表达式,因为文件开头往往有信息部分。
问题始于readFile()。我启动了一个 goroutine,它逐行扫描文件并将所有行获取到通道。当然,执行只是启动它并继续前进。现在的问题是,在go func() 调用之后,我将不得不尝试从频道读取。我在 SO 和互联网上找到的解决方案如下:
func readFile(fileName string) {
cords := make(chan string)
file := strings.NewReader(fileName)
go func() {
scanner := bufio.NewScanner(file)
for scanner.Scan() {
cords <- scanner.Text()
}
close(cords)
}()
for i := 0; i < 100; i++ {
go getCords(cords)
}
}
因此,第一次执行 getCords 可能甚至什么都不做,因为 goroutine 无法以那么快的速度将线路连接到通道。下一次迭代可能会完成这项工作,但问题是我必须写一些数字,比如这个例子中的100,它可能太高了,所以通道将在 10 次迭代后关闭,之后它只是一个浪费时间或者它可能太低,然后我就不会得到所有的结果。
你们如何解决这样的问题,伙计们?有没有最佳方法,还是我必须坚持一些waitGroups?
【问题讨论】:
-
首先编写一个可以工作的顺序版本,然后,使用分析找出程序中最慢的部分,最后开始在相关的地方为程序添加并发性。此外,github.com/AkshanshChahal/TSP-Golang
-
您没有在代码中的任何位置打开任何文件。
file := strings.NewReader(fileName)不会打开并从fileName加载数据。os.Open这样做:golang.org/pkg/os/#Open.
标签: go concurrency