def gsat_solution(self, cnf_formula, sol_list_init, all_clauses, cnf_formula_unsat): positive_gain = ut.positive_gain(sol_list_init, cnf_formula_unsat) cnf_formula_sat = ut().sat_clauses(all_clauses, cnf_formula) # All SAT clauses # Now we wil claculate the negative gain negative_gain = ut.negative_gain(sol_list_init, cnf_formula_sat) # Finding the Net Gain value for each variable net_gain = [x1 - x2 for (x1, x2) in zip(positive_gain, negative_gain)] # getting the maximum netgain max_netgain = max(net_gain) # Getting the indexes of the maximum net gain value max_netgain_list = [i for i, x in enumerate(net_gain) if x == max_netgain] # To choose randomly the maximum net gain variable if more than one max netgain values presetn if len(max_netgain_list) > 1: net_gain_index = random.choice(max_netgain_list) else: net_gain_index = max_netgain_list[0] flipped_value_index = net_gain_index return flipped_value_index
def gwsat_solution(self, cnf_formula, max_tries, max_flips, wp, preprocess): for try_sol in range(0, max_tries): # Here we will generate the random solution in the form of Booleans initial_solution = ut.generate_solution(preprocess) for flip in range(0, max_flips): r = random.random() # Here we will be returned with the and of all clauses if ut.clause_satisfation(initial_solution, cnf_formula, satcheck=True): ''' Generating the solution by changing the booleans to actual variable ''' final_sol_list = ut.final_solution(initial_solution, preprocess, try_sol, flip) self.sat_variables = final_sol_list return f'Solution is {final_sol_list} generated in {try_sol + 1} tries and {flip + 1} flips' else: # List of all the clauses after performing OR operation on each all_clauses = ut.clause_satisfation(initial_solution, cnf_formula, satcheck=False) cnf_formula_unsat = ut().unsat_clauses( all_clauses, cnf_formula) # All unsat clauses if r < wp: # getting a flat list of all variables in the unsat clauses flat_unsatisified_clauses = [ item for sublist in cnf_formula_unsat for item in sublist ] # getting all the unique variables in the unsat clauses unique_unsat_variables = set(flat_unsatisified_clauses) # Randomly selecting variable from the list random_walk_var = random.choice( list(unique_unsat_variables)) flipped_value_index = abs(random_walk_var) - 1 else: sol_list_init = [] # Generating the variable solution list from the boolean list for index, var in enumerate(initial_solution): if not var: sol_list_init.append(-1 * (index + 1)) else: sol_list_init.append((index + 1)) flipped_value_index = GSAT().gsat_solution( cnf_formula, sol_list_init, all_clauses, cnf_formula_unsat) '''Flipping the initial_solution variable''' initial_solution[flipped_value_index] = not ( initial_solution[flipped_value_index]) return 'No Solution'
def gwsat_solution(self, cnf_formula, max_tries, max_flips, wp, preprocess): self.steps = 0 start_test_time = time() # To capture the algorithm run starting time end_test_time = 0 # To capture the algorithm run time in order to compare with cutoff time for try_sol in range(0, max_tries): # Here we will generate the random solution in the form of Booleans initial_solution = ut.generate_solution(preprocess) for flip in range(0, max_flips): self.steps = self.steps + 1 # Keeping a count of the steps # Condition to check if the cutoff time is encountered if end_test_time > self.cutoff_time: # print(f' Execution Time : {end_test_time} secs to find the solution surpassed cutoff time ' # f'of {self.cutoff_time} seconds ') return 'Cutoff Time' r = random.random() # Here we will be returned with the 'and' of all clauses if ut.clause_satisfation(initial_solution, cnf_formula,satcheck=True): ''' Generating the solution by changing the booleans to actual variable ''' final_sol_list = ut.final_solution(initial_solution, preprocess, try_sol, flip) self.sat_variables = final_sol_list return f'Solution is {final_sol_list} generated in {try_sol} restart with {flip + 1} flips' else: # List of all the clauses after performing OR operation on each all_clauses = ut.clause_satisfation(initial_solution, cnf_formula, satcheck=False) cnf_formula_unsat = ut().unsat_clauses(all_clauses, cnf_formula) # All unsat clauses if r < wp: # getting a flat list of all variables in the unsat clauses flat_unsatisified_clauses = [item for sublist in cnf_formula_unsat for item in sublist] # getting all the unique variables in the unsat clauses unique_unsat_variables = set(flat_unsatisified_clauses) # Randomly selecting variable from the list random_walk_var = random.choice(list(unique_unsat_variables)) flipped_value_index = abs(random_walk_var) - 1 else: sol_list_init = [] # Generating the variable solution list from the boolean list for index, var in enumerate(initial_solution): if not var: sol_list_init.append(-1 * (index + 1)) else: sol_list_init.append((index + 1)) flipped_value_index = GSAT().gsat_solution(cnf_formula, sol_list_init, all_clauses, cnf_formula_unsat) '''Flipping the initial_solution variable''' initial_solution[flipped_value_index] = not (initial_solution[flipped_value_index]) end_test_time = time() - start_test_time # Calculating the execution time to find the solution return 'No Solution'
def walksat_solution(self, cnf_formula, max_tries, max_flips, wp, tl, preprocess): self.steps = 0 start_test_time = time() # To capture the algorithm run starting time end_test_time = 0 # To capture the algorithm run time in order to compare with cutoff time for try_sol in range(0, max_tries): # tabu = queue.Queue(maxsize=tl) # Initializing the tabu queue tabu = { j: 0 for j in [i for i in range(1, preprocess.variable_number + 1)] } # Initializing the tabu queue # Here we will generate the random solution in the form of Booleans initial_solution = ut.generate_solution(preprocess) for flip in range(0, max_flips): self.steps = self.steps + 1 # Condition to check if the cutoff time is encountered if end_test_time > self.cutoff_time: # print(f' Execution Time : {end_test_time} secs to find the solution surpassed cutoff time ' # f'of {self.cutoff_time} seconds ') return 'Cutoff Time' # Here we will be returned with the and of all clauses if ut.clause_satisfation(initial_solution, cnf_formula, satcheck=True): ''' Generating the solution by changing the booleans to actual variable ''' final_sol_list = ut.final_solution(initial_solution, preprocess, try_sol, flip) self.sat_variables = final_sol_list return f'Solution is {final_sol_list} generated in {try_sol} restarts with {flip + 1} flips' else: # sol_list_init = [] index_selected_unsat_clause = [] '''Generating the variable solution list from the boolean list''' sol_list_init = ut().variable_sol_list(initial_solution) # List of all the clauses after performing OR operation on each all_clauses = ut.clause_satisfation(initial_solution, cnf_formula, satcheck=False) cnf_formula_unsat = ut().unsat_clauses( all_clauses, cnf_formula) # All unsat clauses cnf_formula_sat = ut().sat_clauses( all_clauses, cnf_formula) # All SAT clauses # Selecting UNSAT clause randomly unsat_clause_selection = random.choice(cnf_formula_unsat) '''CHECKING THE TABU LIST, if all the variables in selected unsat clauses are on the tabu list''' # tabu_list = list(tabu.queue) # Creating the selected unsat clause variable list (not literal) abs_unsat_clause_selection = [ abs(var) for var in unsat_clause_selection ] # if all the variables are in tabu list then # if set(abs_unsat_clause_selection).issubset(set(tabu_list)): # continue # if all the variables are in tabu list then reiterating for var in abs_unsat_clause_selection: if tabu[var] > self.steps: reiterate = True else: reiterate = False break if reiterate: continue '''We will check for each variable if that variable in UNSAT clause exists in tabu list It is a preprocessed step to reduce operation cost of checking tabu list after the var selection ''' # for index,var in enumerate(abs_unsat_clause_selection): # if var in tabu.queue: # index_selected_unsat_clause.append(index) for index, var in enumerate(abs_unsat_clause_selection): if tabu[var] > self.steps: index_selected_unsat_clause.append(index) # Now lets remove the variables from selected unsat clause which are in tabu list unsat_clause_selection = [ i for j, i in enumerate(unsat_clause_selection) if j not in index_selected_unsat_clause ] # If only single variable is present in the unsat clause after tabu check, then just flip that if len(unsat_clause_selection) == 1: flipped_value_index = abs( unsat_clause_selection[0]) - 1 else: # Computing negative gain of the variables in selected unsat clauses negative_gain = ut.negative_gain( sol_list_init, cnf_formula_sat, unsat_clause_selection) if 0 in negative_gain: '''Checking for the variables with negative gain of 0''' flipped_value_index = self.zero_negative_gain( negative_gain, unsat_clause_selection) else: r = random.random() if r < wp: '''getting a random variable in the selected unsat clauses''' flipped_value_var = random.choice( unsat_clause_selection) flipped_value_index = abs( flipped_value_var) - 1 else: '''Selecting the variable with minimum negative gain''' flipped_value_index = self.min_negative_gain( negative_gain, unsat_clause_selection) '''Manipulating the tabu list''' # if tabu.full(): # tabu.get() # tabu.put(flipped_value_index+1) tabu[flipped_value_index + 1] = self.steps + tl '''Flipping the initial_solution variable''' initial_solution[flipped_value_index] = not ( initial_solution[flipped_value_index]) end_test_time = time( ) - start_test_time # Calculating the execution time to find the solution return 'No Solution'
def walksat_solution(self, cnf_formula, max_tries, max_flips, wp, tl, preprocess): for try_sol in range(0, max_tries): tabu = queue.Queue(maxsize=tl) # Initializing the tabu queue # Here we will generate the random solution in the form of Booleans initial_solution = ut.generate_solution(preprocess) for flip in range(0, max_flips): # Here we will be returned with the and of all clauses if ut.clause_satisfation(initial_solution, cnf_formula, satcheck=True): ''' Generating the solution by changing the booleans to actual variable ''' final_sol_list = ut.final_solution(initial_solution, preprocess, try_sol, flip) self.sat_variables = final_sol_list return f'Solution is {final_sol_list} generated in {try_sol + 1} tries and {flip + 1} flips' else: # sol_list_init = [] index_selected_unsat_clause = [] '''Generating the variable solution list from the boolean list''' sol_list_init = ut().variable_sol_list(initial_solution) # List of all the clauses after performing OR operation on each all_clauses = ut.clause_satisfation(initial_solution, cnf_formula, satcheck=False) cnf_formula_unsat = ut().unsat_clauses( all_clauses, cnf_formula) # All unsat clauses cnf_formula_sat = ut().sat_clauses( all_clauses, cnf_formula) # All SAT clauses # Selecting UNSAT clause randomly unsat_clause_selection = random.choice(cnf_formula_unsat) '''CHECKING THE TABU LIST, if all the variables in selected unsat clauses are on the tabu list''' tabu_list = list(tabu.queue) # Creating the selected usat clause variable list (not literal) abs_unsat_clause_selection = [ abs(var) for var in unsat_clause_selection ] # if all the variables are in tabu list then if set(abs_unsat_clause_selection).issubset( set(tabu_list)): continue '''We will check for each variale if that variable in UNSAT clause exists in tabu list If yes : The remove that variable from tabu list. It is a preprocessed step to reduce operation cost of checking tabu list after the var selection ''' for index, var in enumerate(abs_unsat_clause_selection): if var in tabu.queue: index_selected_unsat_clause.append(index) # Now lets remove the variables from selected unsat clause which are in tabu list unsat_clause_selection = [ i for j, i in enumerate(unsat_clause_selection) if j not in index_selected_unsat_clause ] # If only single variable is present in the unsat clause after tabu check, then just flip that if len(unsat_clause_selection) == 1: flipped_value_index = abs( unsat_clause_selection[0]) - 1 else: # Computing negative gain of the variables in selected unsat clauses negative_gain = ut.negative_gain( sol_list_init, cnf_formula_sat, unsat_clause_selection) if 0 in negative_gain: '''Checking for the variables with negative gain of 0''' flipped_value_index = self.zero_negative_gain( negative_gain, unsat_clause_selection) else: r = random.random() if r < wp: '''getting a random variable in the selected unsat clauses''' flipped_value_var = random.choice( unsat_clause_selection) flipped_value_index = abs( flipped_value_var) - 1 else: '''Selecting the variable with minimum negative gain''' flipped_value_index = self.min_negative_gain( negative_gain, unsat_clause_selection) '''Manipulating the tabu list''' if tabu.full(): tabu.get() tabu.put(flipped_value_index + 1) '''Flipping the initial_solution variable''' initial_solution[flipped_value_index] = not ( initial_solution[flipped_value_index]) return 'No Solution'