|
|
- #!/usr/bin/env python3
-
- import argparse
- import os
- import glob
- import json
- import numpy as np
- import matplotlib.pyplot as plt
- import collections
-
- def main():
- args = __parseArguments()
-
- __stats(args["comparisonDir"], args["outputDir"])
-
-
- def __parseArguments():
- parser = argparse.ArgumentParser()
- parser.add_argument("-d", "--directory", help="the direcotry with all comparison files", type=str)
- parser.add_argument("-o", "--output", help="Directory to store the stats", type=str)
- args = parser.parse_args()
-
- arguments = {}
- print(args)
-
- arguments["comparisonDir"] = args.directory
- if arguments["comparisonDir"] == None:
- arguments["comparisonDir"] = str(input("Comparison directory: "))
-
- arguments["comparisonDir"] = os.path.abspath(arguments["comparisonDir"])
-
- arguments["outputDir"] = args.output
- if arguments["outputDir"] == None:
- arguments["outputDir"] = str(input("Output directory: "))
-
- arguments["outputDir"] = os.path.abspath(arguments["outputDir"])
-
- return arguments
-
- def __stats(comparisonDir, outputDir):
- stats = __collectStats(comparisonDir)
-
- __writeStats(stats, outputDir)
-
- def __collectStats(comparisonDir):
- files = glob.glob(os.path.join(comparisonDir, "*.cmp"))
-
- stats = []
-
- for path in files:
-
- comparison = __readComparison(path)
-
- stats.append(__processSingleInstance(comparison))
-
- return stats
-
-
- def __processSingleInstance(comparison):
- instanceStats = {}
-
- degrees = comparison["degrees_of_variables"]
- degreeArr = np.array(list(degrees.values()))
-
- instanceStats["degree_of_variables_mean"] = degreeArr.mean()
- instanceStats["degree_of_variables_median"] = np.median(degreeArr)
- instanceStats["degree_of_variables_std_dev"] = np.std(degreeArr)
- instanceStats["degree_of_variables_max"] = degreeArr.max()
- instanceStats["degree_of_variables_min"] = degreeArr.min()
- instanceStats["variables_per_degree"] = __getVarsPerDegree(degreeArr)
-
- if comparison["minisat_satisfiable"]:
- if __instanceIsFalseNegative(comparison):
- instanceStats["result"] = "false_negative"
- else:
- instanceStats["result"] = "satisfiable"
- else:
- instanceStats["result"] = "unsatisfiable"
-
- return instanceStats
-
- def __instanceIsFalseNegative(comparison):
- return (comparison["minisat_satisfiable"] == True and
- comparison["qubo_satisfiable"] == False)
-
- def __getVarsPerDegree(degreeArr):
- degCount = collections.Counter(degreeArr)
-
- varsPerDegree = {}
-
- for degree in degCount:
- varsPerDegree[degree] = degCount[degree]
-
- return varsPerDegree
-
-
- def __readComparison(path):
- cmpFile = open(path, "r")
- comparison = json.load(cmpFile)
- cmpFile.close()
-
- return comparison
-
-
- def __writeStats(stats, outputDir):
-
- fig1 = plt.figure()
-
- data = __seperateMatchesAndFalseNegatives(stats)
-
- ax0 = fig1.add_subplot(141,)
- ax0.boxplot([data["mean"]["satisfiable"],
- data["mean"]["false_negative"],
- data["mean"]["unsatisfiable"]])
- ax0.set_title("mean")
-
- ax1 = fig1.add_subplot(142, sharey=ax0)
- ax1.boxplot([data["median"]["satisfiable"],
- data["median"]["false_negative"],
- data["median"]["unsatisfiable"]])
- ax1.set_title("median")
-
- ax2 = fig1.add_subplot(143, sharey=ax0)
- ax2.boxplot([data["max"]["satisfiable"],
- data["max"]["false_negative"],
- data["max"]["unsatisfiable"]])
- ax2.set_title("max degree")
-
- ax3 = fig1.add_subplot(144, sharey=ax0)
- ax3.boxplot([data["min"]["satisfiable"],
- data["min"]["false_negative"],
- data["min"]["unsatisfiable"]])
- ax3.set_title("min degree")
-
-
- fig2 = plt.figure()
- ax4 = fig2.add_subplot(111)
- ax4.boxplot([data["std_dev"]["satisfiable"],
- data["std_dev"]["false_negative"],
- data["std_dev"]["unsatisfiable"]])
- ax4.set_title("standard deviation")
-
-
- _BINS_ = 23
-
- fig3 = plt.figure()
- ax5 = fig3.add_subplot(311)
- varsPerDegreeSat = __accumulateVarsPerDegree(data["vars_per_degree"]["satisfiable"])
- ax5.hist(varsPerDegreeSat, density=True, bins=_BINS_)
-
- ax6 = fig3.add_subplot(312, sharex=ax5)
- varsPerDegreeFP = __accumulateVarsPerDegree(data["vars_per_degree"]["false_negative"])
- ax6.hist(varsPerDegreeFP, density=True, bins=_BINS_)
-
- ax7 = fig3.add_subplot(313, sharex=ax6)
- varsPerDegreeUnsat = __accumulateVarsPerDegree(data["vars_per_degree"]["unsatisfiable"])
- ax7.hist(varsPerDegreeUnsat, density=True, bins=_BINS_)
-
-
- plt.setp([ax0, ax1, ax2, ax3, ax4], xticks=[1, 2, 3], xticklabels=["satisfiable",
- "false negative",
- "unsatisfiable"])
- plt.setp(ax0.get_xticklabels(), rotation=45)
- plt.setp(ax1.get_xticklabels(), rotation=45)
- plt.setp(ax2.get_xticklabels(), rotation=45)
- plt.setp(ax3.get_xticklabels(), rotation=45)
- plt.setp(ax4.get_xticklabels(), rotation=45)
- fig1.set_size_inches(12, 8)
- fig1.suptitle("Degrees of variables", fontsize=16)
-
- fig2.set_size_inches(4, 8)
-
- fig3.set_size_inches(5, 12)
-
- fig1.savefig(os.path.join(outputDir, "degrees1.png"))
- fig2.savefig(os.path.join(outputDir, "degrees2.png"))
- fig3.savefig(os.path.join(outputDir, "degrees3.png"))
-
- plt.show()
-
-
- def __accumulateVarsPerDegree(listOfVarsPerDegreeDicts):
- accumulated = []
-
- for instance in listOfVarsPerDegreeDicts:
- for degree in instance:
- accumulated += [degree] * instance[degree]
-
- return accumulated
-
- def __compressVarsPerDegree(listOfVarsPerDegreeDicts):
- compressed = {}
-
- countOfVars = 0
-
- for instance in listOfVarsPerDegreeDicts:
- for degree in instance:
- if degree in compressed:
- compressed[degree] += float(instance[degree])
- else:
- compressed[degree] = float(instance[degree])
-
- countOfVars += instance[degree]
-
- check = 0
- for degree in compressed:
- compressed[degree] /= countOfVars
-
- check += compressed[degree]
-
-
- print("check: ", check)
-
- return compressed
-
-
- def __seperateMatchesAndFalseNegatives(stats):
- data = {}
- data["mean"] = {"false_negative": [],
- "satisfiable": [],
- "unsatisfiable": []}
-
- data["median"] = {"false_negative": [],
- "satisfiable": [],
- "unsatisfiable": []}
-
- data["std_dev"] = {"false_negative": [],
- "satisfiable": [],
- "unsatisfiable": []}
-
- data["max"] = {"false_negative": [],
- "satisfiable": [],
- "unsatisfiable": []}
-
- data["min"] = {"false_negative": [],
- "satisfiable": [],
- "unsatisfiable": []}
-
- data["vars_per_degree"] = {"false_negative": [],
- "satisfiable": [],
- "unsatisfiable": []}
-
- for instance in stats:
- target = instance["result"]
-
- data["mean"][target].append(instance["degree_of_variables_mean"])
- data["median"][target].append(instance["degree_of_variables_median"])
- data["std_dev"][target].append(instance["degree_of_variables_std_dev"])
- data["max"][target].append(instance["degree_of_variables_max"])
- data["min"][target].append(instance["degree_of_variables_min"])
- data["vars_per_degree"][target].append(instance["variables_per_degree"])
-
- return data
-
- if __name__ == "__main__":
- main()
|