```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),
+	},
}
```