Skip to content

Commit

Permalink
new generators
Browse files Browse the repository at this point in the history
  • Loading branch information
damianoazzolini committed Nov 30, 2024
1 parent 58ec2e2 commit 3edc998
Show file tree
Hide file tree
Showing 3 changed files with 260 additions and 20 deletions.
144 changes: 144 additions & 0 deletions benchmark/map/generate_graph_coloring_map.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
import argparse
import random
import sys

def parse_args():
"""
Arguments parser.
"""
command_parser = argparse.ArgumentParser(
description="Generate datasets with increasing rule numbers",
# epilog="Example: ",
formatter_class=argparse.ArgumentDefaultsHelpFormatter
)

command_parser.add_argument(
"-n",
help="Number of probabilistic facts",
type=int,
required=True
)

command_parser.add_argument(
"--map",
help="Percentage of query atoms",
type=float,
default=0
)

command_parser.add_argument(
"--aspmc",
help="Generate aspmc version with shifted negation",
action="store_true"
)

command_parser.add_argument(
"--prob",
help="Set the probability value (default random)",
type=float,
default=-1
)

command_parser.add_argument(
"--seed",
help="Seed for random numbers generator",
type=int,
default=42
)

return command_parser.parse_args()


def get_random_float() -> float:
"""
Get random float truncated at 3 decimals.
"""
return float(str(random.random())[:5])


def main():
"""
Main body.
"""
args = parse_args()
if args.n < 6:
print("n must be at least 6.")
sys.exit()

if args.map < 0 or args.map > 1:
print("map must be between 0 or 1, or not specified")
sys.exit()

random.seed(args.seed)

preamble = """
red(X) :- node(X), not green(X), not blue(X).
green(X) :- node(X), not red(X), not blue(X).
blue(X) :- node(X), not red(X), not green(X).
e(X,Y) :- edge(X,Y).
e(Y,X) :- edge(Y,X).
:- e(X,Y), red(X), red(Y).
:- e(X,Y), green(X), green(Y).
:- e(X,Y), blue(X), blue(Y).
qr:- blue(3).
red(1).
green(4).
green(6).
"""

if args.aspmc:
preamble = preamble.replace('not', '\+')

print(preamble)

already_in = [[1, 2], [1, 3], [2, 5], [2, 6], [3, 4], [4, 5], [5, 6]]

# generate the probabilistic facts
for _ in range(0, args.n - 6 + 1):
n0 = random.randint(1, args.n)
n1 = random.randint(1, args.n)
l = [n0, n1]
l.sort()

if l in already_in:
n0 = n1

while (n1 == n0):
n1 = random.randint(1, args.n)
l = [n0, n1]
l.sort()
if l in already_in:
n1 = n0

already_in.append(l)

# write the probabilistic facts
prob_atoms : 'list[float]' = []
for _ in range(args.n + 2):
prob = args.prob if (args.prob > 0 and args.prob < 1) else get_random_float()
prob_atoms.append(prob)

selected_query_atoms = []
if args.map >= 0:
n_map = int((args.n + 2) * args.map)
selected_query_atoms = random.sample(range(args.n + 2), n_map)

for idx, l in enumerate(already_in):
if idx in selected_query_atoms:
prefix = "map "
else:
prefix = ""

print(f"{prefix}{prob_atoms[idx]}::edge({l[0]},{l[1]}).")

flat_list = [item for sublist in already_in for item in sublist]
for j in range(1, max(flat_list) + 1):
print(f"node({j}).")


if __name__ == "__main__":
main()
40 changes: 20 additions & 20 deletions benchmark/map/generate_map_benchmarks.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import argparse
import copy
import random
import sys

def parse_args():
"""
Expand All @@ -14,9 +13,10 @@ def parse_args():
)

command_parser.add_argument(
"program",
"--program",
help="Type of programs to generate.",
type=str,
required=True,
choices=["1","2", "3", "4"]
)

Expand All @@ -26,12 +26,6 @@ def parse_args():
type=int,
required=True
)

command_parser.add_argument(
"--mpe",
help="For MPE (all query atoms)",
action="store_true"
)

command_parser.add_argument(
"--map",
Expand All @@ -53,6 +47,13 @@ def parse_args():
help="Generate aspmc version with shifted negation",
action="store_true"
)

command_parser.add_argument(
"--prob",
help="Set the probability value (default random)",
type=float,
default=-1
)

command_parser.add_argument(
"--seed",
Expand All @@ -72,21 +73,24 @@ def get_random_float() -> float:
def print_query_atoms(args : argparse.Namespace):
"""
Prints query atoms and probabilistic facts.
Convoluted way but keeps the same probaiblity among different
runs with different map values.
"""
prob_atoms : 'list[float]' = []
for _ in range(args.n):
prob = args.prob if (args.prob > 0 and args.prob < 1) else get_random_float()
prob_atoms.append(prob)

selected_query_atoms = []
if args.map >= 0:
n_map = int(args.n * args.map)
selected_query_atoms = random.sample(range(args.n), n_map)

for i in range(args.n):
if args.mpe:
print(f"map {get_random_float()}::a{i}.")
for idx, p in enumerate(prob_atoms):
if idx in selected_query_atoms:
print(f"map {p}::a{idx}.")
else:
if i in selected_query_atoms:
print(f"map {get_random_float()}::a{i}.")
else:
print(f"{get_random_float()}::a{i}.")

print(f"{p}::a{idx}.")

def generate_first_type_programs(args : argparse.Namespace):
"""
Expand Down Expand Up @@ -251,10 +255,6 @@ def main():
args = parse_args()
print(f"% {args}")

if not args.mpe and args.map == -1:
print("Select either map or mpe.")
sys.exit()

random.seed(args.seed)

if args.program == "1":
Expand Down
96 changes: 96 additions & 0 deletions benchmark/map/generate_reachability_map.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import argparse
import random
import networkx
import sys

def parse_args():
"""
Arguments parser.
"""
command_parser = argparse.ArgumentParser(
description="Generate datasets with increasing rule numbers",
# epilog="Example: ",
formatter_class=argparse.ArgumentDefaultsHelpFormatter
)

command_parser.add_argument(
"-n",
help="Number of probabilistic facts",
type=int,
required=True
)

command_parser.add_argument(
"--map",
help="Percentage of query atoms",
type=float,
default=0
)

command_parser.add_argument(
"--prob",
help="Set the probability value (default random)",
type=float,
default=-1
)

command_parser.add_argument(
"--seed",
help="Seed for random numbers generator",
type=int,
default=42
)

return command_parser.parse_args()


def get_random_float() -> float:
"""
Get random float truncated at 3 decimals.
"""
return float(str(random.random())[:5])

def print_query_atoms(args : argparse.Namespace):
"""
Prints query atoms and probabilistic facts.
Convoluted way but keeps the same probaiblity among different
runs with different map values.
"""
prob_atoms : 'list[float]' = []
for _ in range(args.n):
prob = args.prob if (args.prob > 0 and args.prob < 1) else get_random_float()
prob_atoms.append(prob)

selected_query_atoms = []
if args.map >= 0:
n_map = int(args.n * args.map)
selected_query_atoms = random.sample(range(args.n), n_map)

for idx, p in enumerate(prob_atoms):
if idx in selected_query_atoms:
print(f"map {p}::node({idx}).")
else:
print(f"{p}::node({idx}).")


def main():
"""
Main.
"""
args = parse_args()
random.seed(args.seed)

print("reaches(X,Y) :- edge(X,Y), node(X), node(Y).")
print("reaches(X,Y) :- edge(X,Z), reaches(Z,Y), node(X), node(Y), node(Z).")
print(f"qr:- reaches(0,{args.n - 1}).")

g = networkx.complete_graph(args.n)

for edge in g.edges:
print(f"edge({edge[0]},{edge[1]}).")

print_query_atoms(args)


if __name__ == "__main__":
main()

0 comments on commit 3edc998

Please sign in to comment.