Advertisement
Guest User

Untitled

a guest
Jun 6th, 2024
561
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 7.47 KB | Science | 0 0
  1. import sys
  2. import copy
  3. import os
  4. import math
  5. import scipy
  6. import scipy.sparse as sp
  7. import numpy as np
  8. import gmpy2
  9. gmpy2.get_context().precision = 1000
  10.  
  11. # Works best on python 3.8, at least for me.
  12. # Exact 3 Cover
  13. S = [5,33,24,45,46,47,564,12,234]
  14. S_dict = {element: True for element in S}
  15. C = {5,33,24},{24,5,33},{45,46,47},{24,46,33}
  16. #########################################################################
  17. # Making sure subsets follow the rules of combinations
  18.  
  19. # Rules for input that does not violate the correctness for general Exact 3 Cover
  20. # Only one permutation of a subset is needed to form a solution (eg. {1,2,3} and {3,2,1})
  21. # Only subsets that have elements in S are allowed
  22. # subsets are only of size 3
  23. # Subsets must contain no duplicates
  24. # Only one occurrence of a subset
  25.  
  26. valid_subsets_dict = {}
  27. valid_subsets = []
  28. for SL in C:
  29.     # Make sure that subsets have 3 elements
  30.     if len(SL) == 3:
  31.         # Make sure only subsets with elements in S are considered
  32.         if all(element in S_dict for element in SL):  
  33.             # Remove multiple permutations of subsets and only
  34.             # allows one occurrence of a subset
  35.             # Does not affect the correctness of deciding if a solution exists
  36.             # because you only need one permutation to form a solution.
  37.             if tuple(sorted(SL)) not in valid_subsets_dict:  
  38.                 valid_subsets_dict[tuple(sorted(SL))] = True
  39.                 # Since sets aren't subscribtable I have to convert them to a list.
  40.                 # I have to touch the subsets to perform the reduction.
  41.                 valid_subsets.append(list(SL))
  42.                
  43. C = valid_subsets
  44. # Creating a copy of C to make sure that I can reverse the reduction to show
  45. # the original solution
  46. C_copy = copy.deepcopy(C)
  47.  
  48. #########################################################################
  49. def is_prime(n):
  50.     if n <= 1:
  51.         return False
  52.     elif n <= 3:
  53.         return True
  54.     elif n % 2 == 0 or n % 3 == 0:
  55.         return False
  56.     i = 5
  57.     while i * i <= n:
  58.         if n % i == 0 or n % (i + 2) == 0:
  59.             return False
  60.         i += 6
  61.     return True
  62. # Get the first N odd primes
  63. def get_primes_up_to_N(N):
  64.     primes = []
  65.     num = k[len(k)-1] + 1
  66.     while len(primes) < N:
  67.         if is_prime(num):
  68.             primes.append(num)
  69.         num += 1
  70.     return primes
  71.  
  72. #########################################################################
  73. # Generate primes following the pattern
  74. # [3,5,7]  Size 3
  75. # [11,13,17,19,23,29]  Size 6
  76. # [31, 37, 41, 43, 47, 53, 59, 61, 67]   Size 9
  77. # Go to last iteration, such as [3,5,7] Notice i[len(i)-1] is 7
  78. # Find prime larger than i[len(i)-1] which is 11
  79. # Generate N odd primes start at 11, which is 11,13,17,19,23,29. Where N is six.
  80. # Raise each odd prime to the powers of 5,6,7 in sequential order (eg. a^5, b^6, c^7, d^5, e^6, f^7, g^5...)
  81. # This ensures list of different sizes always has a unique list of odd primes. And that it uses primes larger than the last one
  82.  
  83.  
  84. k = [2]
  85. N = 0
  86. new_S = []
  87. while len(new_S) != len(S):
  88.     N = N + 3
  89.     B = [i for i in range(1, N + 1)]
  90.     primes = get_primes_up_to_N(len(B))
  91.     k = primes
  92.     Y = [5,6,7]
  93.     new_S = []
  94.     i = 0
  95.     x = 0
  96.     while len(new_S) != len(B):
  97.         new_S.append(primes[x]**Y[i])
  98.         i = i + 1
  99.         x = x + 1
  100.         if i == 3:
  101.             i = 0
  102. #########################################################################
  103.  
  104. # Create a dictionary to map elements in S to their indices in new_S
  105. index_mapping = {element: new_S[index] for index, element in enumerate(S)}
  106.  
  107. # Define N for Subset Sum dynamic solution
  108. N = sum(new_S)
  109. # sums from the collection of transformed subsets
  110. sums = []
  111. # Mapping new C
  112. for SL in C:
  113.     for j in range(len(SL)):
  114.         # Use the dictionary to map the elem to its corresponding value in new_S
  115.         SL[j] = index_mapping[SL[j]]
  116.     sums.append(sum(SL))
  117.  
  118. #########################################################################
  119.  
  120. # Function to write a list to a file on the flash drive
  121. def write_list_to_file(filename, data):
  122.     with open(filename, 'wb') as f:  # Open the file in binary mode
  123.         for row in data:
  124.             # Convert boolean values to bytes before writing to file
  125.             row_bytes = bytearray([1 if cell else 0 for cell in row])
  126.             f.write(row_bytes)
  127.             f.write(b'\n')  # Add newline separator
  128.  
  129. #############################################################################################
  130.  
  131. # Function to read a list from a file on the flash drive
  132. def read_list_from_file(filename):
  133.     with open(filename, 'rb') as f:  # Open the file in binary mode
  134.         return [[byte != 0 for byte in line.strip()] for line in f]
  135.  
  136. #########################################################################
  137.  
  138. def isSubsetSumSolidStateDrive(arr, n, target, filename):
  139.     # Initialize a set to store the indices of subset sums that are possible
  140.     subset_indices = set()
  141.     subset_indices.add(0)  # 0 is always possible
  142.      
  143.     # Perform dynamic programming and write intermediate results to the flash drive
  144.     with open(filename, 'wb') as f:  # Open the file in binary write mode
  145.         for i in range(1, n + 1):
  146.             new_indices = set()
  147.             for j in subset_indices:
  148.                 new_indices.add(j + arr[i - 1])
  149.                  
  150.             subset_indices.update(new_indices)
  151.              
  152.             # Convert boolean values to bytes and write them to the file
  153.             for j in range(target + 1):
  154.                 f.write(np.uint8(int(j in subset_indices)).tobytes())
  155.  
  156.     # Backtrack to find the solution
  157.     # backtracking does not explore all possible subsets exhaustively.
  158.     # Instead, it prunes the search space
  159.     # This pruning is based on the information stored in the subset table.
  160.     solution = []
  161.     j = target
  162.     for i in range(n, 0, -1):
  163.         if j - arr[i - 1] in subset_indices:
  164.             solution.append(arr[i - 1])
  165.             j -= arr[i - 1]
  166.  
  167.     return target in subset_indices, solution[::-1]  # Return whether solution exists and the solution itself
  168.  
  169. #########################################################################
  170.  
  171. # You must put the path here for the SSD. SSD should be dedicated to this algorithm.
  172. # Otherwise, the algorithm will throw a hissy fit
  173. # You have to physically write out the file name on the 1 Terabyte SSD, case sensitive
  174.  
  175. subset_table_file = 'C:\\Users\\....\\....\\...\\subset_table.txt'
  176. # Function to reset the subset table file before using the code.
  177. def reset_subset_table(filename):
  178.     with open(filename, 'w') as f:
  179.         pass  # Simply open the file in write mode, which clears its contents
  180. reset_subset_table(subset_table_file)
  181.  
  182. #########################################################################
  183.  
  184. n = len(sums)
  185. # Call isSubsetSumSolidStateDrive function with SSD file path
  186. solution = isSubsetSumSolidStateDrive(sums, n, N, subset_table_file)
  187. cover = []
  188. # Reverse the reduction in order verify if the algorithm
  189. # was able to find a solution.
  190. if solution[0] == True:
  191.     get_i = solution[1]
  192.     for i in get_i:
  193.         get_index = sums.index(i)
  194.         reverse_map = C_copy[get_index]
  195.         cover.append(reverse_map)
  196.  
  197.        
  198. if len(cover) == len(S)//3:
  199.     # flatten the list and check for duplicates
  200.     F = [item for sublist in cover for item in sublist]
  201.     if len(F) == len(set(F)):
  202.         print('Solution Exists')
  203. else:
  204.     print('no solution found')
  205.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement