-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmin_conflicts.py
More file actions
81 lines (67 loc) · 2.51 KB
/
Copy pathmin_conflicts.py
File metadata and controls
81 lines (67 loc) · 2.51 KB
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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
import random
import time
def conflicts_for_column(board, col):
"""Count how many attacking queens the queen in column col currently has."""
n = len(board)
row = board[col]
conflicts = 0
for c in range(n):
if c == col:
continue
r2 = board[c]
if r2 == row or abs(r2 - row) == abs(c - col):
conflicts += 1
return conflicts
def min_conflicts(n, max_steps=100000):
board = [random.randrange(n) for _ in range(n)] # start with a random row for every column
explored_nodes = 0
checked_assignments = 0
start = time.perf_counter()
for step in range(max_steps): # perform up to max_steps repair iterations
checked_assignments += 1
# Track which columns currently violate constraints
conflicted_cols = [c for c in range(n) if conflicts_for_column(board, c) > 0]
if not conflicted_cols:
end = time.perf_counter()
# board is a valid solution because no queens threaten each other
return {
"method": "Min-Conflicts local search",
"N": n,
"solution": list(board),
"explored_nodes": explored_nodes,
"checked_assignments": checked_assignments,
"steps": step,
"runtime": end - start,
}
col = random.choice(conflicted_cols) # pick one conflicted queen to move
best_rows = []
best_conf = None
for row in range(n):
explored_nodes += 1
conf = 0
# Count conflicts if this queen is moved to 'row'
for c2 in range(n):
if c2 == col:
continue
r2 = board[c2]
if r2 == row or abs(r2 - row) == abs(c2 - col):
conf += 1
if best_conf is None or conf < best_conf:
best_conf = conf
best_rows = [row]
elif conf == best_conf:
best_rows.append(row)
# Move the queen to one of the rows with minimum conflicts (ties broken uniformly)
board[col] = random.choice(best_rows)
end = time.perf_counter()
# Ran out of steps without finding a conflict-free assignment
return {
"method": "Min-Conflicts local search",
"N": n,
"solution": None,
"explored_nodes": explored_nodes,
"checked_assignments": checked_assignments,
"steps": max_steps,
"runtime": end - start,
}
__all__ = ["min_conflicts"]