Skip to content
Commits on Source (1)
......@@ -206,13 +206,13 @@ The greedy 'Welsh and Powell' algorithm will find a solution of about 300 colors
A objective/neighbourhood strategy is used, that is conservative on using colors. Instead of starting with `K` colors, and use annealing to get to `K - 1` colors, we start with only using a few colors, and only add a color after a threshold `vertices/color` is obtained.
The rational is that it is difficult to put the 'devil back in the box', but the idea is not tested properly against a more general sum of squares of color classes, which start with `K` colors and try to reduce the number of colors.
The rational behind is that it is difficult to put the 'devil back in the box', where the devil in this analogy is the color you want to get rid off.
This method requires that the number of maximum colors used is fixed at the start, and in our example we aim for 250.
Annealing color by color gives more room to move around, but this idea is not tested properly against a more general sum of squares of color classes, which start with `K` colors and try to reduce the number of colors.
We use `O_stop=0` to stop the annealing when an colering has been found, a stopping criterea on the Objective function.
This method requires that the number of maximum colors used is fixed at the start, and in the example below we aim for 250.
The goal number of colors for example below is set to 250.
We use `O_stop=0` to stop the annealing when an colering has been found, a stopping criterea on the Objective function.
```
import frigidum
......@@ -239,10 +239,3 @@ local_opt = frigidum.sa(random_start=gcp.random_start,
repeats=10**2)
```
## To-Do:
- Re-Annealing, `R` times, back to temperature `T_reanneal`.
- Check that neighbours done modify the state in place.
- (loosely) check that used copy method indeed copies the state.
......@@ -47,6 +47,8 @@ vertices_degree = np.sum( edges_matrix, axis = 1 )
goal_number_of_colors = 250
goal_average = edges_matrix[0].size / goal_number_of_colors
class_exponent = 1.5
"""
Strategy:
......@@ -157,6 +159,38 @@ def partial_welsh_and_powell(C):
return colors[:active_color]
def partial_dsatur(C):
C = C.copy()
colored_vertices = np.any( C,axis=0 )
uncolored_vertices = np.nonzero( ~colored_vertices )[0]
saturation = np.array([ np.sum( np.any( C[ :, edges_matrix[u] ] ,axis=1) ) for u in uncolored_vertices ])
degree = vertices_degree[ uncolored_vertices ]
ordered_by_sat = np.argsort( - saturation - degree/(C.shape[1] + 1) )
need_to_color = np.repeat(True, uncolored_vertices.size)
while( np.any(need_to_color) ):
vertex_to_color = uncolored_vertices[ ordered_by_sat ][need_to_color[ordered_by_sat]][0]
colors_available = np.nonzero( [ np.all( ~edges_matrix[ c,vertex_to_color ] ) for c in C ] )[0]
if colors_available.size > 0 :
color_weights = 1 + np.sum( C[ colors_available, :] ,axis=1)**2
weights = color_weights / np.sum(color_weights)
random_color = np.random.choice( colors_available, p=weights)
C[random_color,vertex_to_color] = True
need_to_color[uncolored_vertices == vertex_to_color] = False
else:
need_to_color[uncolored_vertices == vertex_to_color] = False
return C
def random_start():
W = welsh_and_powell()
C = W[ np.flip(np.argsort( np.sum(W,axis=1) ) )]
......@@ -360,6 +394,7 @@ def check_average_and_add_row(C):
colored = np.sum(C)
if average_vertices >= goal_average and colored < C.shape[1]:
new_color = np.repeat( False, C.shape[1] )
colored_vertices = np.any( C,axis=0 )
uncolored_vertex = np.random.choice( np.nonzero(~colored_vertices)[0] )
......@@ -381,14 +416,18 @@ def check_valid_coloring(C):
def squared_sum_of_classes(C):
clean_unused_colors(C)
sum_of_squared_classes = np.sum( np.sum(C,axis=1)**2 )
sum_of_squared_classes = np.sum( np.sum(C,axis=1)**class_exponent )
return -sum_of_squared_classes
def fill_the_gaps(C):
pass
"""Idea to calculate gaps for each color and minimize gaps"""
def squared_classes(C):
max_value = 10**6 * (1 + goal_number_of_colors)
colors_used = C.shape[0]
sum_of_squared_classes = np.sum(np.sum(C,axis=1)**2)
sum_of_squared_classes = np.sum(np.sum(C,axis=1)**class_exponent)
all_vertices_colored = np.sum(C) == C.shape[1]
return max_value - (10**6 * colors_used) - sum_of_squared_classes - (10**6 * all_vertices_colored)
......