- 26.1k
- 13
- 47
- 113
Where could I optmize this slow 3sat algorithm
i'm currently trying to solve this problem: https://open.kattis.com/problems/satisfiability
Alice recently started to work for a hardware design company and as a part of her job, she needs to identify defects in fabricated integrated circuits. An approach for identifying these defects boils down to solving a satisfiability instance. She needs your help to write a program to do this task.
Input
The first line of input contains a single integer, not more than 5, indicating the number of test cases to follow. The first line of each test case contains two integers n and m where 1≤n≤20 indicates the number of variables and 1≤m≤100 indicates the number of clauses. Then, m lines follow corresponding to each clause. Each clause is a disjunction of literals in the form Xi or ~Xi for some 1≤i≤n, where ~Xi indicates the negation of the literal Xi. The "or" operator is denoted by a ‘v’ character and is seperated from literals with a single space.Output
For each test case, display satisfiable on a single line if there is a satisfiable assignment; otherwise display unsatisfiable.
And I have this code:
import sys
cases = int(sys.stdin.readline())
def GetReverse(literal):
if literal[0] == '~':
return literal[1:]
else:
return '~' + literal
for i in range(cases):
vars, clauses = map(int, sys.stdin.readline().split())
mySets = []
firstClause = sys.stdin.readline().strip().split(" v ")
for c in firstClause:
this = set()
this.add(c)
mySets.append(this)
for i in range(clauses-1):
tempSets = []
currentClause = sys.stdin.readline().strip().split(" v ")
for s in mySets:
for literal in currentClause:
if not s.__contains__(GetReverse(literal)):
newset = s.copy()
newset.add(literal)
tempSets.append(newset)
mySets = tempSets
if mySets:
print("satisfiable")
else:
print("unsatisfiable")
This code basically maintains "mySets" which is a list of sets, which all represent possible combinations of literals that could make the entire statement true. every time we parse a new clause, we check if it's negation exists already in a set, if it does, the set is not included.
for i in range(clauses-1):
tempSets = []
currentClause = sys.stdin.readline().strip().split(" v ")
for s in mySets:
for literal in currentClause:
if not s.__contains__(GetReverse(literal)):
newset = s.copy()
newset.add(literal)
tempSets.append(newset)
mySets = tempSets
It's obvious that the problem lies somewhere here, indented forloops just arent great, but 3sat should be at least exponential anyway. Could i do the same thing as I do here, using one less loop? thanks a lot
- 165
- 4