graph/multi: use more efficient and correct direction dedup logic

Also add test case to testgraph corpus.
diff --git a/graph/multi/undirected.go b/graph/multi/undirected.go
index c6bd747..d28c309 100644
--- a/graph/multi/undirected.go
+++ b/graph/multi/undirected.go
@@ -77,25 +77,27 @@
 		return graph.Empty
 	}
 	var edges []graph.Edge
-	seen := make(map[int64]struct{})
-	for _, u := range g.lines {
-		for _, e := range u {
-			var lines []graph.Line
+	for xid, u := range g.lines {
+		for yid, e := range u {
+			if yid < xid {
+				// Do not consider lines when the To node ID is
+				// before the From node ID. Both orientations
+				// are stored.
+				continue
+			}
+			// TODO(kortschak): Add iterator.Lines and use that here.
+			if len(e) == 0 {
+				continue
+			}
+			lines := make([]graph.Line, 0, len(e))
 			for _, l := range e {
-				lid := l.ID()
-				if _, ok := seen[lid]; ok {
-					continue
-				}
-				seen[lid] = struct{}{}
 				lines = append(lines, l)
 			}
-			if len(lines) != 0 {
-				edges = append(edges, Edge{
-					F:     g.Node(lines[0].From().ID()),
-					T:     g.Node(lines[0].To().ID()),
-					Lines: iterator.NewOrderedLines(lines),
-				})
-			}
+			edges = append(edges, Edge{
+				F:     g.Node(xid),
+				T:     g.Node(yid),
+				Lines: iterator.NewOrderedLines(lines),
+			})
 		}
 	}
 	if len(edges) == 0 {
diff --git a/graph/multi/weighted_undirected.go b/graph/multi/weighted_undirected.go
index a2a2944..d8ed075 100644
--- a/graph/multi/weighted_undirected.go
+++ b/graph/multi/weighted_undirected.go
@@ -82,26 +82,28 @@
 		return graph.Empty
 	}
 	var edges []graph.Edge
-	seen := make(map[int64]struct{})
-	for _, u := range g.lines {
-		for _, e := range u {
-			var lines []graph.WeightedLine
+	for xid, u := range g.lines {
+		for yid, e := range u {
+			if yid < xid {
+				// Do not consider lines when the To node ID is
+				// before the From node ID. Both orientations
+				// are stored.
+				continue
+			}
+			// TODO(kortschak): Add iterator.WeightedLines and use that here.
+			if len(e) == 0 {
+				continue
+			}
+			lines := make([]graph.WeightedLine, 0, len(e))
 			for _, l := range e {
-				lid := l.ID()
-				if _, ok := seen[lid]; ok {
-					continue
-				}
-				seen[lid] = struct{}{}
 				lines = append(lines, l)
 			}
-			if len(lines) != 0 {
-				edges = append(edges, WeightedEdge{
-					F:             g.Node(lines[0].From().ID()),
-					T:             g.Node(lines[0].To().ID()),
-					WeightedLines: iterator.NewOrderedWeightedLines(lines),
-					WeightFunc:    g.EdgeWeightFunc,
-				})
-			}
+			edges = append(edges, WeightedEdge{
+				F:             g.Node(xid),
+				T:             g.Node(yid),
+				WeightedLines: iterator.NewOrderedWeightedLines(lines),
+				WeightFunc:    g.EdgeWeightFunc,
+			})
 		}
 	}
 	if len(edges) == 0 {
@@ -334,26 +336,28 @@
 		return graph.Empty
 	}
 	var edges []graph.WeightedEdge
-	seen := make(map[int64]struct{})
-	for _, u := range g.lines {
-		for _, e := range u {
-			var lines []graph.WeightedLine
+	for xid, u := range g.lines {
+		for yid, e := range u {
+			if yid < xid {
+				// Do not consider lines when the To node ID is
+				// before the From node ID. Both orientations
+				// are stored.
+				continue
+			}
+			// TODO(kortschak): Add iterator.WeightedLines and use that here.
+			if len(e) == 0 {
+				continue
+			}
+			lines := make([]graph.WeightedLine, 0, len(e))
 			for _, l := range e {
-				lid := l.ID()
-				if _, ok := seen[lid]; ok {
-					continue
-				}
-				seen[lid] = struct{}{}
 				lines = append(lines, l)
 			}
-			if len(lines) != 0 {
-				edges = append(edges, WeightedEdge{
-					F:             g.Node(lines[0].From().ID()),
-					T:             g.Node(lines[0].To().ID()),
-					WeightedLines: iterator.NewOrderedWeightedLines(lines),
-					WeightFunc:    g.EdgeWeightFunc,
-				})
-			}
+			edges = append(edges, WeightedEdge{
+				F:             g.Node(xid),
+				T:             g.Node(yid),
+				WeightedLines: iterator.NewOrderedWeightedLines(lines),
+				WeightFunc:    g.EdgeWeightFunc,
+			})
 		}
 	}
 	if len(edges) == 0 {
diff --git a/graph/testgraph/testcases.go b/graph/testgraph/testcases.go
index 347e8a7..fb9a971 100644
--- a/graph/testgraph/testcases.go
+++ b/graph/testgraph/testcases.go
@@ -369,4 +369,15 @@
 		self:     0,
 		absent:   math.Inf(1),
 	},
+	{
+		name:  "issue 1686",
+		nodes: []graph.Node{node(0), node(1), node(2)},
+		edges: []WeightedLine{
+			line{F: node(0), T: node(1), UID: 0, W: 0.5},
+			line{F: node(1), T: node(2), UID: 0, W: 0.5},
+		},
+		nonexist: []graph.Node{node(-1), node(4)},
+		self:     0,
+		absent:   math.Inf(1),
+	},
 }