-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathweightvc.go
67 lines (57 loc) · 1.37 KB
/
weightvc.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
package approximate
import (
"algorithms/graph"
"algorithms/linear"
)
func ApproxMinWeightVC(g *graph.G, weights []float64) ([]*graph.V, error) {
var a = linear.Matrix{}
var b = linear.Vector{}
var c = linear.Vector{}
vertexMap := map[*graph.V]int{}
for vIdx, v := range g.Vertexes {
vertexMap[v] = vIdx
}
seenEdges := map[graph.Edge]struct{}{}
for vIdx := range g.Vertexes {
c = append(c, -1*weights[vIdx])
}
for u, vertexes := range g.Adj {
for _, v := range vertexes {
if _, exists := seenEdges[graph.Edge{u, v}]; exists {
continue
}
if _, exists := seenEdges[graph.Edge{v, u}]; exists {
continue
}
seenEdges[graph.Edge{u, v}] = struct{}{}
a = append(a, makeCond2Var(len(g.Vertexes), vertexMap[u], vertexMap[v]))
b = append(b, -1)
}
}
for vIdx := range g.Vertexes {
a = append(a, makeCond1Var(len(g.Vertexes), vIdx))
b = append(b, 1)
}
linearRes, err := linear.Simplex(a, b, c)
if err != nil {
return nil, err
}
vertexCover := []*graph.V{}
for idx, res := range linearRes {
if res >= 0.5 {
vertexCover = append(vertexCover, g.Vertexes[idx])
}
}
return vertexCover, nil
}
func makeCond1Var(len int, idx int) linear.Vector {
vec := make(linear.Vector, len)
vec[idx] = 1
return vec
}
func makeCond2Var(len int, idx1, idx2 int) linear.Vector {
vec := make(linear.Vector, len)
vec[idx1] = -1
vec[idx2] = -1
return vec
}