Advertisement
Guest User

Untitled

a guest
Apr 21st, 2018
72
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 8.58 KB | None | 0 0
  1. from collections import deque
  2. import numpy as np
  3.  
  4. def revise_rows(possible_positions, image):
  5.     revised = False
  6.     for r in range(row_num):
  7.         pos_mat = possible_positions[r]
  8.  
  9.         image_row = image[r, :]
  10.  
  11.         result = pos_mat + image_row
  12.         result = np.all(result != 1, axis=1)
  13.  
  14.         revised |= np.any(result == False)
  15.  
  16.         possible_positions[r] = possible_positions[r][result,:]
  17.     return revised
  18.  
  19. def revise_cols(possible_positions, image):
  20.     revised = False
  21.     for c in range(col_num):
  22.         pos_mat = possible_positions[c]
  23.         image_col = image[:, c]
  24.  
  25.         result = pos_mat + image_col
  26.         result = np.all(result != 1, axis=1)
  27.  
  28.         revised |= np.any(result == False)
  29.  
  30.         possible_positions[c] = possible_positions[c][result, :]
  31.     return revised
  32.  
  33. def revise_row(r, possible_positions, image):
  34.     revised = False
  35.     pos_mat = possible_positions[r]
  36.  
  37.     image_row = image[r, :]
  38.  
  39.     result = pos_mat + image_row
  40.     result = np.all(result != 1, axis=1)
  41.  
  42.     revised |= np.any(result == False)
  43.  
  44.     possible_positions[r] = possible_positions[r][result,:]
  45.     return revised
  46.  
  47. def revise_col(c, possible_positions, image):
  48.     revised = False
  49.     pos_mat = possible_positions[c]
  50.  
  51.     image_col = image[:, c]
  52.  
  53.     result = pos_mat + image_col
  54.     result = np.all(result != 1, axis=1)
  55.  
  56.     revised |= np.any(result == False)
  57.  
  58.     possible_positions[c] = possible_positions[c][result, :]
  59.     return revised
  60.  
  61. def fix_by_rows(possible_positions, image):
  62.     for r in range(row_num):
  63.         pos_mat = possible_positions[r]
  64.         result = pos_mat.sum(axis=0)
  65.         image[r, result==len(possible_positions[r])] = 1
  66.         image[r, result==0] = 0
  67.  
  68. def fix_by_cols(possible_positions, image):
  69.     for c in range(col_num):
  70.         pos_mat = possible_positions[c]
  71.         result = pos_mat.sum(axis=0)
  72.         image[result==len(possible_positions[c]), c] = 1
  73.         image[result==0, c] = 0
  74.  
  75. def revise(row_possible_positions, col_possible_positions, image):
  76.     revised = True
  77.     while revised:
  78.         revised = False
  79.         image_sum = image.sum()
  80.         for r in range(row_num):
  81.             revised |= revise_row(r, row_possible_positions, image)
  82.             if(len(row_possible_positions[r]) == 0):
  83.                 return False
  84.             fix_by_rows(row_possible_positions, image)
  85.         for c in range(col_num):
  86.             revised |= revise_col(c, col_possible_positions, image)
  87.             if(len(col_possible_positions[c]) == 0):
  88.                 return False
  89.             fix_by_cols(col_possible_positions, image)
  90.  
  91.         revised |= image_sum < image.sum()
  92.     return True
  93. def solve(row_descriptions_list, col_descriptions_list):
  94.     t0 = time.time()
  95.     row_possible_positions = [binary_descripts(block_domains(col_num, row_description), row_description, col_num) \
  96.         for row_description in row_descriptions_list]
  97.     col_possible_positions = [binary_descripts(block_domains(row_num, col_description), col_description, row_num) \
  98.         for col_description in col_descriptions_list]
  99.  
  100.  
  101.     print('block domains time:',time.time() - t0)
  102.     # -1 = unassigned, 0 - not filled, 1 - filled
  103.     image = np.ones((row_num, col_num)) * (-1)
  104.  
  105.     t0 = time.time()
  106.     revise(row_possible_positions, col_possible_positions, image)
  107.     print('first revise time:',time.time() - t0)
  108.     assigned_rows = np.array([False] * len(row_possible_positions))
  109.     assigned_cols = np.array([False] * len(col_possible_positions))
  110.     update_assigned(row_possible_positions, assigned_rows, col_possible_positions, assigned_cols)
  111.  
  112.     _, image = backtrack(row_possible_positions, assigned_rows, col_possible_positions, assigned_cols, image)
  113.  
  114.     draw_image(image)
  115.  
  116. import time
  117. sorting_time = 0
  118. revising_time = 0
  119. backtrack_num = 0
  120. def backtrack(row_variables, assigned_rows, col_variables, assigned_cols, image):
  121.     global sorting_time
  122.     global revising_time
  123.     global backtrack_num
  124.     backtrack_num += 1
  125.     if np.all(assigned_rows) and np.all(assigned_cols):
  126.         return True, image
  127.    
  128.     var_type, var_idx = choose_variable(row_variables, assigned_rows, col_variables, assigned_cols)
  129.     if var_type == 'r':
  130.         var = row_variables[var_idx]
  131.         assigned_rows[var_idx] = True
  132.     else:
  133.         var = col_variables[var_idx]
  134.         assigned_cols[var_idx] = True
  135.  
  136.     t0 = time.time()
  137.     sorted_values = sort_values(row_variables, col_variables, var, var_idx, var_type, image)#reversed(range(len(var)))
  138.     sorting_time += time.time() - t0
  139.  
  140.     for value_idx in sorted_values:
  141.         image_copy = image.copy()
  142.         row_variables_copy = [v.copy() for v in row_variables]
  143.         col_variables_copy = [v.copy() for v in col_variables]
  144.  
  145.        
  146.         assign_value(var[value_idx, :], var_idx, var_type, image_copy)
  147.         t0 = time.time()
  148.         revised = revise(row_variables_copy, col_variables_copy, image_copy)
  149.         revising_time += time.time() - t0
  150.         if revised:
  151.             result, result_img = backtrack(row_variables_copy, assigned_rows, \
  152.                 col_variables_copy, assigned_cols, image_copy)
  153.  
  154.             if result == True:
  155.                 return True, result_img
  156.  
  157.     if var_type == 'r':
  158.         assigned_rows[var_idx] = False
  159.     else:
  160.         assigned_cols[var_idx] = False
  161.  
  162.     return False, None
  163.  
  164. def assign_value(vector, vector_idx, vector_type, image):
  165.     if vector_type == 'r':
  166.         image[vector_idx, :] = vector
  167.     else:
  168.         image[:, vector_idx] = vector
  169.  
  170. def choose_variable(row_variables, assigned_rows, col_variables, assigned_cols):
  171.    
  172.     best_var = '', 999999, -1
  173.  
  174.     for i in range(len(col_variables)):
  175.         if assigned_cols[i] == False and best_var[1] > col_variables[i].shape[0]:
  176.             best_var = 'c', col_variables[i].shape[0], i
  177.  
  178.     for i in range(len(row_variables)):
  179.         if assigned_rows[i] == False and best_var[1] > row_variables[i].shape[0]:
  180.             best_var = 'r', row_variables[i].shape[0], i
  181.  
  182.     return best_var[0], best_var[2]
  183.  
  184.  
  185. def update_assigned(row_variables, assigned_rows, col_variables, assigned_cols):
  186.     for i, row in enumerate(row_variables):
  187.         if row.shape[0] == 1:
  188.             assigned_rows[i] = True
  189.     for i, col in enumerate(col_variables):
  190.         if row.shape[0] == 1:
  191.             assigned_cols[i] = True
  192.  
  193. def sort_values(row_poss, col_poss, values, vector_idx, vector_type, image):
  194.     indicies = []
  195.     img_cpy = image.copy()
  196.     for val_idx, val in enumerate(values):
  197.        
  198.         assign_value(val, vector_idx, vector_type, img_cpy)
  199.         if vector_type == 'r':
  200.             col_poss_copy = [v.copy() for v in col_poss]
  201.             revise_cols(col_poss_copy, img_cpy)
  202.             indicies.append((sum([c.shape[0] for c in col_poss_copy]), val_idx))
  203.  
  204.         else:
  205.             row_poss_copy = [v.copy() for v in row_poss]
  206.             revise_rows(row_poss_copy, img_cpy)
  207.             indicies.append((sum([r.shape[0] for r in row_poss_copy]), val_idx))
  208.  
  209.     indicies.sort(reverse=True)
  210.     return [idx for val, idx in indicies]
  211.  
  212. def block_domains(sequence_len, block_lens):
  213.     block_num = len(block_lens)
  214.     q = deque() # queue holdings states. Each state is list of positions of blocks.
  215.    
  216.     positions = []
  217.  
  218.     pos = 0
  219.     while pos + sum(block_lens) + len(block_lens) - 1 <= sequence_len:
  220.         q.append([pos])
  221.         pos += 1
  222.      
  223.     while not (len(q) == 0):
  224.         state = q.pop()
  225.         state_len = len(state)
  226.         if state_len != block_num:
  227.            
  228.             pos = state[-1] + block_lens[state_len-1] + 1
  229.             while pos + sum(block_lens[state_len:]) + len(block_lens[state_len:]) - 1 <= sequence_len:
  230.                 new_state = list(state)
  231.                 new_state.append(pos)
  232.                 q.append(new_state)
  233.                 pos += 1
  234.         else:
  235.             positions.append(state)
  236.     return positions
  237.  
  238. binary_time = 0
  239. def binary_descripts(domain, lengths, sequence_len):
  240.     global binary_time
  241.     t0 = time.time()
  242.     binary_domain = np.array([[0] * sequence_len] * len(domain))
  243.     for i, positions in enumerate(domain):
  244.         for pos, length in zip(positions, lengths):
  245.             binary_domain[i,pos:pos+length] = 1
  246.     binary_time += time.time() - t0
  247.     return binary_domain
  248.  
  249. def draw_image(image):
  250.     for row in image:
  251.         signs = []
  252.         for i in row:
  253.             signs.append('#' if i == 1 else '.')
  254.         f_out.write(''.join(signs) + '\n')
  255.  
  256. def print_image(image):
  257.     for row in image:
  258.         signs = []
  259.         for i in row:
  260.             signs.append('#' if i == 1 else '.')
  261.         print(''.join(signs) + '\n')
  262.     print('\n*******\n')
  263.  
  264.  
  265. f = open("zad_input.txt", 'r')
  266. f_out = open("zad_output.txt", 'w')
  267.  
  268. row_descriptions = []
  269. col_descriptions = []
  270. for i,l in enumerate(f):
  271.     l = l.split()
  272.  
  273.     if i == 0:
  274.         row_num = int(l[0])
  275.         col_num = int(l[1])
  276.     elif len(row_descriptions) < row_num:
  277.         row_descriptions.append([int(x) for x in l])
  278.     else:
  279.         col_descriptions.append([int(x) for x in l])
  280.  
  281.  
  282. solve(row_descriptions,col_descriptions)
  283. print('sorting time=',sorting_time)
  284. print('revising_time=',revising_time)
  285. print('binary_time=',binary_time)
  286. print('backtrack_num=', backtrack_num)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement