Initial data commit
This commit is contained in:
parent
72d218235f
commit
f23f22d71c
199087 changed files with 3378941 additions and 0 deletions
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")
|
||||
Loading…
Add table
Add a link
Reference in a new issue