Data commit
This commit is contained in:
parent
7387c8f97b
commit
cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions
2
Task/Graph-colouring/00-META.yaml
Normal file
2
Task/Graph-colouring/00-META.yaml
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
---
|
||||
from: http://rosettacode.org/wiki/Graph_colouring
|
||||
147
Task/Graph-colouring/00-TASK.txt
Normal file
147
Task/Graph-colouring/00-TASK.txt
Normal file
|
|
@ -0,0 +1,147 @@
|
|||
A [[wp:Graph (discrete mathematics)|Graph]] is a collection of nodes
|
||||
(or vertices), connected by edges (or not).
|
||||
Nodes directly connected by edges are called neighbours.
|
||||
|
||||
In our representation of graphs, nodes are numbered and edges are represented
|
||||
by the two node numbers connected by the edge separated by a dash.
|
||||
Edges define the nodes being connected. Only unconnected nodes ''need'' a separate
|
||||
description.
|
||||
|
||||
For example,
|
||||
<pre>0-1 1-2 2-0 3</pre>
|
||||
Describes the following graph. Note that node 3 has no neighbours
|
||||
|
||||
|
||||
;Example graph:
|
||||
<pre>
|
||||
+---+
|
||||
| 3 |
|
||||
+---+
|
||||
|
||||
+-------------------+
|
||||
| |
|
||||
+---+ +---+ +---+
|
||||
| 0 | --- | 1 | --- | 2 |
|
||||
+---+ +---+ +---+
|
||||
</pre>
|
||||
|
||||
A useful internal datastructure for a graph and for later graph algorithms is
|
||||
as a mapping between each node and the set/list of its neighbours.
|
||||
|
||||
In the above example:
|
||||
<pre>0 maps-to 1 and 2
|
||||
1 maps to 2 and 0
|
||||
2 maps-to 1 and 0
|
||||
3 maps-to <nothing></pre>
|
||||
|
||||
;[[wp:Greedy coloring|Graph colouring]] task:
|
||||
Colour the vertices of a given graph so that no edge is between verticies of
|
||||
the same colour.
|
||||
|
||||
* Integers may be used to denote different colours.
|
||||
* Algorithm should do better than just assigning each vertex a separate colour. The idea is to minimise the number of colours used, although no algorithm short of exhaustive search for the minimum is known at present, (and exhaustive search is '''not''' a requirement).
|
||||
* Show for each edge, the colours assigned on each vertex.
|
||||
* Show the total number of nodes, edges, and colours used for each graph.
|
||||
|
||||
;Use the following graphs:
|
||||
;Ex1:
|
||||
|
||||
0-1 1-2 2-0 3
|
||||
|
||||
<pre>
|
||||
+---+
|
||||
| 3 |
|
||||
+---+
|
||||
|
||||
+-------------------+
|
||||
| |
|
||||
+---+ +---+ +---+
|
||||
| 0 | --- | 1 | --- | 2 |
|
||||
+---+ +---+ +---+
|
||||
</pre>
|
||||
;Ex2:
|
||||
The wp articles left-side graph
|
||||
|
||||
1-6 1-7 1-8 2-5 2-7 2-8 3-5 3-6 3-8 4-5 4-6 4-7
|
||||
|
||||
<pre>
|
||||
|
||||
+----------------------------------+
|
||||
| |
|
||||
| +---+ |
|
||||
| +-----------------| 3 | ------+----+
|
||||
| | +---+ | |
|
||||
| | | | |
|
||||
| | | | |
|
||||
| | | | |
|
||||
| +---+ +---+ +---+ +---+ |
|
||||
| | 8 | --- | 1 | --- | 6 | --- | 4 | |
|
||||
| +---+ +---+ +---+ +---+ |
|
||||
| | | | |
|
||||
| | | | |
|
||||
| | | | |
|
||||
| | +---+ +---+ +---+ |
|
||||
+----+------ | 7 | --- | 2 | --- | 5 | -+
|
||||
| +---+ +---+ +---+
|
||||
| |
|
||||
+-------------------+
|
||||
</pre>
|
||||
;Ex3:
|
||||
The wp articles right-side graph which is the same graph as Ex2, but with
|
||||
different node orderings and namings.
|
||||
|
||||
1-4 1-6 1-8 3-2 3-6 3-8 5-2 5-4 5-8 7-2 7-4 7-6
|
||||
|
||||
<pre>
|
||||
|
||||
+----------------------------------+
|
||||
| |
|
||||
| +---+ |
|
||||
| +-----------------| 5 | ------+----+
|
||||
| | +---+ | |
|
||||
| | | | |
|
||||
| | | | |
|
||||
| | | | |
|
||||
| +---+ +---+ +---+ +---+ |
|
||||
| | 8 | --- | 1 | --- | 4 | --- | 7 | |
|
||||
| +---+ +---+ +---+ +---+ |
|
||||
| | | | |
|
||||
| | | | |
|
||||
| | | | |
|
||||
| | +---+ +---+ +---+ |
|
||||
+----+------ | 6 | --- | 3 | --- | 2 | -+
|
||||
| +---+ +---+ +---+
|
||||
| |
|
||||
+-------------------+
|
||||
</pre>
|
||||
;Ex4:
|
||||
This is the same graph, node naming, and edge order as Ex2 except some of the edges x-y are flipped to y-x.
|
||||
This might alter the node order used in the greedy algorithm leading to differing numbers of colours.
|
||||
|
||||
1-6 7-1 8-1 5-2 2-7 2-8 3-5 6-3 3-8 4-5 4-6 4-7
|
||||
|
||||
<pre>
|
||||
|
||||
+-------------------------------------------------+
|
||||
| |
|
||||
| |
|
||||
+-------------------+---------+ |
|
||||
| | | |
|
||||
+---+ +---+ +---+ +---+ +---+ +---+ +---+ +---+
|
||||
| 4 | --- | 5 | --- | 2 | --- | 7 | --- | 1 | --- | 6 | --- | 3 | --- | 8 |
|
||||
+---+ +---+ +---+ +---+ +---+ +---+ +---+ +---+
|
||||
| | | | | |
|
||||
+---------+-----------------------------+---------+ | |
|
||||
| | | |
|
||||
| | | |
|
||||
+-----------------------------+-------------------+ |
|
||||
| |
|
||||
| |
|
||||
+-----------------------------+
|
||||
</pre>
|
||||
|
||||
;References:
|
||||
* [[wp:Greedy coloring|Greedy coloring]] Wikipedia.
|
||||
* [https://www.slideshare.net/PriyankJain26/graph-coloring-48222920 Graph Coloring : Greedy Algorithm & Welsh Powell Algorithm] by Priyank Jain.
|
||||
|
||||
|
||||
46
Task/Graph-colouring/11l/graph-colouring.11l
Normal file
46
Task/Graph-colouring/11l/graph-colouring.11l
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
F first_avail_int(data)
|
||||
‘return lowest int 0... not in data’
|
||||
V d = Set(data)
|
||||
L(i) 0..
|
||||
I i !C d
|
||||
R i
|
||||
|
||||
F greedy_colour(name, connections)
|
||||
DefaultDict[Int, [Int]] graph
|
||||
|
||||
L(connection) connections.split(‘ ’)
|
||||
I ‘-’ C connection
|
||||
V (n1, n2) = connection.split(‘-’).map(Int)
|
||||
graph[n1].append(n2)
|
||||
graph[n2].append(n1)
|
||||
E
|
||||
graph[Int(connection)] = [Int]()
|
||||
|
||||
// Greedy colourisation algo
|
||||
V order = sorted(graph.keys())
|
||||
[Int = Int] colour
|
||||
V neighbours = graph
|
||||
L(node) order
|
||||
V used_neighbour_colours = neighbours[node].filter(nbr -> nbr C @colour).map(nbr -> @colour[nbr])
|
||||
colour[node] = first_avail_int(used_neighbour_colours)
|
||||
|
||||
print("\n"name)
|
||||
V canonical_edges = Set[(Int, Int)]()
|
||||
L(n1, neighbours) sorted(graph.items())
|
||||
I !neighbours.empty
|
||||
L(n2) neighbours
|
||||
V edge = tuple_sorted((n1, n2))
|
||||
I edge !C canonical_edges
|
||||
print(‘ #.-#.: Colour: #., #.’.format(n1, n2, colour[n1], colour[n2]))
|
||||
canonical_edges.add(edge)
|
||||
E
|
||||
print(‘ #.: Colour: #.’.format(n1, colour[n1]))
|
||||
V lc = Set(colour.values()).len
|
||||
print(" #Nodes: #.\n #Edges: #.\n #Colours: #.".format(colour.len, canonical_edges.len, lc))
|
||||
|
||||
L(name, connections) [
|
||||
(‘Ex1’, ‘0-1 1-2 2-0 3’),
|
||||
(‘Ex2’, ‘1-6 1-7 1-8 2-5 2-7 2-8 3-5 3-6 3-8 4-5 4-6 4-7’),
|
||||
(‘Ex3’, ‘1-4 1-6 1-8 3-2 3-6 3-8 5-2 5-4 5-8 7-2 7-4 7-6’),
|
||||
(‘Ex4’, ‘1-6 7-1 8-1 5-2 2-7 2-8 3-5 6-3 3-8 4-5 4-6 4-7’)]
|
||||
greedy_colour(name, connections)
|
||||
172
Task/Graph-colouring/Go/graph-colouring.go
Normal file
172
Task/Graph-colouring/Go/graph-colouring.go
Normal file
|
|
@ -0,0 +1,172 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sort"
|
||||
)
|
||||
|
||||
type graph struct {
|
||||
nn int // number of nodes
|
||||
st int // node numbering starts from
|
||||
nbr [][]int // neighbor list for each node
|
||||
}
|
||||
|
||||
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 graph{nn, st, nbr}
|
||||
}
|
||||
|
||||
// Note that this creates a single 'virtual' edge for an isolated node.
|
||||
func (g graph) addEdge(n1, n2 int) {
|
||||
n1, n2 = n1-g.st, n2-g.st // adjust to starting node number
|
||||
g.nbr[n1] = append(g.nbr[n1], n2)
|
||||
if n1 != n2 {
|
||||
g.nbr[n2] = append(g.nbr[n2], n1)
|
||||
}
|
||||
}
|
||||
|
||||
// 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
|
||||
for i := 1; i < g.nn; i++ {
|
||||
cols[i] = -1 // mark all nodes after the first as having no color assigned (-1)
|
||||
}
|
||||
// create a bool slice to keep track of which colors are available
|
||||
available := make([]bool, g.nn) // all false by default
|
||||
// assign colors to all nodes after the first
|
||||
for i := 1; i < g.nn; i++ {
|
||||
// iterate through neighbors and mark their colors as available
|
||||
for _, j := range g.nbr[i] {
|
||||
if cols[j] != -1 {
|
||||
available[cols[j]] = true
|
||||
}
|
||||
}
|
||||
// find the first available color
|
||||
c := 0
|
||||
for ; c < g.nn; c++ {
|
||||
if !available[c] {
|
||||
break
|
||||
}
|
||||
}
|
||||
cols[i] = c // assign it to the current node
|
||||
// reset the neighbors' colors to unavailable
|
||||
// before the next iteration
|
||||
for _, j := range g.nbr[i] {
|
||||
if cols[j] != -1 {
|
||||
available[cols[j]] = false
|
||||
}
|
||||
}
|
||||
}
|
||||
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
|
||||
}
|
||||
|
||||
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}
|
||||
edges1 := [][2]int{{0, 1}, {1, 2}, {2, 0}, {3, 3}}
|
||||
edges2 := [][2]int{{1, 6}, {1, 7}, {1, 8}, {2, 5}, {2, 7}, {2, 8},
|
||||
{3, 5}, {3, 6}, {3, 8}, {4, 5}, {4, 6}, {4, 7}}
|
||||
edges3 := [][2]int{{1, 4}, {1, 6}, {1, 8}, {3, 2}, {3, 6}, {3, 8},
|
||||
{5, 2}, {5, 4}, {5, 8}, {7, 2}, {7, 4}, {7, 6}}
|
||||
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 j, fn := range fns {
|
||||
fmt.Println("Using the", titles[j], "algorithm:\n")
|
||||
for i, edges := range [][][2]int{edges1, edges2, edges3, edges4} {
|
||||
fmt.Println(" Example", i+1)
|
||||
g := newGraph(nns[i], starts[i])
|
||||
for _, e := range edges {
|
||||
g.addEdge(e[0], e[1])
|
||||
}
|
||||
cols := fn(g)
|
||||
ecount := 0 // counts edges
|
||||
for _, e := range edges {
|
||||
if e[0] != e[1] {
|
||||
fmt.Printf(" Edge %d-%d -> Color %d, %d\n", e[0], e[1],
|
||||
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()
|
||||
}
|
||||
}
|
||||
}
|
||||
69
Task/Graph-colouring/Haskell/graph-colouring-1.hs
Normal file
69
Task/Graph-colouring/Haskell/graph-colouring-1.hs
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
import Data.Maybe
|
||||
import Data.List
|
||||
import Control.Monad.State
|
||||
import qualified Data.Map as M
|
||||
import Text.Printf
|
||||
|
||||
------------------------------------------------------------
|
||||
-- Primitive graph representation
|
||||
|
||||
type Node = Int
|
||||
type Color = Int
|
||||
type Graph = M.Map Node [Node]
|
||||
|
||||
nodes :: Graph -> [Node]
|
||||
nodes = M.keys
|
||||
|
||||
adjacentNodes :: Graph -> Node -> [Node]
|
||||
adjacentNodes g n = fromMaybe [] $ M.lookup n g
|
||||
|
||||
degree :: Graph -> Node -> Int
|
||||
degree g = length . adjacentNodes g
|
||||
|
||||
fromList :: [(Node, [Node])] -> Graph
|
||||
fromList = foldr add M.empty
|
||||
where
|
||||
add (a, bs) g = foldr (join [a]) (join bs a g) bs
|
||||
join = flip (M.insertWith (++))
|
||||
|
||||
readGraph :: String -> Graph
|
||||
readGraph = fromList . map interprete . words
|
||||
where
|
||||
interprete s = case span (/= '-') s of
|
||||
(a, "") -> (read a, [])
|
||||
(a, '-':b) -> (read a, [read b])
|
||||
|
||||
------------------------------------------------------------
|
||||
-- Graph coloring functions
|
||||
|
||||
uncolored :: Node -> State [(Node, Color)] Bool
|
||||
uncolored n = isNothing <$> colorOf n
|
||||
|
||||
colorOf :: Node -> State [(Node, Color)] (Maybe Color)
|
||||
colorOf n = gets (lookup n)
|
||||
|
||||
greedyColoring :: Graph -> [(Node, Color)]
|
||||
greedyColoring g = mapM_ go (nodes g) `execState` []
|
||||
where
|
||||
go n = do
|
||||
c <- colorOf n
|
||||
when (isNothing c) $ do
|
||||
adjacentColors <- nub . catMaybes <$> mapM colorOf (adjacentNodes g n)
|
||||
let newColor = head $ filter (`notElem` adjacentColors) [1..]
|
||||
modify ((n, newColor) :)
|
||||
filterM uncolored (adjacentNodes g n) >>= mapM_ go
|
||||
|
||||
wpColoring :: Graph -> [(Node, Color)]
|
||||
wpColoring g = go [1..] nodesList `execState` []
|
||||
where
|
||||
nodesList = sortOn (negate . degree g) (nodes g)
|
||||
|
||||
go _ [] = pure ()
|
||||
go (c:cs) ns = do
|
||||
mark c ns
|
||||
filterM uncolored ns >>= go cs
|
||||
|
||||
mark c [] = pure () :: State [(Node, Color)] ()
|
||||
mark c (n:ns) = do
|
||||
modify ((n, c) :)
|
||||
mark c (filter (`notElem` adjacentNodes g n) ns)
|
||||
18
Task/Graph-colouring/Haskell/graph-colouring-2.hs
Normal file
18
Task/Graph-colouring/Haskell/graph-colouring-2.hs
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
ex1 = "0-1 1-2 2-0 3"
|
||||
ex2 = "1-6 1-7 1-8 2-5 2-7 2-8 3-5 3-6 3-8 4-5 4-6 4-7"
|
||||
ex3 = "1-4 1-6 1-8 3-2 3-6 3-8 5-2 5-4 5-8 7-2 7-4 7-6"
|
||||
ex4 = "1-6 7-1 8-1 5-2 2-7 2-8 3-5 6-3 3-8 4-5 4-6 4-7"
|
||||
|
||||
task method ex =
|
||||
let g = readGraph ex
|
||||
cs = sortOn fst $ method g
|
||||
color n = fromJust $ lookup n cs
|
||||
ns = nodes g
|
||||
mkLine n = printf "%d\t%d\t%s\n" n (color n) (show (color <$> adjacentNodes g n))
|
||||
in do
|
||||
print ex
|
||||
putStrLn $ "nodes:\t" ++ show ns
|
||||
putStrLn $ "colors:\t" ++ show (nub (snd <$> cs))
|
||||
putStrLn "node\tcolor\tadjacent colors"
|
||||
mapM_ mkLine ns
|
||||
putStrLn ""
|
||||
15
Task/Graph-colouring/J/graph-colouring-1.j
Normal file
15
Task/Graph-colouring/J/graph-colouring-1.j
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
parse=: {{
|
||||
ref=: 2$L:1(;:each cut y) -.L:1 ;:'-'
|
||||
labels=: /:~~.;ref
|
||||
sparse=. (*:#labels) > 20*#ref
|
||||
graph=: (+.|:) 1 (labels i.L:1 ref)} $.^:sparse 0$~2##labels
|
||||
}}
|
||||
|
||||
greedy=: {{
|
||||
colors=. (#y)#a:
|
||||
for_node.y do.
|
||||
color=. <{.(-.~ [:i.1+#) ~.;node#colors
|
||||
colors=. color node_index} colors
|
||||
end.
|
||||
;colors
|
||||
}}
|
||||
32
Task/Graph-colouring/J/graph-colouring-2.j
Normal file
32
Task/Graph-colouring/J/graph-colouring-2.j
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
ex1=:'0-1 1-2 2-0 3'
|
||||
ex2=:'1-6 1-7 1-8 2-5 2-7 2-8 3-5 3-6 3-8 4-5 4-6 4-7'
|
||||
ex3=:'1-4 1-6 1-8 3-2 3-6 3-8 5-2 5-4 5-8 7-2 7-4 7-6'
|
||||
ex4=:'1-6 7-1 8-1 5-2 2-7 2-8 3-5 6-3 3-8 4-5 4-6 4-7'
|
||||
require'format/printf'
|
||||
require'format/printf'
|
||||
task=: {{
|
||||
colors=. greedy parse y
|
||||
echo'nodes: %d, edges: %d, colours: %d' sprintf #each graph;ref;~.colors
|
||||
edgecolors=. <@(,&":':',&":])/"1(>labels i.L:1 ref){colors
|
||||
,./>' ',.~each^:2(cut y),:each edgecolors
|
||||
}}
|
||||
|
||||
task ex1
|
||||
nodes: 4, edges: 4, colours: 3
|
||||
0-1 1-2 2-0 3
|
||||
0:1 1:2 2:0 0:0
|
||||
|
||||
task ex2
|
||||
nodes: 8, edges: 12, colours: 2
|
||||
1-6 1-7 1-8 2-5 2-7 2-8 3-5 3-6 3-8 4-5 4-6 4-7
|
||||
0:1 0:1 0:1 0:1 0:1 0:1 0:1 0:1 0:1 0:1 0:1 0:1
|
||||
|
||||
task ex3
|
||||
nodes: 8, edges: 12, colours: 4
|
||||
1-4 1-6 1-8 3-2 3-6 3-8 5-2 5-4 5-8 7-2 7-4 7-6
|
||||
0:1 0:2 0:3 1:0 1:2 1:3 2:0 2:1 2:3 3:0 3:1 3:2
|
||||
|
||||
task ex4
|
||||
nodes: 8, edges: 12, colours: 2
|
||||
1-6 7-1 8-1 5-2 2-7 2-8 3-5 6-3 3-8 4-5 4-6 4-7
|
||||
0:1 1:0 1:0 1:0 0:1 0:1 0:1 1:0 0:1 0:1 0:1 0:1
|
||||
37
Task/Graph-colouring/J/graph-colouring-3.j
Normal file
37
Task/Graph-colouring/J/graph-colouring-3.j
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
anneal=: {{
|
||||
best=. i.#y [ cost=. #~.greedy y
|
||||
for.i.#y do.
|
||||
o=. ?~#y
|
||||
c=.#~.greedy o ([ { {"1) y
|
||||
if. cost > c do.
|
||||
best=. o [ cost=. c
|
||||
end.
|
||||
end.
|
||||
(/:best) { greedy best ([ { {"1) y
|
||||
}}
|
||||
task=: {{
|
||||
colors=. anneal parse y
|
||||
echo'nodes: %d, edges: %d, colours: %d' sprintf #each graph;ref;~.colors
|
||||
edgecolors=. <@(,&":':',&":])/"1(>labels i.L:1 ref){colors
|
||||
,./>' ',.~each^:2(cut y),:each edgecolors
|
||||
}}
|
||||
|
||||
task ex1
|
||||
nodes: 4, edges: 4, colours: 3
|
||||
0-1 1-2 2-0 3
|
||||
0:1 1:2 2:0 0:0
|
||||
|
||||
task ex2
|
||||
nodes: 8, edges: 12, colours: 2
|
||||
1-6 1-7 1-8 2-5 2-7 2-8 3-5 3-6 3-8 4-5 4-6 4-7
|
||||
0:1 0:1 0:1 0:1 0:1 0:1 0:1 0:1 0:1 0:1 0:1 0:1
|
||||
|
||||
task ex3
|
||||
nodes: 8, edges: 12, colours: 2
|
||||
1-4 1-6 1-8 3-2 3-6 3-8 5-2 5-4 5-8 7-2 7-4 7-6
|
||||
0:1 0:1 0:1 0:1 0:1 0:1 0:1 0:1 0:1 0:1 0:1 0:1
|
||||
|
||||
task ex4
|
||||
nodes: 8, edges: 12, colours: 2
|
||||
1-6 7-1 8-1 5-2 2-7 2-8 3-5 6-3 3-8 4-5 4-6 4-7
|
||||
0:1 1:0 1:0 1:0 0:1 0:1 0:1 1:0 0:1 0:1 0:1 0:1
|
||||
104
Task/Graph-colouring/Julia/graph-colouring.julia
Normal file
104
Task/Graph-colouring/Julia/graph-colouring.julia
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
using Random
|
||||
|
||||
"""Useful constants for the colors to be selected for nodes of the graph"""
|
||||
const colors4 = ["blue", "red", "green", "yellow"]
|
||||
const badcolor = "black"
|
||||
@assert(!(badcolor in colors4))
|
||||
|
||||
"""
|
||||
struct graph
|
||||
|
||||
undirected simple graph
|
||||
constructed from its name and a string listing of point to point connections
|
||||
"""
|
||||
mutable struct Graph
|
||||
name::String
|
||||
g::Dict{Int, Vector{Int}}
|
||||
nodecolor::Dict{Int, String}
|
||||
function Graph(nam::String, s::String)
|
||||
gdic = Dict{Int, Vector{Int}}()
|
||||
for p in eachmatch(r"(\d+)-(\d+)|(\d+)(?!\s*-)" , s)
|
||||
if p != nothing
|
||||
if p[3] != nothing
|
||||
n3 = parse(Int, p[3])
|
||||
get!(gdic, n3, [])
|
||||
else
|
||||
n1, n2 = parse(Int, p[1]), parse(Int, p[2])
|
||||
p1vec = get!(gdic, n1, [])
|
||||
!(n2 in p1vec) && push!(p1vec, n2)
|
||||
p2vec = get!(gdic, n2, [])
|
||||
!(n1 in p2vec) && push!(p2vec, n1)
|
||||
end
|
||||
end
|
||||
end
|
||||
new(nam, gdic, Dict{Int, String}())
|
||||
end
|
||||
end
|
||||
|
||||
"""
|
||||
tryNcolors!(gr::Graph, N, maxtrials)
|
||||
|
||||
Try up to maxtrials to get a coloring with <= N colors
|
||||
"""
|
||||
function tryNcolors!(gr::Graph, N, maxtrials)
|
||||
t, mintrial, minord = N, N + 1, Dict()
|
||||
for _ in 1:maxtrials
|
||||
empty!(gr.nodecolor)
|
||||
ordering = shuffle(collect(keys(gr.g)))
|
||||
for node in ordering
|
||||
usedneighborcolors = [gr.nodecolor[c] for c in gr.g[node] if haskey(gr.nodecolor, c)]
|
||||
gr.nodecolor[node] = badcolor
|
||||
for c in colors4[1:N]
|
||||
if !(c in usedneighborcolors)
|
||||
gr.nodecolor[node] = c
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
t = length(unique(values(gr.nodecolor)))
|
||||
if t < mintrial
|
||||
mintrial = t
|
||||
minord = deepcopy(gr.nodecolor)
|
||||
end
|
||||
end
|
||||
if length(minord) > 0
|
||||
gr.nodecolor = minord
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
"""
|
||||
prettyprintcolors(gr::graph)
|
||||
|
||||
print out the colored nodes in graph
|
||||
"""
|
||||
function prettyprintcolors(gr::Graph)
|
||||
println("\nColors for the graph named ", gr.name, ":")
|
||||
edgesdone = Vector{Vector{Int}}()
|
||||
for (node, neighbors) in gr.g
|
||||
if !isempty(neighbors)
|
||||
for n in neighbors
|
||||
edge = node < n ? [node, n] : [n, node]
|
||||
if !(edge in edgesdone)
|
||||
println(" ", edge[1], "-", edge[2], " Color: ",
|
||||
gr.nodecolor[edge[1]], ", ", gr.nodecolor[edge[2]])
|
||||
push!(edgesdone, edge)
|
||||
end
|
||||
end
|
||||
else
|
||||
println(" ", node, ": ", gr.nodecolor[node])
|
||||
end
|
||||
end
|
||||
println("\n", length(unique(keys(gr.nodecolor))), " nodes, ",
|
||||
length(edgesdone), " edges, ",
|
||||
length(unique(values(gr.nodecolor))), " colors.")
|
||||
end
|
||||
|
||||
for (name, txt) in [("Ex1", "0-1 1-2 2-0 3"),
|
||||
("Ex2", "1-6 1-7 1-8 2-5 2-7 2-8 3-5 3-6 3-8 4-5 4-6 4-7"),
|
||||
("Ex3", "1-4 1-6 1-8 3-2 3-6 3-8 5-2 5-4 5-8 7-2 7-4 7-6"),
|
||||
("Ex4", "1-6 7-1 8-1 5-2 2-7 2-8 3-5 6-3 3-8 4-5 4-6 4-7")]
|
||||
exgraph = Graph(name, txt)
|
||||
tryNcolors!(exgraph, 4, 100)
|
||||
prettyprintcolors(exgraph)
|
||||
end
|
||||
35
Task/Graph-colouring/Mathematica/graph-colouring.math
Normal file
35
Task/Graph-colouring/Mathematica/graph-colouring.math
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
ClearAll[ColorGroups]
|
||||
ColorGroups[g_Graph] := Module[{h, cols, indset, diffcols},
|
||||
h = g;
|
||||
cols = {};
|
||||
While[! EmptyGraphQ[h], maxd = RandomChoice[VertexList[h]];
|
||||
indset = Flatten[FindIndependentVertexSet[{h, maxd}]];
|
||||
AppendTo[cols, indset];
|
||||
h = VertexDelete[h, indset];
|
||||
];
|
||||
AppendTo[cols, VertexList[h]];
|
||||
diffcols = Length[cols];
|
||||
cols = Catenate[Map[Thread][Rule @@@ Transpose[{cols, Range[Length[cols]]}]]];
|
||||
Print[Column[Row[{"Edge ", #1, " to ", #2, " has colors ", #1 /. cols, " and ", #2 /. cols }] & @@@ EdgeList[g]]];
|
||||
Print[Grid[{{"Vertices: ", VertexCount[g]}, {"Edges: ", EdgeCount[g]}, {"Colors used: ", diffcols}}]]
|
||||
]
|
||||
ColorGroups[Graph[Range[0, 3], {0 \[UndirectedEdge] 1, 1 \[UndirectedEdge] 2,
|
||||
2 \[UndirectedEdge] 0}]]
|
||||
ColorGroups[Graph[Range[8], {1 \[UndirectedEdge] 6, 1 \[UndirectedEdge] 7,
|
||||
1 \[UndirectedEdge] 8, 2 \[UndirectedEdge] 5,
|
||||
2 \[UndirectedEdge] 7, 2 \[UndirectedEdge] 8,
|
||||
3 \[UndirectedEdge] 5, 3 \[UndirectedEdge] 6,
|
||||
3 \[UndirectedEdge] 8, 4 \[UndirectedEdge] 5,
|
||||
4 \[UndirectedEdge] 6, 4 \[UndirectedEdge] 7}]]
|
||||
ColorGroups[Graph[Range[8], {1 \[UndirectedEdge] 4, 1 \[UndirectedEdge] 6,
|
||||
1 \[UndirectedEdge] 8, 3 \[UndirectedEdge] 2,
|
||||
3 \[UndirectedEdge] 6, 3 \[UndirectedEdge] 8,
|
||||
5 \[UndirectedEdge] 2, 5 \[UndirectedEdge] 4,
|
||||
5 \[UndirectedEdge] 8, 7 \[UndirectedEdge] 2,
|
||||
7 \[UndirectedEdge] 4, 7 \[UndirectedEdge] 6}]]
|
||||
ColorGroups[Graph[Range[8], {1 \[UndirectedEdge] 6, 7 \[UndirectedEdge] 1,
|
||||
8 \[UndirectedEdge] 1, 5 \[UndirectedEdge] 2,
|
||||
2 \[UndirectedEdge] 7, 2 \[UndirectedEdge] 8,
|
||||
3 \[UndirectedEdge] 5, 6 \[UndirectedEdge] 3,
|
||||
3 \[UndirectedEdge] 8, 4 \[UndirectedEdge] 5,
|
||||
4 \[UndirectedEdge] 6, 4 \[UndirectedEdge] 7}]]
|
||||
127
Task/Graph-colouring/Nim/graph-colouring.nim
Normal file
127
Task/Graph-colouring/Nim/graph-colouring.nim
Normal file
|
|
@ -0,0 +1,127 @@
|
|||
import algorithm, sequtils, strscans, strutils, tables
|
||||
|
||||
const NoColor = 0
|
||||
|
||||
type
|
||||
|
||||
Color = range[0..63]
|
||||
|
||||
Node = ref object
|
||||
num: Natural # Node number.
|
||||
color: Color # Node color.
|
||||
degree: Natural # Node degree.
|
||||
dsat: Natural # Node Dsaturation.
|
||||
neighbors: seq[Node] # List of neighbors.
|
||||
|
||||
Graph = seq[Node] # List of nodes ordered by number.
|
||||
|
||||
#---------------------------------------------------------------------------------------------------
|
||||
|
||||
proc initGraph(graphRepr: string): Graph =
|
||||
## Initialize the graph from its string representation.
|
||||
|
||||
var mapping: Table[Natural, Node] # Temporary mapping.
|
||||
for elem in graphRepr.splitWhitespace():
|
||||
var num1, num2: int
|
||||
if elem.scanf("$i-$i", num1, num2):
|
||||
let node1 = mapping.mgetOrPut(num1, Node(num: num1))
|
||||
let node2 = mapping.mgetOrPut(num2, Node(num: num2))
|
||||
node1.neighbors.add node2
|
||||
node2.neighbors.add node1
|
||||
elif elem.scanf("$i", num1):
|
||||
discard mapping.mgetOrPut(num1, Node(num: num1))
|
||||
else:
|
||||
raise newException(ValueError, "wrong description: " & elem)
|
||||
|
||||
for node in mapping.values:
|
||||
node.degree = node.neighbors.len
|
||||
result = sortedByIt(toSeq(mapping.values), it.num)
|
||||
|
||||
#---------------------------------------------------------------------------------------------------
|
||||
|
||||
proc numbers(nodes: seq[Node]): string =
|
||||
## Return the numbers of a list of nodes.
|
||||
for node in nodes:
|
||||
result.addSep(" ")
|
||||
result.add($node.num)
|
||||
|
||||
#---------------------------------------------------------------------------------------------------
|
||||
|
||||
proc `$`(graph: Graph): string =
|
||||
## Return the description of the graph.
|
||||
|
||||
var maxColor = NoColor
|
||||
for node in graph:
|
||||
stdout.write "Node ", node.num, ": color = ", node.color
|
||||
if node.color > maxColor: maxColor = node.color
|
||||
if node.neighbors.len > 0:
|
||||
echo " neighbors = ", sortedByIt(node.neighbors, it.num).numbers
|
||||
else:
|
||||
echo ""
|
||||
echo "Number of colors: ", maxColor
|
||||
|
||||
#---------------------------------------------------------------------------------------------------
|
||||
|
||||
proc `<`(node1, node2: Node): bool =
|
||||
## Comparison of nodes, by dsaturation first, then by degree.
|
||||
if node1.dsat == node2.dsat: node1.degree < node2.degree
|
||||
else: node1.dsat < node2.dsat
|
||||
|
||||
#---------------------------------------------------------------------------------------------------
|
||||
|
||||
proc getMaxDsatNode(nodes: var seq[Node]): Node =
|
||||
## Return the node with the greatest dsaturation.
|
||||
let idx = nodes.maxIndex()
|
||||
result = nodes[idx]
|
||||
nodes.delete(idx)
|
||||
|
||||
#---------------------------------------------------------------------------------------------------
|
||||
|
||||
proc minColor(node: Node): COLOR =
|
||||
## Return the minimum available color for a node.
|
||||
var colorUsed: set[Color]
|
||||
for neighbor in node.neighbors:
|
||||
colorUsed.incl neighbor.color
|
||||
for color in 1..Color.high:
|
||||
if color notin colorUsed: return color
|
||||
|
||||
#---------------------------------------------------------------------------------------------------
|
||||
|
||||
proc distinctColorsCount(node: Node): Natural =
|
||||
## Return the number of distinct colors of the neighbors of a node.
|
||||
var colorUsed: set[Color]
|
||||
for neighbor in node.neighbors:
|
||||
colorUsed.incl neighbor.color
|
||||
result = colorUsed.card
|
||||
|
||||
#---------------------------------------------------------------------------------------------------
|
||||
|
||||
proc updateDsats(node: Node) =
|
||||
## Update the dsaturations of the neighbors of a node.
|
||||
for neighbor in node.neighbors:
|
||||
if neighbor.color == NoColor:
|
||||
neighbor.dsat = neighbor.distinctColorsCount()
|
||||
|
||||
#---------------------------------------------------------------------------------------------------
|
||||
|
||||
proc colorize(graphRepr: string) =
|
||||
## Colorize a graph.
|
||||
|
||||
let graph = initGraph(graphRepr)
|
||||
var nodes = sortedByIt(graph, -it.degree) # Copy or graph sorted by decreasing degrees.
|
||||
while nodes.len > 0:
|
||||
let node = nodes.getMaxDsatNode()
|
||||
node.color = node.minColor()
|
||||
node.updateDsats()
|
||||
|
||||
echo "Graph: ", graphRepr
|
||||
echo graph
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------------------------------
|
||||
|
||||
when isMainModule:
|
||||
colorize("0-1 1-2 2-0 3")
|
||||
colorize("1-6 1-7 1-8 2-5 2-7 2-8 3-5 3-6 3-8 4-5 4-6 4-7")
|
||||
colorize("1-4 1-6 1-8 3-2 3-6 3-8 5-2 5-4 5-8 7-2 7-4 7-6")
|
||||
colorize("1-6 7-1 8-1 5-2 2-7 2-8 3-5 6-3 3-8 4-5 4-6 4-7")
|
||||
64
Task/Graph-colouring/Perl/graph-colouring.pl
Normal file
64
Task/Graph-colouring/Perl/graph-colouring.pl
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
use strict;
|
||||
use warnings;
|
||||
no warnings 'uninitialized';
|
||||
use feature 'say';
|
||||
use constant True => 1;
|
||||
use List::Util qw(head uniq);
|
||||
|
||||
sub GraphNodeColor {
|
||||
my(%OneMany, %NodeColor, %NodePool, @ColorPool);
|
||||
my(@data) = @_;
|
||||
|
||||
for (@data) {
|
||||
my($a,$b) = @$_;
|
||||
push @{$OneMany{$a}}, $b;
|
||||
push @{$OneMany{$b}}, $a;
|
||||
}
|
||||
|
||||
@ColorPool = 0 .. -1 + scalar %OneMany;
|
||||
$NodePool{$_} = True for keys %OneMany;
|
||||
|
||||
if ($OneMany{''}) { # skip islanders for now
|
||||
delete $NodePool{$_} for @{$OneMany{''}};
|
||||
delete $NodePool{''};
|
||||
}
|
||||
|
||||
while (%NodePool) {
|
||||
my $color = shift @ColorPool;
|
||||
my %TempPool = %NodePool;
|
||||
|
||||
while (my $n = head 1, sort keys %TempPool) {
|
||||
$NodeColor{$n} = $color;
|
||||
delete $TempPool{$n};
|
||||
delete $TempPool{$_} for @{$OneMany{$n}} ; # skip neighbors as well
|
||||
delete $NodePool{$n};
|
||||
}
|
||||
|
||||
if ($OneMany{''}) { # islanders use an existing color
|
||||
$NodeColor{$_} = head 1, sort values %NodeColor for @{$OneMany{''}};
|
||||
}
|
||||
}
|
||||
%NodeColor
|
||||
}
|
||||
|
||||
my @DATA = (
|
||||
[ [1,2],[2,3],[3,1],[4,undef],[5,undef],[6,undef] ],
|
||||
[ [1,6],[1,7],[1,8],[2,5],[2,7],[2,8],[3,5],[3,6],[3,8],[4,5],[4,6],[4,7] ],
|
||||
[ [1,4],[1,6],[1,8],[3,2],[3,6],[3,8],[5,2],[5,4],[5,8],[7,2],[7,4],[7,6] ],
|
||||
[ [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 my $d (@DATA) {
|
||||
my %result = GraphNodeColor @$d;
|
||||
|
||||
my($graph,$colors);
|
||||
$graph .= '(' . join(' ', @$_) . '), ' for @$d;
|
||||
$colors .= ' ' . $result{$$_[0]} . '-' . ($result{$$_[1]} // '') . ' ' for @$d;
|
||||
|
||||
say 'Graph : ' . $graph =~ s/,\s*$//r;
|
||||
say 'Colors : ' . $colors;
|
||||
say 'Nodes : ' . keys %result;
|
||||
say 'Edges : ' . @$d;
|
||||
say 'Unique : ' . uniq values %result;
|
||||
say '';
|
||||
}
|
||||
74
Task/Graph-colouring/Phix/graph-colouring.phix
Normal file
74
Task/Graph-colouring/Phix/graph-colouring.phix
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
(phixonline)-->
|
||||
<span style="color: #000080;font-style:italic;">-- demo\rosetta\Graph_colouring.exw</span>
|
||||
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
|
||||
<span style="color: #008080;">constant</span> <span style="color: #000000;">tests</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">split</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"""
|
||||
0-1 1-2 2-0 3
|
||||
1-6 1-7 1-8 2-5 2-7 2-8 3-5 3-6 3-8 4-5 4-6 4-7
|
||||
1-4 1-6 1-8 3-2 3-6 3-8 5-2 5-4 5-8 7-2 7-4 7-6
|
||||
1-6 7-1 8-1 5-2 2-7 2-8 3-5 6-3 3-8 4-5 4-6 4-7
|
||||
"""</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"\n"</span><span style="color: #0000FF;">,</span><span style="color: #004600;">true</span><span style="color: #0000FF;">)</span>
|
||||
|
||||
<span style="color: #008080;">function</span> <span style="color: #000000;">colour</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">nodes</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">links</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">colours</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">soln</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">best</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">next</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">used</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #000080;font-style:italic;">-- fill/try each colours[next], recursing as rqd and saving any improvements.
|
||||
-- nodes/links are read-only here, colours is the main workspace, soln/best are
|
||||
-- the results, next is 1..length(nodes), and used is length(unique(colours)).
|
||||
-- On really big graphs I might consider making nodes..best static, esp colours,
|
||||
-- in which case you will probably also want a "colours[next] = 0" reset below.</span>
|
||||
<span style="color: #004080;">integer</span> <span style="color: #000000;">c</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span>
|
||||
<span style="color: #000000;">colours</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">deep_copy</span><span style="color: #0000FF;">(</span><span style="color: #000000;">colours</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">while</span> <span style="color: #000000;">c</span><span style="color: #0000FF;"><</span><span style="color: #000000;">best</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #004080;">bool</span> <span style="color: #000000;">avail</span> <span style="color: #0000FF;">=</span> <span style="color: #004600;">true</span>
|
||||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">links</span><span style="color: #0000FF;">[</span><span style="color: #000000;">next</span><span style="color: #0000FF;">])</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #000000;">colours</span><span style="color: #0000FF;">[</span><span style="color: #000000;">links</span><span style="color: #0000FF;">[</span><span style="color: #000000;">next</span><span style="color: #0000FF;">][</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]]==</span><span style="color: #000000;">c</span> <span style="color: #008080;">then</span>
|
||||
<span style="color: #000000;">avail</span> <span style="color: #0000FF;">=</span> <span style="color: #004600;">false</span>
|
||||
<span style="color: #008080;">exit</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #000000;">avail</span> <span style="color: #008080;">then</span>
|
||||
<span style="color: #000000;">colours</span><span style="color: #0000FF;">[</span><span style="color: #000000;">next</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">c</span>
|
||||
<span style="color: #004080;">integer</span> <span style="color: #000000;">newused</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">used</span> <span style="color: #0000FF;">+</span> <span style="color: #0000FF;">(</span><span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #000000;">c</span><span style="color: #0000FF;">,</span><span style="color: #000000;">colours</span><span style="color: #0000FF;">)==</span><span style="color: #000000;">next</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #000000;">next</span><span style="color: #0000FF;"><</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">nodes</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span>
|
||||
<span style="color: #0000FF;">{</span><span style="color: #000000;">best</span><span style="color: #0000FF;">,</span><span style="color: #000000;">soln</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">colour</span><span style="color: #0000FF;">(</span><span style="color: #000000;">nodes</span><span style="color: #0000FF;">,</span><span style="color: #000000;">links</span><span style="color: #0000FF;">,</span><span style="color: #000000;">colours</span><span style="color: #0000FF;">,</span><span style="color: #000000;">soln</span><span style="color: #0000FF;">,</span><span style="color: #000000;">best</span><span style="color: #0000FF;">,</span><span style="color: #000000;">next</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">newused</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">elsif</span> <span style="color: #000000;">newused</span><span style="color: #0000FF;"><</span><span style="color: #000000;">best</span> <span style="color: #008080;">then</span>
|
||||
<span style="color: #0000FF;">{</span><span style="color: #000000;">best</span><span style="color: #0000FF;">,</span><span style="color: #000000;">soln</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">newused</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">deep_copy</span><span style="color: #0000FF;">(</span><span style="color: #000000;">colours</span><span style="color: #0000FF;">)}</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #000000;">c</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
|
||||
<span style="color: #008080;">return</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">best</span><span style="color: #0000FF;">,</span><span style="color: #000000;">soln</span><span style="color: #0000FF;">}</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
|
||||
|
||||
<span style="color: #008080;">function</span> <span style="color: #000000;">add_node</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">nodes</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">links</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">string</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #004080;">integer</span> <span style="color: #000000;">rdx</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">,</span><span style="color: #000000;">nodes</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #000000;">rdx</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
|
||||
<span style="color: #000000;">nodes</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">nodes</span><span style="color: #0000FF;">,</span><span style="color: #000000;">n</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #000000;">links</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">links</span><span style="color: #0000FF;">,{})</span>
|
||||
<span style="color: #000000;">rdx</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">nodes</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #008080;">return</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">nodes</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">links</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">rdx</span><span style="color: #0000FF;">}</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
|
||||
|
||||
<span style="color: #008080;">for</span> <span style="color: #000000;">t</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tests</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #004080;">string</span> <span style="color: #000000;">tt</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">tests</span><span style="color: #0000FF;">[</span><span style="color: #000000;">t</span><span style="color: #0000FF;">]</span>
|
||||
<span style="color: #004080;">sequence</span> <span style="color: #000000;">lt</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">split</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tt</span><span style="color: #0000FF;">,</span><span style="color: #008000;">" "</span><span style="color: #0000FF;">),</span>
|
||||
<span style="color: #000000;">nodes</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{},</span>
|
||||
<span style="color: #000000;">links</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span>
|
||||
<span style="color: #004080;">integer</span> <span style="color: #000000;">linkcount</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">left</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">right</span>
|
||||
<span style="color: #008080;">for</span> <span style="color: #000000;">l</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">lt</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #004080;">sequence</span> <span style="color: #000000;">ll</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">split</span><span style="color: #0000FF;">(</span><span style="color: #000000;">lt</span><span style="color: #0000FF;">[</span><span style="color: #000000;">l</span><span style="color: #0000FF;">],</span><span style="color: #008000;">"-"</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #0000FF;">{</span><span style="color: #000000;">nodes</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">links</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">left</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">add_node</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">deep_copy</span><span style="color: #0000FF;">(</span><span style="color: #000000;">nodes</span><span style="color: #0000FF;">),</span><span style="color: #7060A8;">deep_copy</span><span style="color: #0000FF;">(</span><span style="color: #000000;">links</span><span style="color: #0000FF;">),</span><span style="color: #000000;">ll</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">])</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ll</span><span style="color: #0000FF;">)=</span><span style="color: #000000;">2</span> <span style="color: #008080;">then</span>
|
||||
<span style="color: #0000FF;">{</span><span style="color: #000000;">nodes</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">links</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">right</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">add_node</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">deep_copy</span><span style="color: #0000FF;">(</span><span style="color: #000000;">nodes</span><span style="color: #0000FF;">),</span><span style="color: #7060A8;">deep_copy</span><span style="color: #0000FF;">(</span><span style="color: #000000;">links</span><span style="color: #0000FF;">),</span><span style="color: #000000;">ll</span><span style="color: #0000FF;">[</span><span style="color: #000000;">2</span><span style="color: #0000FF;">])</span>
|
||||
<span style="color: #000000;">links</span><span style="color: #0000FF;">[</span><span style="color: #000000;">left</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">deep_copy</span><span style="color: #0000FF;">(</span><span style="color: #000000;">links</span><span style="color: #0000FF;">[</span><span style="color: #000000;">left</span><span style="color: #0000FF;">])&</span><span style="color: #000000;">right</span>
|
||||
<span style="color: #000000;">links</span><span style="color: #0000FF;">[</span><span style="color: #000000;">right</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">deep_copy</span><span style="color: #0000FF;">(</span><span style="color: #000000;">links</span><span style="color: #0000FF;">[</span><span style="color: #000000;">right</span><span style="color: #0000FF;">])&</span><span style="color: #000000;">left</span>
|
||||
<span style="color: #000000;">linkcount</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
|
||||
<span style="color: #004080;">integer</span> <span style="color: #000000;">ln</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">nodes</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"test%d: %d nodes, %d edges, "</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">t</span><span style="color: #0000FF;">,</span><span style="color: #000000;">ln</span><span style="color: #0000FF;">,</span><span style="color: #000000;">linkcount</span><span style="color: #0000FF;">})</span>
|
||||
<span style="color: #004080;">sequence</span> <span style="color: #000000;">colours</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">ln</span><span style="color: #0000FF;">),</span>
|
||||
<span style="color: #000000;">soln</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">tagset</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ln</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- fallback solution</span>
|
||||
<span style="color: #004080;">integer</span> <span style="color: #000000;">next</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">best</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">ln</span>
|
||||
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%d colours:%v\n"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">colour</span><span style="color: #0000FF;">(</span><span style="color: #000000;">nodes</span><span style="color: #0000FF;">,</span><span style="color: #000000;">links</span><span style="color: #0000FF;">,</span><span style="color: #000000;">colours</span><span style="color: #0000FF;">,</span><span style="color: #000000;">soln</span><span style="color: #0000FF;">,</span><span style="color: #000000;">best</span><span style="color: #0000FF;">,</span><span style="color: #000000;">next</span><span style="color: #0000FF;">))</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
|
||||
<!--
|
||||
73
Task/Graph-colouring/Python/graph-colouring.py
Normal file
73
Task/Graph-colouring/Python/graph-colouring.py
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
import re
|
||||
from collections import defaultdict
|
||||
from itertools import count
|
||||
|
||||
|
||||
connection_re = r"""
|
||||
(?: (?P<N1>\d+) - (?P<N2>\d+) | (?P<N>\d+) (?!\s*-))
|
||||
"""
|
||||
|
||||
class Graph:
|
||||
|
||||
def __init__(self, name, connections):
|
||||
self.name = name
|
||||
self.connections = connections
|
||||
g = self.graph = defaultdict(list) # maps vertex to direct connections
|
||||
|
||||
matches = re.finditer(connection_re, connections,
|
||||
re.MULTILINE | re.VERBOSE)
|
||||
for match in matches:
|
||||
n1, n2, n = match.groups()
|
||||
if n:
|
||||
g[n] += []
|
||||
else:
|
||||
g[n1].append(n2) # Each the neighbour of the other
|
||||
g[n2].append(n1)
|
||||
|
||||
def greedy_colour(self, order=None):
|
||||
"Greedy colourisation algo."
|
||||
if order is None:
|
||||
order = self.graph # Choose something
|
||||
colour = self.colour = {}
|
||||
neighbours = self.graph
|
||||
for node in order:
|
||||
used_neighbour_colours = (colour[nbr] for nbr in neighbours[node]
|
||||
if nbr in colour)
|
||||
colour[node] = first_avail_int(used_neighbour_colours)
|
||||
self.pp_colours()
|
||||
return colour
|
||||
|
||||
def pp_colours(self):
|
||||
print(f"\n{self.name}")
|
||||
c = self.colour
|
||||
e = canonical_edges = set()
|
||||
for n1, neighbours in sorted(self.graph.items()):
|
||||
if neighbours:
|
||||
for n2 in neighbours:
|
||||
edge = tuple(sorted([n1, n2]))
|
||||
if edge not in canonical_edges:
|
||||
print(f" {n1}-{n2}: Colour: {c[n1]}, {c[n2]}")
|
||||
canonical_edges.add(edge)
|
||||
else:
|
||||
print(f" {n1}: Colour: {c[n1]}")
|
||||
lc = len(set(c.values()))
|
||||
print(f" #Nodes: {len(c)}\n #Edges: {len(e)}\n #Colours: {lc}")
|
||||
|
||||
|
||||
def first_avail_int(data):
|
||||
"return lowest int 0... not in data"
|
||||
d = set(data)
|
||||
for i in count():
|
||||
if i not in d:
|
||||
return i
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
for name, connections in [
|
||||
('Ex1', "0-1 1-2 2-0 3"),
|
||||
('Ex2', "1-6 1-7 1-8 2-5 2-7 2-8 3-5 3-6 3-8 4-5 4-6 4-7"),
|
||||
('Ex3', "1-4 1-6 1-8 3-2 3-6 3-8 5-2 5-4 5-8 7-2 7-4 7-6"),
|
||||
('Ex4', "1-6 7-1 8-1 5-2 2-7 2-8 3-5 6-3 3-8 4-5 4-6 4-7"),
|
||||
]:
|
||||
g = Graph(name, connections)
|
||||
g.greedy_colour()
|
||||
38
Task/Graph-colouring/Raku/graph-colouring.raku
Normal file
38
Task/Graph-colouring/Raku/graph-colouring.raku
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
sub GraphNodeColor(@RAW) {
|
||||
my %OneMany = my %NodeColor;
|
||||
for @RAW { %OneMany{$_[0]}.push: $_[1] ; %OneMany{$_[1]}.push: $_[0] }
|
||||
my @ColorPool = "0", "1" … ^+%OneMany.elems; # as string
|
||||
my %NodePool = %OneMany.BagHash; # this DWIM is nice
|
||||
if %OneMany<NaN>:exists { %NodePool{$_}:delete for %OneMany<NaN>, NaN } # pending
|
||||
while %NodePool.Bool {
|
||||
my $color = @ColorPool.shift;
|
||||
my %TempPool = %NodePool;
|
||||
while (my \n = %TempPool.keys.sort.first) {
|
||||
%NodeColor{n} = $color;
|
||||
%TempPool{n}:delete;
|
||||
%TempPool{$_}:delete for @(%OneMany{n}) ; # skip neighbors as well
|
||||
%NodePool{n}:delete;
|
||||
}
|
||||
}
|
||||
if %OneMany<NaN>:exists { # islanders use an existing color
|
||||
%NodeColor{$_} = %NodeColor.values.sort.first for @(%OneMany<NaN>)
|
||||
}
|
||||
return %NodeColor
|
||||
}
|
||||
|
||||
my \DATA = [
|
||||
[<0 1>,<1 2>,<2 0>,<3 NaN>,<4 NaN>,<5 NaN>],
|
||||
[<1 6>,<1 7>,<1 8>,<2 5>,<2 7>,<2 8>,<3 5>,<3 6>,<3 8>,<4 5>,<4 6>,<4 7>],
|
||||
[<1 4>,<1 6>,<1 8>,<3 2>,<3 6>,<3 8>,<5 2>,<5 4>,<5 8>,<7 2>,<7 4>,<7 6>],
|
||||
[<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 DATA {
|
||||
say "DATA : ", $_;
|
||||
say "Result : ";
|
||||
my %out = GraphNodeColor $_;
|
||||
say "$_[0]-$_[1]:\t Color %out{$_[0]} ",$_[1].isNaN??''!!%out{$_[1]} for @$_;
|
||||
say "Nodes : ", %out.keys.elems;
|
||||
say "Edges : ", $_.elems;
|
||||
say "Colors : ", %out.values.Set.elems;
|
||||
}
|
||||
150
Task/Graph-colouring/Wren/graph-colouring.wren
Normal file
150
Task/Graph-colouring/Wren/graph-colouring.wren
Normal file
|
|
@ -0,0 +1,150 @@
|
|||
import "/dynamic" for Struct
|
||||
import "/sort" for Sort
|
||||
import "/fmt" for Fmt
|
||||
|
||||
// (n)umber of node and its (v)alence i.e. number of neighbors
|
||||
var NodeVal = Struct.create("NodeVal", ["n", "v"])
|
||||
|
||||
class Graph {
|
||||
construct new(nn, st) {
|
||||
_nn = nn // number of nodes
|
||||
_st = st // node numbering starts from
|
||||
_nbr = List.filled(nn, null) // neighbor list for each node
|
||||
for (i in 0...nn) _nbr[i] = []
|
||||
}
|
||||
|
||||
nn { _nn }
|
||||
st { _st }
|
||||
|
||||
// Note that this creates a single 'virtual' edge for an isolated node.
|
||||
addEdge(n1, n2) {
|
||||
// adjust to starting node number
|
||||
n1 = n1 - _st
|
||||
n2 = n2 - _st
|
||||
_nbr[n1].add(n2)
|
||||
if (n1 != n2) _nbr[n2].add(n1)
|
||||
}
|
||||
|
||||
// Uses 'greedy' algorithm.
|
||||
greedyColoring {
|
||||
// create a list with a color for each node
|
||||
var cols = List.filled(_nn, -1) // -1 denotes no color assigned
|
||||
cols[0] = 0 // first node assigned color 0
|
||||
// create a bool list to keep track of which colors are available
|
||||
var available = List.filled(_nn, false)
|
||||
// assign colors to all nodes after the first
|
||||
for (i in 1..._nn) {
|
||||
// iterate through neighbors and mark their colors as available
|
||||
for (j in _nbr[i]) {
|
||||
if (cols[j] != -1) available[cols[j]] = true
|
||||
}
|
||||
// find the first available color
|
||||
var c = available.indexOf(false)
|
||||
cols[i] = c // assign it to the current node
|
||||
// reset the neighbors' colors to unavailable
|
||||
// before the next iteration
|
||||
for (j in _nbr[i]) {
|
||||
if (cols[j] != -1) available[cols[j]] = false
|
||||
}
|
||||
}
|
||||
return cols
|
||||
}
|
||||
|
||||
// Uses Welsh-Powell algorithm.
|
||||
wpColoring {
|
||||
// create NodeVal for each node
|
||||
var nvs = List.filled(_nn, null)
|
||||
for (i in 0..._nn) {
|
||||
var v = _nbr[i].count
|
||||
if (v == 1 && _nbr[i][0] == i) { // isolated node
|
||||
v = 0
|
||||
}
|
||||
nvs[i] = NodeVal.new(i, v)
|
||||
}
|
||||
// sort the NodeVals in descending order by valence
|
||||
var cmp = Fn.new { |nv1, nv2| (nv2.v - nv1.v).sign }
|
||||
Sort.insertion(nvs, cmp) // stable sort
|
||||
|
||||
// create colors list with entries for each node
|
||||
var cols = List.filled(_nn, -1) // set all nodes to no color (-1) initially
|
||||
var currCol = 0 // start with color 0
|
||||
for (f in 0..._nn-1) {
|
||||
var 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
|
||||
var i = f + 1
|
||||
while (i < _nn) {
|
||||
var outer = false
|
||||
var j = nvs[i].n
|
||||
if (cols[j] != -1) { // already colored
|
||||
i = i + 1
|
||||
continue
|
||||
}
|
||||
var k = f
|
||||
while (k < i) {
|
||||
var l = nvs[k].n
|
||||
if (cols[l] == -1) { // not yet colored
|
||||
k = k + 1
|
||||
continue
|
||||
}
|
||||
if (_nbr[j].contains(l)) {
|
||||
outer = true
|
||||
break // node j is connected to an earlier colored node
|
||||
}
|
||||
k = k + 1
|
||||
}
|
||||
if (!outer) cols[j] = currCol
|
||||
i = i + 1
|
||||
}
|
||||
currCol = currCol + 1
|
||||
}
|
||||
return cols
|
||||
}
|
||||
}
|
||||
|
||||
var fns = [Fn.new { |g| g.greedyColoring }, Fn.new { |g| g.wpColoring }]
|
||||
var titles = ["'Greedy'", "Welsh-Powell"]
|
||||
var nns = [4, 8, 8, 8]
|
||||
var starts = [0, 1, 1, 1]
|
||||
var edges1 = [[0, 1], [1, 2], [2, 0], [3, 3]]
|
||||
var edges2 = [[1, 6], [1, 7], [1, 8], [2, 5], [2, 7], [2, 8],
|
||||
[3, 5], [3, 6], [3, 8], [4, 5], [4, 6], [4, 7]]
|
||||
var edges3 = [[1, 4], [1, 6], [1, 8], [3, 2], [3, 6], [3, 8],
|
||||
[5, 2], [5, 4], [5, 8], [7, 2], [7, 4], [7, 6]]
|
||||
var edges4 = [[1, 6], [7, 1], [8, 1], [5, 2], [2, 7], [2, 8],
|
||||
[3, 5], [6, 3], [3, 8], [4, 5], [4, 6], [4, 7]]
|
||||
var j = 0
|
||||
for (fn in fns) {
|
||||
System.print("Using the %(titles[j]) algorithm:\n")
|
||||
var i = 0
|
||||
for (edges in [edges1, edges2, edges3, edges4]) {
|
||||
System.print(" Example %(i+1)")
|
||||
var g = Graph.new(nns[i], starts[i])
|
||||
for (e in edges) g.addEdge(e[0], e[1])
|
||||
var cols = fn.call(g)
|
||||
var ecount = 0 // counts edges
|
||||
for (e in edges) {
|
||||
if (e[0] != e[1]) {
|
||||
Fmt.print(" Edge $d-$d -> Color $d, $d", e[0], e[1],
|
||||
cols[e[0]-g.st], cols[e[1]-g.st])
|
||||
ecount = ecount + 1
|
||||
} else {
|
||||
Fmt.print(" Node $d -> Color $d\n", e[0], cols[e[0]-g.st])
|
||||
}
|
||||
}
|
||||
var maxCol = 0 // maximum color number used
|
||||
for (col in cols) {
|
||||
if (col > maxCol) maxCol = col
|
||||
}
|
||||
System.print(" Number of nodes : %(nns[i])")
|
||||
System.print(" Number of edges : %(ecount)")
|
||||
System.print(" Number of colors : %(maxCol+1)")
|
||||
System.print()
|
||||
i = i + 1
|
||||
}
|
||||
j = j + 1
|
||||
}
|
||||
19
Task/Graph-colouring/Zkl/graph-colouring-1.zkl
Normal file
19
Task/Graph-colouring/Zkl/graph-colouring-1.zkl
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
fcn colorGraph(nodeStr){ // "0-1 1-2 2-0 3"
|
||||
numEdges,graph := 0,Dictionary(); // ( 0:(1,2), 1:L(0,2), 2:(1,0), 3:() )
|
||||
foreach n in (nodeStr.split(" ")){ // parse string to graph
|
||||
n=n - " ";
|
||||
if(n.holds("-")){
|
||||
a,b := n.split("-"); // keep as string
|
||||
graph.appendV(a,b); graph.appendV(b,a);
|
||||
numEdges+=1;
|
||||
}
|
||||
else graph[n]=T; // island
|
||||
}
|
||||
colors,colorPool := Dictionary(), ["A".."Z"].walk();
|
||||
graph.pump(Void,'wrap([(node,nbrs)]){ // ( "1",(0,2), "3",() )
|
||||
clrs:=colorPool.copy(); // all colors are available, then remove neighbours
|
||||
foreach i in (nbrs){ clrs.remove(colors.find(i)) } // if nbr has color, color not available
|
||||
colors[node] = clrs[0]; // first available remaining color
|
||||
});
|
||||
return(graph,colors,numEdges)
|
||||
}
|
||||
18
Task/Graph-colouring/Zkl/graph-colouring-2.zkl
Normal file
18
Task/Graph-colouring/Zkl/graph-colouring-2.zkl
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
fcn printColoredGraph(graphStr){
|
||||
graph,colors,numEdges := colorGraph(graphStr);
|
||||
nodes:=graph.keys.sort();
|
||||
println("Graph: ",graphStr);
|
||||
println("Node/color: ",
|
||||
nodes.pump(List,'wrap(v){ String(v,"/",colors[v]) }).concat(", "));
|
||||
println("Node : neighbours --> colors:");
|
||||
foreach node in (nodes){
|
||||
ns:=graph[node];
|
||||
println(node," : ",ns.concat(" ")," --> ",
|
||||
colors[node]," : ",ns.apply(colors.get).concat(" "));
|
||||
}
|
||||
println("Number nodes: ",nodes.len());
|
||||
println("Number edges: ",numEdges);
|
||||
println("Number colors: ",
|
||||
colors.values.pump(Dictionary().add.fp1(Void)).len()); // create set, count
|
||||
println();
|
||||
}
|
||||
7
Task/Graph-colouring/Zkl/graph-colouring-3.zkl
Normal file
7
Task/Graph-colouring/Zkl/graph-colouring-3.zkl
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
graphs:=T(
|
||||
"0-1 1-2 2-0 3",
|
||||
"1-6 1-7 1-8 2-5 2-7 2-8 3-5 3-6 3-8 4-5 4-6 4-7",
|
||||
"1-4 1-6 1-8 3-2 3-6 3-8 5-2 5-4 5-8 7-2 7-4 7-6",
|
||||
"1-6 7-1 8-1 5-2 2-7 2-8 3-5 6-3 3-8 4-5 4-6 4-7"
|
||||
);
|
||||
graphs.apply2(printColoredGraph);
|
||||
Loading…
Add table
Add a link
Reference in a new issue