[workshop] Add notebook
This commit is contained in:
1592
Workshop - 1 (Random, BFS, DFS, DP).ipynb
Normal file
1592
Workshop - 1 (Random, BFS, DFS, DP).ipynb
Normal file
File diff suppressed because one or more lines are too long
1420
Workshop - 2 (UCS, A, Hill-Climbing).ipynb
Normal file
1420
Workshop - 2 (UCS, A, Hill-Climbing).ipynb
Normal file
File diff suppressed because one or more lines are too long
122
Workshop - 3 (Game).ipynb
Normal file
122
Workshop - 3 (Game).ipynb
Normal file
@@ -0,0 +1,122 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Create a terminal here"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"<img src=\"images/terminal.png\">"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Change working directory"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"```bash\n",
|
||||
"$ cd Workshop\\ -\\ 3\\ \\(Game\\)/\n",
|
||||
"```"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"<img src=\"images/pwd.png\">"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Run the game"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"```bash\n",
|
||||
"$ python3 minimax.py\n",
|
||||
"```"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"<img src=\"images/minimax.png\">"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"```bash\n",
|
||||
"$ python3 ab-pruning.py\n",
|
||||
"```"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"<img src=\"images/ab-pruning.png\">"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Reading Materials"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"https://stackabuse.com/minimax-and-alpha-beta-pruning-in-python/"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.8.5"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 4
|
||||
}
|
||||
191
Workshop - 3 (Game)/ab-pruning.py
Normal file
191
Workshop - 3 (Game)/ab-pruning.py
Normal file
@@ -0,0 +1,191 @@
|
||||
# We'll use the time module to measure the time of evaluating
|
||||
# game tree in every move. It's a nice way to show the
|
||||
# distinction between the basic Minimax and Minimax with
|
||||
# alpha-beta pruning :)
|
||||
import time
|
||||
|
||||
class Game:
|
||||
def __init__(self):
|
||||
self.initialize_game()
|
||||
|
||||
def initialize_game(self):
|
||||
self.current_state = [['.','.','.'],
|
||||
['.','.','.'],
|
||||
['.','.','.']]
|
||||
|
||||
# Player X always plays first
|
||||
self.player_turn = 'X'
|
||||
|
||||
def draw_board(self):
|
||||
for i in range(0, 3):
|
||||
for j in range(0, 3):
|
||||
print('{}|'.format(self.current_state[i][j]), end=" ")
|
||||
print()
|
||||
print()
|
||||
|
||||
# Determines if the made move is a legal move
|
||||
def is_valid(self, px, py):
|
||||
if px < 0 or px > 2 or py < 0 or py > 2:
|
||||
return False
|
||||
elif self.current_state[px][py] != '.':
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
||||
# Checks if the game has ended and returns the winner in each case
|
||||
def is_end(self):
|
||||
# Vertical win
|
||||
for i in range(0, 3):
|
||||
if (self.current_state[0][i] != '.' and
|
||||
self.current_state[0][i] == self.current_state[1][i] and
|
||||
self.current_state[1][i] == self.current_state[2][i]):
|
||||
return self.current_state[0][i]
|
||||
|
||||
# Horizontal win
|
||||
for i in range(0, 3):
|
||||
if (self.current_state[i] == ['X', 'X', 'X']):
|
||||
return 'X'
|
||||
elif (self.current_state[i] == ['O', 'O', 'O']):
|
||||
return 'O'
|
||||
|
||||
# Main diagonal win
|
||||
if (self.current_state[0][0] != '.' and
|
||||
self.current_state[0][0] == self.current_state[1][1] and
|
||||
self.current_state[0][0] == self.current_state[2][2]):
|
||||
return self.current_state[0][0]
|
||||
|
||||
# Second diagonal win
|
||||
if (self.current_state[0][2] != '.' and
|
||||
self.current_state[0][2] == self.current_state[1][1] and
|
||||
self.current_state[0][2] == self.current_state[2][0]):
|
||||
return self.current_state[0][2]
|
||||
|
||||
# Is whole board full?
|
||||
for i in range(0, 3):
|
||||
for j in range(0, 3):
|
||||
# There's an empty field, we continue the game
|
||||
if (self.current_state[i][j] == '.'):
|
||||
return None
|
||||
|
||||
# It's a tie!
|
||||
return '.'
|
||||
|
||||
def max_alpha_beta(self, alpha, beta):
|
||||
maxv = -2
|
||||
px = None
|
||||
py = None
|
||||
|
||||
result = self.is_end()
|
||||
|
||||
if result == 'X':
|
||||
return (-1, 0, 0)
|
||||
elif result == 'O':
|
||||
return (1, 0, 0)
|
||||
elif result == '.':
|
||||
return (0, 0, 0)
|
||||
|
||||
for i in range(0, 3):
|
||||
for j in range(0, 3):
|
||||
if self.current_state[i][j] == '.':
|
||||
self.current_state[i][j] = 'O'
|
||||
(m, min_i, in_j) = self.min_alpha_beta(alpha, beta)
|
||||
if m > maxv:
|
||||
maxv = m
|
||||
px = i
|
||||
py = j
|
||||
self.current_state[i][j] = '.'
|
||||
|
||||
# Next two ifs in Max and Min are the only difference between regular algorithm and minimax
|
||||
if maxv >= beta:
|
||||
return (maxv, px, py)
|
||||
|
||||
if maxv > alpha:
|
||||
alpha = maxv
|
||||
|
||||
return (maxv, px, py)
|
||||
|
||||
def min_alpha_beta(self, alpha, beta):
|
||||
|
||||
minv = 2
|
||||
|
||||
qx = None
|
||||
qy = None
|
||||
|
||||
result = self.is_end()
|
||||
|
||||
if result == 'X':
|
||||
return (-1, 0, 0)
|
||||
elif result == 'O':
|
||||
return (1, 0, 0)
|
||||
elif result == '.':
|
||||
return (0, 0, 0)
|
||||
|
||||
for i in range(0, 3):
|
||||
for j in range(0, 3):
|
||||
if self.current_state[i][j] == '.':
|
||||
self.current_state[i][j] = 'X'
|
||||
(m, max_i, max_j) = self.max_alpha_beta(alpha, beta)
|
||||
if m < minv:
|
||||
minv = m
|
||||
qx = i
|
||||
qy = j
|
||||
self.current_state[i][j] = '.'
|
||||
|
||||
if minv <= alpha:
|
||||
return (minv, qx, qy)
|
||||
|
||||
if minv < beta:
|
||||
beta = minv
|
||||
|
||||
return (minv, qx, qy)
|
||||
|
||||
def play_alpha_beta(self):
|
||||
while True:
|
||||
self.draw_board()
|
||||
self.result = self.is_end()
|
||||
|
||||
if self.result != None:
|
||||
if self.result == 'X':
|
||||
print('The winner is X!')
|
||||
elif self.result == 'O':
|
||||
print('The winner is O!')
|
||||
elif self.result == '.':
|
||||
print("It's a tie!")
|
||||
|
||||
|
||||
self.initialize_game()
|
||||
return
|
||||
|
||||
if self.player_turn == 'X':
|
||||
|
||||
while True:
|
||||
start = time.time()
|
||||
(m, qx, qy) = self.min_alpha_beta(-2, 2)
|
||||
end = time.time()
|
||||
print('Evaluation time: {}s'.format(round(end - start, 7)))
|
||||
print('Recommended move: X = {}, Y = {}'.format(qx, qy))
|
||||
|
||||
px = int(input('Insert the X coordinate: '))
|
||||
py = int(input('Insert the Y coordinate: '))
|
||||
|
||||
qx = px
|
||||
qy = py
|
||||
|
||||
if self.is_valid(px, py):
|
||||
self.current_state[px][py] = 'X'
|
||||
self.player_turn = 'O'
|
||||
break
|
||||
else:
|
||||
print('The move is not valid! Try again.')
|
||||
|
||||
else:
|
||||
(m, px, py) = self.max_alpha_beta(-2, 2)
|
||||
self.current_state[px][py] = 'O'
|
||||
self.player_turn = 'X'
|
||||
|
||||
def main():
|
||||
g = Game()
|
||||
g.play_alpha_beta()
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
204
Workshop - 3 (Game)/minimax.py
Normal file
204
Workshop - 3 (Game)/minimax.py
Normal file
@@ -0,0 +1,204 @@
|
||||
# We'll use the time module to measure the time of evaluating
|
||||
# game tree in every move. It's a nice way to show the
|
||||
# distinction between the basic Minimax and Minimax with
|
||||
# alpha-beta pruning :)
|
||||
import time
|
||||
|
||||
class Game:
|
||||
def __init__(self):
|
||||
self.initialize_game()
|
||||
|
||||
def initialize_game(self):
|
||||
self.current_state = [['.','.','.'],
|
||||
['.','.','.'],
|
||||
['.','.','.']]
|
||||
|
||||
# Player X always plays first
|
||||
self.player_turn = 'X'
|
||||
|
||||
def draw_board(self):
|
||||
for i in range(0, 3):
|
||||
for j in range(0, 3):
|
||||
print('{}|'.format(self.current_state[i][j]), end=" ")
|
||||
print()
|
||||
print()
|
||||
|
||||
# Determines if the made move is a legal move
|
||||
def is_valid(self, px, py):
|
||||
if px < 0 or px > 2 or py < 0 or py > 2:
|
||||
return False
|
||||
elif self.current_state[px][py] != '.':
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
||||
# Checks if the game has ended and returns the winner in each case
|
||||
def is_end(self):
|
||||
# Vertical win
|
||||
for i in range(0, 3):
|
||||
if (self.current_state[0][i] != '.' and
|
||||
self.current_state[0][i] == self.current_state[1][i] and
|
||||
self.current_state[1][i] == self.current_state[2][i]):
|
||||
return self.current_state[0][i]
|
||||
|
||||
# Horizontal win
|
||||
for i in range(0, 3):
|
||||
if (self.current_state[i] == ['X', 'X', 'X']):
|
||||
return 'X'
|
||||
elif (self.current_state[i] == ['O', 'O', 'O']):
|
||||
return 'O'
|
||||
|
||||
# Main diagonal win
|
||||
if (self.current_state[0][0] != '.' and
|
||||
self.current_state[0][0] == self.current_state[1][1] and
|
||||
self.current_state[0][0] == self.current_state[2][2]):
|
||||
return self.current_state[0][0]
|
||||
|
||||
# Second diagonal win
|
||||
if (self.current_state[0][2] != '.' and
|
||||
self.current_state[0][2] == self.current_state[1][1] and
|
||||
self.current_state[0][2] == self.current_state[2][0]):
|
||||
return self.current_state[0][2]
|
||||
|
||||
# Is whole board full?
|
||||
for i in range(0, 3):
|
||||
for j in range(0, 3):
|
||||
# There's an empty field, we continue the game
|
||||
if (self.current_state[i][j] == '.'):
|
||||
return None
|
||||
|
||||
# It's a tie!
|
||||
return '.'
|
||||
|
||||
# Player 'O' is max, in this case AI
|
||||
def max(self):
|
||||
|
||||
# Possible values for maxv are:
|
||||
# -1 - loss
|
||||
# 0 - a tie
|
||||
# 1 - win
|
||||
|
||||
# We're initially setting it to -2 as worse than the worst case:
|
||||
maxv = -2
|
||||
|
||||
px = None
|
||||
py = None
|
||||
|
||||
result = self.is_end()
|
||||
|
||||
# If the game came to an end, the function needs to return
|
||||
# the evaluation function of the end. That can be:
|
||||
# -1 - loss
|
||||
# 0 - a tie
|
||||
# 1 - win
|
||||
if result == 'X':
|
||||
return (-1, 0, 0)
|
||||
elif result == 'O':
|
||||
return (1, 0, 0)
|
||||
elif result == '.':
|
||||
return (0, 0, 0)
|
||||
|
||||
for i in range(0, 3):
|
||||
for j in range(0, 3):
|
||||
if self.current_state[i][j] == '.':
|
||||
# On the empty field player 'O' makes a move and calls Min
|
||||
# That's one branch of the game tree.
|
||||
self.current_state[i][j] = 'O'
|
||||
(m, min_i, min_j) = self.min()
|
||||
# Fixing the maxv value if needed
|
||||
if m > maxv:
|
||||
maxv = m
|
||||
px = i
|
||||
py = j
|
||||
# Setting back the field to empty
|
||||
self.current_state[i][j] = '.'
|
||||
return (maxv, px, py)
|
||||
|
||||
# Player 'X' is min, in this case human
|
||||
def min(self):
|
||||
|
||||
# Possible values for minv are:
|
||||
# -1 - win
|
||||
# 0 - a tie
|
||||
# 1 - loss
|
||||
|
||||
# We're initially setting it to 2 as worse than the worst case:
|
||||
minv = 2
|
||||
|
||||
qx = None
|
||||
qy = None
|
||||
|
||||
result = self.is_end()
|
||||
|
||||
if result == 'X':
|
||||
return (-1, 0, 0)
|
||||
elif result == 'O':
|
||||
return (1, 0, 0)
|
||||
elif result == '.':
|
||||
return (0, 0, 0)
|
||||
|
||||
for i in range(0, 3):
|
||||
for j in range(0, 3):
|
||||
if self.current_state[i][j] == '.':
|
||||
self.current_state[i][j] = 'X'
|
||||
(m, max_i, max_j) = self.max()
|
||||
if m < minv:
|
||||
minv = m
|
||||
qx = i
|
||||
qy = j
|
||||
self.current_state[i][j] = '.'
|
||||
|
||||
return (minv, qx, qy)
|
||||
|
||||
def play(self):
|
||||
while True:
|
||||
self.draw_board()
|
||||
self.result = self.is_end()
|
||||
|
||||
# Printing the appropriate message if the game has ended
|
||||
if self.result != None:
|
||||
if self.result == 'X':
|
||||
print('The winner is X!')
|
||||
elif self.result == 'O':
|
||||
print('The winner is O!')
|
||||
elif self.result == '.':
|
||||
print("It's a tie!")
|
||||
|
||||
self.initialize_game()
|
||||
return
|
||||
|
||||
# If it's player's turn
|
||||
if self.player_turn == 'X':
|
||||
|
||||
while True:
|
||||
|
||||
start = time.time()
|
||||
(m, qx, qy) = self.min()
|
||||
end = time.time()
|
||||
print('Evaluation time: {}s'.format(round(end - start, 7)))
|
||||
print('Recommended move: X = {}, Y = {}'.format(qx, qy))
|
||||
|
||||
px = int(input('Insert the X coordinate: '))
|
||||
py = int(input('Insert the Y coordinate: '))
|
||||
|
||||
(qx, qy) = (px, py)
|
||||
|
||||
if self.is_valid(px, py):
|
||||
self.current_state[px][py] = 'X'
|
||||
self.player_turn = 'O'
|
||||
break
|
||||
else:
|
||||
print('The move is not valid! Try again.')
|
||||
|
||||
# If it's AI's turn
|
||||
else:
|
||||
(m, px, py) = self.max()
|
||||
self.current_state[px][py] = 'O'
|
||||
self.player_turn = 'X'
|
||||
|
||||
def main():
|
||||
g = Game()
|
||||
g.play()
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
252
Workshop - 3 (LP).ipynb
Normal file
252
Workshop - 3 (LP).ipynb
Normal file
@@ -0,0 +1,252 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"**Make sure you run this at the begining**"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import numpy as np\n",
|
||||
"np.set_printoptions(suppress=True)\n",
|
||||
"from scipy.optimize import linprog"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Feasible Example"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"\\begin{align}\n",
|
||||
"\\max f=4x_1+x_2 \\\\\n",
|
||||
"\\text{s.t.} -x_1 + 2x_2 &\\leq 4 \\\\\n",
|
||||
"2x_1 + 3x_2 &\\leq 12 \\\\\n",
|
||||
"x_1 - x_2 &\\leq 3 \\\\\n",
|
||||
"\\text{and } x_1, x_2 \\geq 0\n",
|
||||
"\\end{align}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"c = [-4, -1, 0, 0, 0]\n",
|
||||
"A = [[-1, 2, 0, 0, 0], [2, 3, 0, 0, 0], [1, -1, 0, 0, 0]]\n",
|
||||
"b = [4, 12, 3]\n",
|
||||
"\n",
|
||||
"x0_bounds = (0, None)\n",
|
||||
"x1_bounds = (0, None)\n",
|
||||
"x2_bounds = (None, None)\n",
|
||||
"x3_bounds = (None, None)\n",
|
||||
"x4_bounds = (None, None)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"metadata": {
|
||||
"scrolled": true
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
" con: array([], dtype=float64)\n",
|
||||
" fun: -17.999999976555795\n",
|
||||
" message: 'Optimization terminated successfully.'\n",
|
||||
" nit: 4\n",
|
||||
" slack: array([5.8 , 0.00000002, 0. ])\n",
|
||||
" status: 0\n",
|
||||
" success: True\n",
|
||||
" x: array([4.19999999, 1.2 , 0. , 0. , 0. ])\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"res = linprog(c, A_ub=A, b_ub=b, bounds=[x0_bounds, x1_bounds, x2_bounds, x3_bounds, x4_bounds])\n",
|
||||
"\n",
|
||||
"print(res)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Infeasible Example"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"\\begin{align}\n",
|
||||
"\\min f = x_1 - 2x_2 + 3x_3 \\\\\n",
|
||||
"s.t. -2x_1 + x_2 + 3x_3 & = 2 \\\\\n",
|
||||
"3x_1 + 3x_2 + 4x_3 & = 1 \\\\\n",
|
||||
"\\end{align}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"c = [-1, 2, -3]\n",
|
||||
"A = [[-2, 1, 3], [3, 3, 4]]\n",
|
||||
"b = [2, 1]\n",
|
||||
"\n",
|
||||
"x0_bounds = (0, None)\n",
|
||||
"x1_bounds = (0, None)\n",
|
||||
"x2_bounds = (0, None)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"metadata": {
|
||||
"scrolled": false
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
" con: array([ 0. , -4.56053464])\n",
|
||||
" fun: -0.6099904044751114\n",
|
||||
" message: 'The algorithm terminated successfully and determined that the problem is infeasible.'\n",
|
||||
" nit: 4\n",
|
||||
" slack: array([], dtype=float64)\n",
|
||||
" status: 2\n",
|
||||
" success: False\n",
|
||||
" x: array([0.2893146 , 0.75265113, 0.60865936])\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"res = linprog(c, A_eq=A, b_eq=b, bounds=[x0_bounds, x1_bounds, x2_bounds,])\n",
|
||||
"\n",
|
||||
"print(res)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"<h1><font color='red'>Assignment</font></h1>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"\\begin{align}\n",
|
||||
"\\min f = 3x_1 - x_2 \\\\\n",
|
||||
"s.t. 2x_1 + x_2 & \\geq 2 \\\\\n",
|
||||
"x_1 + 3x_2 & \\leq 3 \\\\\n",
|
||||
"x_2 & \\leq 4 \\\\\n",
|
||||
"\\text{and } x_1, x_2 \\geq 0\n",
|
||||
"\\end{align}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 6,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"c = [-3, 1]\n",
|
||||
"A = [[-2, -1], [1, 3], [0, 1]]\n",
|
||||
"b = [-2, 3, 4]\n",
|
||||
"\n",
|
||||
"x0_bounds = (0, None)\n",
|
||||
"x1_bounds = (0, None)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 7,
|
||||
"metadata": {
|
||||
"scrolled": true
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
" con: array([], dtype=float64)\n",
|
||||
" fun: -8.999999998556428\n",
|
||||
" message: 'Optimization terminated successfully.'\n",
|
||||
" nit: 4\n",
|
||||
" slack: array([4., 0., 4.])\n",
|
||||
" status: 0\n",
|
||||
" success: True\n",
|
||||
" x: array([3., 0.])\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"res = linprog(c, A_ub=A, b_ub=b, bounds=[x0_bounds, x1_bounds])\n",
|
||||
"\n",
|
||||
"print(res)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.8.5"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 4
|
||||
}
|
||||
1026
Workshop - 4 (TSP SA).ipynb
Normal file
1026
Workshop - 4 (TSP SA).ipynb
Normal file
File diff suppressed because one or more lines are too long
1022
Workshop - 5 (ACO, PSO).ipynb
Normal file
1022
Workshop - 5 (ACO, PSO).ipynb
Normal file
File diff suppressed because one or more lines are too long
2278
Workshop - 5 (PSO, ACO).ipynb
Normal file
2278
Workshop - 5 (PSO, ACO).ipynb
Normal file
File diff suppressed because it is too large
Load Diff
1317
Workshop - 6 (GA, SOM).ipynb
Normal file
1317
Workshop - 6 (GA, SOM).ipynb
Normal file
File diff suppressed because one or more lines are too long
BIN
images/ab-pruning.png
Normal file
BIN
images/ab-pruning.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 40 KiB |
BIN
images/minimax.png
Normal file
BIN
images/minimax.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 42 KiB |
BIN
images/pwd.png
Normal file
BIN
images/pwd.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 20 KiB |
BIN
images/solutions.png
Normal file
BIN
images/solutions.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 43 KiB |
BIN
images/terminal.png
Normal file
BIN
images/terminal.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 55 KiB |
BIN
images/tsp.jpg
Normal file
BIN
images/tsp.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 71 KiB |
0
.gitignore → template/.gitignore
vendored
0
.gitignore → template/.gitignore
vendored
@@ -1,3 +1,6 @@
|
||||
## Build Image
|
||||
|
||||
docker build -t com2014-tsp .
|
||||
|
||||
## Windows
|
||||
|
||||
@@ -35,13 +35,13 @@ def TSP(tsp_file, model):
|
||||
coords = load_data(tsp_file)
|
||||
|
||||
# Set timeout
|
||||
signal.signal(signal.SIGALRM, timeout_handler)
|
||||
signal.alarm(60)
|
||||
# signal.signal(signal.SIGALRM, timeout_handler)
|
||||
# signal.alarm(60)
|
||||
|
||||
# Try your algorithm
|
||||
try:
|
||||
model.init(coords)
|
||||
best_solution, fitness_list = model.fit(max_it=100000)
|
||||
best_solution, fitness_list = model.fit(max_it=10000)
|
||||
except Exception as exc:
|
||||
if(str(exc) == "Timeout"):
|
||||
log("Timeout -3")
|
||||
@@ -72,7 +72,7 @@ class SimAnneal(Model):
|
||||
self.log("Starting annealing.")
|
||||
while self.T >= self.stopping_temperature and self.iteration < max_it:
|
||||
candidate = list(self.cur_solution)
|
||||
l = random.randint(2, self.N - 1)
|
||||
l = random.randint(1, self.N - 1)
|
||||
i = random.randint(0, self.N - l)
|
||||
candidate[i : (i + l)] = reversed(candidate[i : (i + l)])
|
||||
self.accept(candidate)
|
||||
8
template/output/.gitignore
vendored
Normal file
8
template/output/.gitignore
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
# .gitignore sample
|
||||
###################
|
||||
|
||||
# Ignore all files in this dir...
|
||||
*
|
||||
|
||||
# ... except for this one.
|
||||
!.gitignore
|
||||
21
template/utils/load_data.py
Normal file
21
template/utils/load_data.py
Normal file
@@ -0,0 +1,21 @@
|
||||
def log(msg):
|
||||
print('[*] {msg}'.format(msg=msg))
|
||||
|
||||
def load_data(file):
|
||||
coords = []
|
||||
with open(file, "r") as infile:
|
||||
line = infile.readline()
|
||||
# Skip instance header
|
||||
while "NODE_COORD_SECTION" not in line:
|
||||
line = infile.readline()
|
||||
|
||||
for line in infile.readlines():
|
||||
line = line.replace("\n", "")
|
||||
if line and 'EOF' not in line:
|
||||
line = [float(x) for x in line.lstrip().split(" ", 1)[1].split(" ") if x]
|
||||
coords.append(line)
|
||||
return coords
|
||||
|
||||
def timeout_handler(signum, frame):
|
||||
print("Timeout")
|
||||
raise Exception("Timeout")
|
||||
139
template/utils/tsp.py
Normal file
139
template/utils/tsp.py
Normal file
@@ -0,0 +1,139 @@
|
||||
import os
|
||||
import signal
|
||||
import json
|
||||
import math
|
||||
import timeit
|
||||
|
||||
from utils.load_data import load_data
|
||||
from utils.load_data import log
|
||||
|
||||
def timeout_handler(signum, frame):
|
||||
raise Exception("Timeout")
|
||||
|
||||
def dist(node_0, node_1, coords):
|
||||
"""
|
||||
Euclidean distance between two nodes.
|
||||
"""
|
||||
coord_0, coord_1 = coords[node_0], coords[node_1]
|
||||
return math.sqrt((coord_0[0] - coord_1[0]) ** 2 + (coord_0[1] - coord_1[1]) ** 2)
|
||||
|
||||
def fitness(solution, coords):
|
||||
N = len(coords)
|
||||
cur_fit = 0
|
||||
for i in range(len(solution)):
|
||||
cur_fit += dist(solution[i % N], solution[(i + 1) % N], coords)
|
||||
return cur_fit
|
||||
|
||||
def TSP_Bench(tsp_file, model, *args, max_it=1000, timeout=60):
|
||||
|
||||
start = timeit.default_timer()
|
||||
|
||||
# Model Running
|
||||
best_solution, fitness_list = TSP(tsp_file, model, *args, max_it=max_it,timeout=timeout)
|
||||
# Model End
|
||||
|
||||
stop = timeit.default_timer()
|
||||
print('[*] Running for: {time:.2f} seconds'.format(time=(stop - start)))
|
||||
|
||||
print()
|
||||
return best_solution, fitness_list, (stop - start)
|
||||
|
||||
def TSP_Bench_ALL(tsp_file_path, model, *args, max_it=1000, timeout=60):
|
||||
best_solutions = []
|
||||
fitness_lists = []
|
||||
times = []
|
||||
for root, _, files in os.walk(tsp_file_path):
|
||||
if(files):
|
||||
for f in files:
|
||||
# Get input file name
|
||||
tsp_file = str(root) + '/' + str(f)
|
||||
log(tsp_file)
|
||||
|
||||
# Run TSP
|
||||
best_solution, fitness_list, time = TSP_Bench(tsp_file, model, *args, max_it=max_it,timeout=timeout)
|
||||
best_solutions.append(best_solution)
|
||||
fitness_lists.append(fitness_lists)
|
||||
times.append(time)
|
||||
|
||||
return best_solutions, fitness_lists, times
|
||||
|
||||
def TSP(tsp_file, model, *args, max_it=1000, timeout=60):
|
||||
|
||||
best_solution = []
|
||||
fitness_list = []
|
||||
|
||||
nodes = load_data(tsp_file)
|
||||
|
||||
# Set timeout
|
||||
signal.signal(signal.SIGALRM, timeout_handler)
|
||||
signal.alarm(timeout)
|
||||
|
||||
if not os.path.exists('output'):
|
||||
os.makedirs('output')
|
||||
|
||||
# Try your algorithm
|
||||
try:
|
||||
model.init(nodes, *args)
|
||||
best_solution, fitness_list = model.fit(max_it)
|
||||
except Exception as exc:
|
||||
if(str(exc) == "Timeout"):
|
||||
log("Timeout -3")
|
||||
with open('output/' + os.path.splitext(os.path.basename(tsp_file))[0] + '.txt', "w") as outfile:
|
||||
outfile.write("-3")
|
||||
best_solution = [-1] * len(nodes)
|
||||
else:
|
||||
print(exc)
|
||||
log("Unkown -4")
|
||||
with open('output/' + os.path.splitext(os.path.basename(tsp_file))[0] + '.txt', "w") as outfile:
|
||||
outfile.write("-4")
|
||||
|
||||
signal.alarm(0)
|
||||
|
||||
# Collect results
|
||||
if(len(fitness_list) > 0):
|
||||
log("[Node] " + str(len(best_solution)) + ", [Best] " + str(fitness_list[fitness_list.index(min(fitness_list))]))
|
||||
|
||||
if (len(best_solution) == 0):
|
||||
log("No Answer -1")
|
||||
with open('output/' + os.path.splitext(os.path.basename(tsp_file))[0] + '.txt', "w") as outfile:
|
||||
outfile.write("-1")
|
||||
elif (len(best_solution) != len(nodes)):
|
||||
log("Invalid -2")
|
||||
with open('output/' + os.path.splitext(os.path.basename(tsp_file))[0] + '.txt', "w") as outfile:
|
||||
outfile.write("-2")
|
||||
else:
|
||||
# log("Writing the best solution to file" )
|
||||
with open('output/' + os.path.splitext(os.path.basename(tsp_file))[0] + '.txt', "w") as outfile:
|
||||
outfile.write(str(model.fitness(best_solution)))
|
||||
outfile.write("\n")
|
||||
outfile.write(", ".join(str(item) for item in best_solution))
|
||||
|
||||
# Write to JSON
|
||||
data = {}
|
||||
|
||||
data['nodes'] = []
|
||||
for i in range(len(nodes)):
|
||||
data['nodes'].append({
|
||||
'title': str(i),
|
||||
'id': i,
|
||||
'x': int(nodes[i][0]),
|
||||
'y': int(nodes[i][1])
|
||||
})
|
||||
|
||||
data['edges'] = []
|
||||
for i in range(len(best_solution)):
|
||||
if i == len(best_solution)-1:
|
||||
data['edges'].append({
|
||||
'source': best_solution[i],
|
||||
'target': best_solution[0]
|
||||
})
|
||||
else:
|
||||
data['edges'].append({
|
||||
'source': best_solution[i],
|
||||
'target': best_solution[i+1]
|
||||
})
|
||||
|
||||
with open('output/' + os.path.splitext(os.path.basename(tsp_file))[0] + '.json', 'w') as outfile:
|
||||
json.dump(data, outfile)
|
||||
|
||||
return best_solution, fitness_list
|
||||
Reference in New Issue
Block a user