You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

175 lines
5.5 KiB

6 years ago
6 years ago
6 years ago
6 years ago
5 years ago
6 years ago
5 years ago
6 years ago
  1. #!/usr/bin/env python3
  2. import numpy as np
  3. from . import kSAT
  4. from tqdm import tqdm
  5. import math
  6. __VERTEX_WEIGHT__ = -1
  7. __EDGE_WEIGHT__ = 2
  8. def WMISdictQUBO(kSATInstance):
  9. quboInstance = {}
  10. for clauseIndex in range(kSATInstance.getNumberOfClauses()):
  11. clause = kSATInstance.getClause(clauseIndex)
  12. # build triangles
  13. for varIndexInClause in range(len(clause)):
  14. label = kSATInstance.getLableOfBinding(clauseIndex,
  15. clause[varIndexInClause])
  16. quboInstance[(label, label)] = __VERTEX_WEIGHT__
  17. for i in range(varIndexInClause + 1, len(clause)):
  18. targetLabel = kSATInstance.getLableOfBinding(clauseIndex,
  19. clause[i])
  20. quboInstance[(label, targetLabel)] = __EDGE_WEIGHT__
  21. # connect conflicts
  22. for conflict in kSATInstance.getConflicts():
  23. quboInstance[(conflict[0], conflict[1])] = __EDGE_WEIGHT__
  24. return quboInstance
  25. # only 3sat
  26. def primitiveQUBO(sat):
  27. quboInstance = {}
  28. chains = {}
  29. for clauseIndex in range(sat.getNumberOfClauses()):
  30. clause = sat.getClause(clauseIndex);
  31. #build clause primitives
  32. lit1 = "c{}_l{}".format(clauseIndex, clause[0])
  33. lit2 = "c{}_l{}".format(clauseIndex, clause[1])
  34. lit3 = "c{}_l{}".format(clauseIndex, clause[2])
  35. aux1 = "a{}_{}".format(clauseIndex, 1)
  36. aux2 = "a{}_{}".format(clauseIndex, 2)
  37. aux3 = "a{}_{}".format(clauseIndex, 3)
  38. aux4 = "a{}_{}".format(clauseIndex, 4)
  39. quboInstance[(lit1, lit1)] = 1;
  40. quboInstance[(lit2, lit2)] = 1;
  41. quboInstance[(lit3, lit3)] = 1;
  42. quboInstance[(aux1, aux1)] = -2;
  43. quboInstance[(aux2, aux2)] = 1;
  44. quboInstance[(aux3, aux3)] = -2;
  45. quboInstance[(aux4, aux4)] = -2;
  46. quboInstance[(lit1, lit2)] = 1;
  47. quboInstance[(lit1, aux1)] = -2;
  48. quboInstance[(lit2, aux1)] = -2;
  49. quboInstance[(aux1, aux2)] = -2;
  50. quboInstance[(aux2, aux3)] = -2;
  51. quboInstance[(aux2, lit3)] = 1;
  52. quboInstance[(lit3, aux3)] = -2;
  53. quboInstance[(aux3, aux4)] = -2;
  54. if clause[0] in chains:
  55. chains[clause[0]].append(lit1)
  56. else:
  57. chains[clause[0]] = [lit1]
  58. if clause[1] in chains:
  59. chains[clause[1]].append(lit2)
  60. else:
  61. chains[clause[1]] = [lit2]
  62. if clause[2] in chains:
  63. chains[clause[2]].append(lit3)
  64. else:
  65. chains[clause[2]] = [lit3]
  66. #build chains
  67. longestChain = 0;
  68. for lit, nodes in chains.items():
  69. if len(nodes) > longestChain:
  70. longestChain = len(nodes)
  71. if lit > 0 and -1 * lit in chains:
  72. quboInstance[(chains[lit][0], chains[-1*lit][0])] = 2
  73. print("longest chain = {}".format(longestChain))
  74. for nodes in chains.values():
  75. while len(nodes) > 1:
  76. quboInstance[(nodes[0], nodes[1])] = -2;
  77. nodes.pop(0)
  78. return quboInstance
  79. class QuboWriter:
  80. def __init__(self, qubo):
  81. self.__labelIndexDict = {}
  82. self.__qubo = qubo
  83. self.__initLabelIndexDict(self.__qubo)
  84. print(self.__labelIndexDict)
  85. def __initLabelIndexDict(self, qubo):
  86. indexCount = 0
  87. for coupler in qubo:
  88. label1 = coupler[0]
  89. label2 = coupler[1]
  90. if label1 not in self.__labelIndexDict:
  91. self.__labelIndexDict[label1] = indexCount
  92. indexCount += 1
  93. if label2 not in self.__labelIndexDict:
  94. self.__labelIndexDict[label2] = indexCount
  95. indexCount += 1
  96. def write(self, filePath):
  97. quboFile = open(filePath, "w")
  98. self.__writeQuboFileHeader(quboFile)
  99. self.__writeQuboFileNodes(quboFile)
  100. self.__writeQuboFileCouplers(quboFile)
  101. quboFile.close()
  102. def __writeQuboFileHeader(self, quboFile):
  103. numberOfNodes = len(self.__labelIndexDict)
  104. numberOfCouplers = len(self.__qubo) - numberOfNodes
  105. quboFile.write("c\n")
  106. quboFile.write("c this is a generated qubo file\n")
  107. quboFile.write("c\n")
  108. quboFile.write("p qubo 0 %d %d %d\n" %(numberOfNodes,
  109. numberOfNodes,
  110. numberOfCouplers))
  111. def __writeQuboFileNodes(self, quboFile):
  112. for label in self.__labelIndexDict:
  113. self.__writeCoupler(quboFile, (label, label))
  114. def __writeCoupler(self, quboFile, coupler):
  115. indices = self.__getNodeIndicesFromCoupler(coupler)
  116. quboFile.write("%d %d %d\n" % (indices[0],
  117. indices[1],
  118. self.__qubo[coupler]))
  119. def __getNodeIndicesFromCoupler(self, coupler):
  120. index1 = self.__labelIndexDict[coupler[0]]
  121. index2 = self.__labelIndexDict[coupler[1]]
  122. if index1 <= index2:
  123. return [index1, index2]
  124. else:
  125. return [index2, index1]
  126. def __writeQuboFileCouplers(self, quboFile):
  127. for coupler in self.__qubo:
  128. if coupler[0] != coupler[1]:
  129. self.__writeCoupler(quboFile, coupler)