Graph colouring: Difference between revisions
→{{header|Go}}: Now uses both 'greedy' and Welsh-Powell algorithms. Preamble rewritten.
m (Whoops.) |
(→{{header|Go}}: Now uses both 'greedy' and Welsh-Powell algorithms. Preamble rewritten.) |
||
Line 150:
=={{header|Go}}==
The results are exactly the same for both algorithms. Whilst one would normally expect Welsh-Powell to give better results overall, the last three examples are not well suited to it as each node has exactly the same number of neighbors i.e. the valences are equal.
The results agree with the Python entry for examples 1 and 2 but, for example 3, Python gives 2 colors compared to my 4 and, for example 4, Python gives 3 colors compared to my 2.
<lang go>package main
import
"fmt"
"sort"
)
type graph struct {
Line 163 ⟶ 168:
}
type nodeval struct {
n int // number of node
v int // valence of node i.e. number of neighbors
}
func contains(s []int, n int) bool {
for _, e := range s {
if e == n {
return true
}
}
return false
}
func newGraph(nn, st int) graph {
nbr := make([][]int, nn)
return
}
Line 177 ⟶ 196:
}
// Uses 'greedy' algorithm.
func (g graph) greedyColoring() []int {
// create a slice with a color for each node, starting with color 0
cols := make([]int, g.nn) // all zero by default including the first node
Line 193 ⟶ 213:
}
}
//
c := 0
for ; c < g.nn; c++ {
Line 208 ⟶ 228:
}
}
}
return cols
}
// Uses Welsh-Powell algorithm.
func (g graph) wpColoring() []int {
// create nodeval for each node
nvs := make([]nodeval, g.nn)
for i := 0; i < g.nn; i++ {
v := len(g.nbr[i])
if v == 1 && g.nbr[i][0] == i { // isolated node
v = 0
}
nvs[i] = nodeval{i, v}
}
// sort the nodevals in descending order by valence
sort.Slice(nvs, func(i, j int) bool {
return nvs[i].v > nvs[j].v
})
// create colors slice with entries for each node
cols := make([]int, g.nn)
for i := range cols {
cols[i] = -1 // set all nodes to no color (-1) initially
}
currCol := 0 // start with color 0
for f := 0; f < g.nn-1; f++ {
h := nvs[f].n
if cols[h] != -1 { // already assigned a color
continue
}
cols[h] = currCol
// assign same color to all subsequent uncolored nodes which are
// not connected to a previous colored one
outer:
for i := f + 1; i < g.nn; i++ {
j := nvs[i].n
if cols[j] != -1 { // already colored
continue
}
for k := f; k < i; k++ {
l := nvs[k].n
if cols[l] == -1 { // not yet colored
continue
}
if contains(g.nbr[j], l) {
continue outer // node j is connected to an earlier colored node
}
}
cols[j] = currCol
}
currCol++
}
return cols
Line 213 ⟶ 284:
func main() {
fns := [](func(graph) []int){graph.greedyColoring, graph.wpColoring}
titles := []string{"'Greedy'", "Welsh-Powell"}
nns := []int{4, 8, 8, 8}
starts := []int{0, 1, 1, 1}
Line 222 ⟶ 295:
edges4 := [][2]int{{1, 6}, {7, 1}, {8, 1}, {5, 2}, {2, 7}, {2, 8},
{3, 5}, {6, 3}, {3, 8}, {4, 5}, {4, 6}, {4, 7}}
for
fmt.Println("
for i, edges := range [][][2]int{edges1, edges2, edges3, edges4} {
g
}
for _,
if
cols[e[0]-g.st], cols[e[1]-g.st])
ecount++
} else {
fmt.Printf(" Node %d -> Color %d\n", e[0], cols[e[0]-g.st])
}
}
maxCol := 0 // maximum color number used
for _, col := range cols {
if col > maxCol {
maxCol = col
}
}
fmt.Println(" Number of nodes :", nns[i])
fmt.Println(" Number of edges :", ecount)
fmt.Println(" Number of colors :", maxCol+1)
fmt.Println()
}
}
}</lang>
Line 254 ⟶ 330:
{{out}}
<pre>
Using the 'Greedy' algorithm:
Example 1
Edge
Edge 2-0 -> Color 2, 0
Node 3 -> Color 0
Number of
Number of edges : 3
Number of colors : 3
Example 2
Edge 1-6 -> Color 0, 1
Edge 1-7 -> Color 0, 1
Edge 1-8 -> Color 0, 1
Edge 2-5 -> Color 0, 1
Edge 2-7 -> Color 0, 1
Edge 2-8 -> Color 0, 1
Edge 3-5 -> Color 0, 1
Edge 3-6 -> Color 0, 1
Edge 3-8 -> Color 0, 1
Edge 4-5 -> Color 0, 1
Edge 4-6 -> Color 0, 1
Edge 4-7 -> Color 0, 1
Number of nodes : 8
Number of edges : 12
Number of colors : 2
Example 3
Edge 1-4 -> Color 0, 1
Edge 1-6 -> Color 0, 2
Edge 1-8 -> Color 0, 3
Edge 3-2 -> Color 1, 0
Edge 3-6 -> Color 1, 2
Edge 3-8 -> Color 1, 3
Edge 5-2 -> Color 2, 0
Edge 5-4 -> Color 2, 1
Edge 5-8 -> Color 2, 3
Edge 7-2 -> Color 3, 0
Edge 7-4 -> Color 3, 1
Edge 7-6 -> Color 3, 2
Number of nodes : 8
Number of edges : 12
Number of colors : 4
Example 4
Edge 1-6 -> Color 0, 1
Edge 7-1 -> Color 1, 0
Edge 8-1 -> Color 1, 0
Edge 5-2 -> Color 1, 0
Edge 2-7 -> Color 0, 1
Edge 2-8 -> Color 0, 1
Edge 3-5 -> Color 0, 1
Edge 6-3 -> Color 1, 0
Edge 3-8 -> Color 0, 1
Edge 4-5 -> Color 0, 1
Edge 4-6 -> Color 0, 1
Edge 4-7 -> Color 0, 1
Number of nodes : 8
Number of edges : 12
Number of colors : 2
Using the Welsh-Powell algorithm:
Example 1
Edge 0-1 -> Color 0, 1
Edge 1-2 -> Color 1, 2
Edge 2-0 -> Color 2, 0
Node 3 -> Color 0
Number of nodes : 4
Number of edges : 3
Number of colors : 3
Example 2
Edge 1-6 -> Color 0, 1
Edge 1-7 -> Color 0, 1
Edge 1-8 -> Color 0, 1
Edge 2-5 -> Color 0, 1
Edge 2-7 -> Color 0, 1
Edge 2-8 -> Color 0, 1
Edge 3-5 -> Color 0, 1
Edge 3-6 -> Color 0, 1
Edge 3-8 -> Color 0, 1
Edge 4-5 -> Color 0, 1
Edge 4-6 -> Color 0, 1
Edge 4-7 -> Color 0, 1
Number of nodes : 8
Number of edges : 12
Number of colors : 2
Example 3
Edge 1-4 -> Color 0, 1
Edge 1-6 -> Color 0, 2
Edge 1-8 -> Color 0, 3
Edge 3-2 -> Color 1, 0
Edge 3-6 -> Color 1, 2
Edge 3-8 -> Color 1, 3
Edge 5-2 -> Color 2, 0
Edge 5-4 -> Color 2, 1
Edge 5-8 -> Color 2, 3
Edge 7-2 -> Color 3, 0
Edge 7-4 -> Color 3, 1
Edge 7-6 -> Color 3, 2
Number of nodes : 8
Number of edges : 12
Number of colors : 4
Example 4
Edge 1-6 -> Color 0, 1
Edge 7-1 -> Color 1, 0
Edge 8-1 -> Color 1, 0
Edge 5-2 -> Color 1, 0
Edge 2-7 -> Color 0, 1
Edge 2-8 -> Color 0, 1
Edge 3-5 -> Color 0, 1
Edge 6-3 -> Color 1, 0
Edge 3-8 -> Color 0, 1
Edge 4-5 -> Color 0, 1
Edge 4-6 -> Color 0, 1
Edge 4-7 -> Color 0, 1
Number of nodes : 8
Number of edges : 12
Number of colors : 2
</pre>
|