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.

139 lines
3.8 KiB

  1. #!python3
  2. from pysat.formula import CNF
  3. from pysat.solvers import Glucose4
  4. import pathlib as pl
  5. import random
  6. import bz2
  7. import sys
  8. import argparse
  9. CORE_DIR = pl.Path("./cores")
  10. EXTENDED_DIR = pl.Path("./extensions")
  11. def main():
  12. args = parse_args()
  13. instances = get_instance_paths(pl.Path(args.instance_dir))
  14. CORE_DIR = pl.Path(args.cores_dir)
  15. EXTENDED_DIR = pl.Path(args.extensions_dir)
  16. for instance in instances:
  17. run(instance, args.nr_per_instance, args.verbosity > 0)
  18. def parse_args():
  19. parser = argparse.ArgumentParser()
  20. parser.add_argument( "-i"
  21. ,"--instance_dir"
  22. ,type=str
  23. ,default="./instances"
  24. ,help="directory containing the instances")
  25. parser.add_argument( "-c"
  26. ,"--cores_dir"
  27. ,type=str
  28. ,default="./cores"
  29. ,help="directory containing the cores")
  30. parser.add_argument( "-e"
  31. ,"--extensions_dir"
  32. ,type=str
  33. ,default="./extensions"
  34. ,help="directory target directory to store the generated core extensions")
  35. parser.add_argument( "-n"
  36. ,"--nr_per_instance"
  37. ,type=int
  38. ,default=1
  39. ,help="number of extensions per instance")
  40. parser.add_argument( "-v"
  41. ,"--verbosity"
  42. ,type=int
  43. ,default=1
  44. ,help="1 to print progress, 0 for silent mode")
  45. return parser.parse_args()
  46. def get_instance_paths(instances_dir):
  47. instances = []
  48. for p in instances_dir.iterdir():
  49. if str(p).endswith(".cnf.bz2"):
  50. instances.append(p)
  51. return instances
  52. def run(instance, calls_per_instance, verb):
  53. ipath = pl.Path(instance)
  54. iname = ipath.stem[:-4]
  55. f = CNF(str(ipath))
  56. cores = parse_cores(iname)
  57. for i in range(calls_per_instance):
  58. extension = gen_extension(cores)
  59. if verb and i % 20 == 0:
  60. print("instance: {}".format(iname))
  61. if verb:
  62. print("extension: {} | #cores: {} ({:2.2f}%)".format(i+1, len(extension), 100 * len(extension) / len(cores)))
  63. ext_f = CNF()
  64. ext_f.extend(extension)
  65. fpath, nr = next_file_path(iname)
  66. if not EXTENDED_DIR.exists():
  67. EXTENDED_DIR.mkdir(parents=True)
  68. ext_f.to_file(fpath,
  69. comments=["c extending:{} nr:{}".format(iname, nr),
  70. "c number of cores: {}".format(len(extension))],
  71. compress_with="bzip2")
  72. if verb:
  73. print()
  74. def gen_extension(cores):
  75. p = (len(cores) / 10 ) / len(cores)
  76. extension = []
  77. while len(extension) == 0:
  78. for core in cores:
  79. if p >= random.random():
  80. extension.append(core)
  81. return extension
  82. def parse_cores(instance):
  83. cores = []
  84. with bz2.open(CORE_DIR / (instance + ".cores.bz2"), "tr") as cores_file:
  85. cores = list(map(lambda l: l.strip(), cores_file.readlines()))
  86. cores = list(map(lambda l: l.split(","), cores))
  87. for i in range(len(cores)):
  88. cores[i] = list(map(int, cores[i]))
  89. cores[i] = list(map(lambda lit: -1 * lit, cores[i]))
  90. return cores
  91. def next_file_path(name):
  92. counter = 0
  93. ext_file_path = EXTENDED_DIR / ("{}_{:04}.cnf.bz2".format(name, counter))
  94. while ext_file_path.exists():
  95. counter += 1
  96. ext_file_path = EXTENDED_DIR / ("{}_{:04}.cnf.bz2".format(name, counter))
  97. return ext_file_path, counter
  98. if __name__ == "__main__":
  99. main()