def worstcase1(): """ Solves a worst case graph G_n for n = 1. """ g = io.load_generalized_from_file("assets/strong parity/worstcase_1.txt") (a, c) = gp.generalized_parity_solver(g) return op.are_lists_equal(a, [1, 3, 4, 2, 0]) and op.are_lists_equal(c, [])
def example_2(): """ Solves a simple example. """ g = io.load_generalized_from_file("assets/strong parity/example_2.txt") (a, c) = gp.generalized_parity_solver(g) return op.are_lists_equal(a, [1, 3, 4, 2]) and op.are_lists_equal(c, [])
def worstcase2(): """ Solves a worst case graph G_n for n = 2. """ g = io.load_generalized_from_file("assets/strong parity/worstcase_2.txt") (a, c) = gp.generalized_parity_solver(g) return op.are_lists_equal(a, []) and op.are_lists_equal( c, [6, 8, 9, 7, 5, 4, 0, 2, 1, 3])
def example_1_opposite(): """ Solves a simple example. """ g = gen.opposite_priorities( io.load_generalized_from_file("assets/strong parity/example_1.txt")) (a, c) = gp.generalized_parity_solver(g) return op.are_lists_equal(a, []) and op.are_lists_equal(c, [1, 3, 2])
def simple_example2(): """ Solves a graph which is a simple example for the algorithm. """ g = io.load_generalized_from_file( "assets/generalized parity/simple_example2.txt") (a, c) = gp.generalized_parity_solver(g) return op.are_lists_equal(a, [1, 2]) and op.are_lists_equal(c, [3, 4, 5])
def example_2_doubled(): """ Solves a simple example. """ g = gen.multiple_priorities( io.load_generalized_from_file("assets/strong parity/example_2.txt"), 2) (a, c) = gp.generalized_parity_solver(g) return op.are_lists_equal(a, [1, 3, 4, 2]) and op.are_lists_equal(c, [])
def figure56(): """ Solves the strong parity game from figure 5.6. """ g = io.load_generalized_from_file("assets/strong parity/figure56.txt") (a, c) = gp.generalized_parity_solver(g) return op.are_lists_equal(a, [2, 4, 1, 6]) and op.are_lists_equal( c, [5, 3])
def double_priority(): """ Solves a graph in which the priorities are twice the same. """ g = io.load_generalized_from_file( "assets/generalized parity/double_priority.txt") (a, c) = gp.generalized_parity_solver(g) return op.are_lists_equal(a, []) and op.are_lists_equal( c, [4, 5, 6, 7, 3, 1, 2])
def figure56_opposite(): """ Solves the strong parity game from figure 5.6. """ g = gen.opposite_priorities( io.load_generalized_from_file("assets/strong parity/figure56.txt")) (a, c) = gp.generalized_parity_solver(g) return op.are_lists_equal(a, []) and op.are_lists_equal( c, [2, 4, 1, 6, 5, 3])
def worstcase1_doubled(): """ Solves a worst case graph G_n for n = 1. """ g = gen.multiple_priorities( io.load_generalized_from_file("assets/strong parity/worstcase_1.txt"), 2) (a, c) = gp.generalized_parity_solver(g) return op.are_lists_equal(a, [1, 3, 4, 2, 0]) and op.are_lists_equal(c, [])
def figure56_doubled(): """ Solves the strong parity game from figure 5.6. """ g = gen.multiple_priorities( io.load_generalized_from_file("assets/strong parity/figure56.txt"), 2) (a, c) = gp.generalized_parity_solver(g) return op.are_lists_equal(a, [2, 4, 1, 6]) and op.are_lists_equal( c, [5, 3])
def complementary_priorities(): """ Solves a graph in which the priorities are complementary (one is odd, one is even). This means that player 1 looses from every node (can't have a path even for every priority function) """ g = io.load_generalized_from_file( "assets/generalized parity/complementary_priorities.txt") (a, c) = gp.generalized_parity_solver(g) return op.are_lists_equal(a, []) and op.are_lists_equal( c, [6, 3, 4, 5, 7, 1, 2])
def simple_example(): """ Solves a graph which is a simple example for the algorithm. Player 1 can choose to cycle between two nodes, since center node has priorities (2,2), the path has maximal priority occurring infinitely often 2 for each priority function. """ g = io.load_generalized_from_file( "assets/generalized parity/simple_example.txt") (a, c) = gp.generalized_parity_solver(g) return op.are_lists_equal(a, [1, 2, 3]) and op.are_lists_equal(c, [])
def counter_example(): """ Solves a graph which is one of the counter examples for the naive algorithms. Player 1 cannot avoid cycling between nodes in which 3 will appear infinitely often according to one of the priority function. """ g = io.load_generalized_from_file( "assets/generalized parity/counter_example.txt") (a, c) = gp.generalized_parity_solver(g) return op.are_lists_equal(a, []) and op.are_lists_equal(c, [1, 2, 3])
def benchmark_random_n_nodes(n, k, iterations=3, step=10, plot=False, path=""): """ Benchmarks the classical algorithm for generalized parity games using a random game arenas generator. Arenas of size n with 1 to k priority functions are solved. :param n: number of nodes in generated graph. :param k: number of priority functions in the generated graph. :param iterations: number of times the algorithm is timed (default is 3). :param step: step to be taken in the generation. :param plot: if True, plots the data using matplotlib. :param path: path to the file in which to write the result. """ y = [] # list for the time recordings n_ = [] # list for the x values total_time = 0 # accumulator to record total time nbr_generated = 0 # conserving the number of generated mesures (used to get the index of a mesure) chrono = timer.Timer(verbose=False) # Timer object info = "Time to solve" # info about the current benchmark # print first line of output print u"Generator".center(40) + "|" + u"Nodes (n)".center(12) + "|" + info.center(40) + "\n" + \ "-" * 108 # games generated are size 1 to n for i in range(2, k + 1, step): g = generators.random_generalized(n, i, n, 1, n/2) temp = [] # #iterations calls to the solver are timed for j in range(iterations): with chrono: generalized_parity_solver(g) # solver call temp.append(chrono.interval) # add time recording min_recording = min(temp) y.append(min_recording) # get the minimum out of #iterations recordings n_.append(i) total_time += min_recording print "Random graph".center(40) + "|" + str(i).center(12) + "|" \ + str(y[nbr_generated]).center(40) + "\n" + "-" * 108 nbr_generated += 1 # updating the number of generated mesures # at the end, print total time print "-" * 108 + "\n" + "Total time".center(40) + "|" + "#".center(12) + "|" + \ str(total_time).center(40) + "\n" + "-" * 108 + "\n" if plot: plt.grid(True) plt.title(u"Random graph of size " + str(100)+" with 1 to "+str(k)+" priority functions") plt.xlabel(u'number of nodes') plt.ylabel(u'time (s)') points, = plt.plot(n_, y, 'g.', label=u"Execution time") plt.legend(loc='upper left', handles=[points]) plt.savefig(path) plt.clf() plt.close()
def solver(): """ Takes appropriate actions according to the chosen options (using command_line_handler() output). """ # Parsing the command line arguments args = command_line_handler() if args.mode == "solve": """ ----- Solving mode ----- """ if args.gp: g = tools.load_generalized_from_file(args.inputFile) # we have a generalized parity game arena else: g = tools.load_from_file(args.inputFile) # loading game from the input file player = 0 # default player is 0, so solution comes as (W_0,sigma_0), (W_1,sigma_1) or (W_0, W_1) # Reachability (target and player is set) if args.target is not None: player = int(args.target[0]) # getting player (as int), replacing default player target = map(int, args.target[1].split(",")) # getting node ids in target (transforming them into int) solution = reachability.reachability_solver(g, target, player) # calling reachability solver ops.print_solution(solution, player) # printing the solution # Safety (safe set provided) if args.safe is not None: player = 1 # the player with the reachability objective (to write the solution later) safe_set = map(int, args.safe[0].split(",")) # getting node ids in safe set (transforming them into int) target_set = [] # adds every node not in the safe set to the target set for node in g.get_nodes(): if not (node in safe_set): target_set.append(node) # the solution comes out as (W_1,sigma_1), (W_0,sigma_0) solution = reachability.reachability_solver(g, target_set, 1) # calling reachability solver with target set for player 1 (2) ops.print_solution(solution, 1) # printing the solution, player 1 (2) has the reachability objective # Weak parity elif args.wp: solution = weakparity.weak_parity_solver(g) # calling weak parity solver on the game ops.print_solution(solution, player) # printing the solution # Strong parity (an algorithm is chosen) elif args.parity_algorithm is not None: if (args.parity_algorithm == 'recursive'): solution = strongparity.strong_parity_solver(g) # calling recursive algorithm for parity games ops.print_solution(solution, player) # printing the solution (with strategy) elif (args.parity_algorithm == 'safety'): solution = strongparity.reduction_to_safety_parity_solver(g) # calling reduction to safety algorithm ops.print_winning_regions(solution[0], solution[1]) # printing the solution (without strategy) elif (args.parity_algorithm == 'antichain'): # calling antichain-based algorithm, assumes indexes start with 1 solution = strongparity.strong_parity_antichain_based(g,1) ops.print_winning_regions(solution[0], solution[1]) # printing the solution (without strategy) else: # this should not happen solution = None # Generalized parity elif args.gp: solution = generalizedparity.generalized_parity_solver(g) # calling classical algorithm for generalized parity games ops.print_winning_regions(solution[0], solution[1]) # printing the solution (without strategy) # If output option is chosen and the algorithm is the classical algo for generalized parity games, use special # function dedicated to writing solution of generalized parity games (need to consider several priorities) if (args.outputFile is not None) and args.gp: tools.write_generalized_solution_to_file(g, solution[0], solution[1], args.outputFile) # If output option is chosen and the algorithm is the reduction to safety algorithm for parity games or the # antichain-based algorithm for parity games then the output is only the winning regions, not the strategies elif (args.outputFile is not None) and (args.parity_algorithm == 'safety' or args.parity_algorithm == 'antichain'): tools.write_solution_to_file_no_strategies(g, solution[0], solution[1], args.outputFile) # Else the regular regions + strategies are output elif args.outputFile is not None: tools.write_solution_to_file(g, solution, player, args.outputFile) elif args.mode == "bench": """ ----- Benchmark mode ----- """ max = args.max step = args.step rep = args.repetitions plot = args.outputPlot is not None # Reachability if args.reachability_type is not None: if args.reachability_type == 'complete0': r_bench.benchmark(max, generators.complete_graph, [1], 0, iterations=rep, step=step, plot=plot, regression=True, order=2, path=args.outputPlot, title=u"Graphes complets de taille 1 à " + str(max)) elif args.reachability_type == 'complete1': r_bench.benchmark(max, generators.complete_graph, [1], 1, iterations=rep, step=step, plot=plot, regression=True, order=2, path=args.outputPlot, title=u"Graphes complets de taille 1 à " + str(max)) elif args.reachability_type == 'worstcase': r_bench.benchmark(max, generators.reachability_worst_case, [1], 0, iterations=rep, step=step, plot=plot, regression=True, order=2, path=args.outputPlot, title=u"Graphes 'pire cas' de taille 1 à " + str(max)) # Weak parity elif args.weakparity_type is not None: if args.weakparity_type == 'complete': wp_bench.benchmark(max, generators.complete_graph_weakparity, iterations=rep, step=step, plot=plot, regression=True, order=2, path=args.outputPlot, title=u"Graphes complets de taille 1 à " + str(max)) elif args.weakparity_type == 'worstcase': wp_bench.benchmark(max, generators.weak_parity_worst_case, iterations=rep, step=step, plot=plot, regression=True, order=3, path=args.outputPlot, title=u"Graphes 'pire cas' de taille 1 à " + str(max)) # parity elif args.parity_type is not None: if args.parity_type == 'recursive-random': sp_bench.benchmark_random(max, iterations=rep, step=step, plot=plot,path=args.outputPlot) elif args.parity_type == 'safety-random': sp_bench.benchmark_random_reduction(max, iterations=rep, step=step, plot=plot,path=args.outputPlot) elif args.parity_type == 'antichain-random': sp_bench.benchmark_random_antichain_based(max, iterations=rep, step=step, plot=plot,path=args.outputPlot) elif args.parity_type == 'recursive-worstcase': sp_bench.benchmark_worst_case(max, iterations=rep, step=step, plot=plot, path=args.outputPlot) elif args.parity_type == 'safety-worstcase': sp_bench.benchmark_worst_case_reduction(max, iterations=rep, step=step, plot=plot,path=args.outputPlot) elif args.parity_type == 'antichain-worstcase': sp_bench.benchmark_worst_case_antichain_based(max, iterations=rep, step=step, plot=plot,path=args.outputPlot) # generalized parity else: gp_bench.benchmark_random_k_functions(max,3,iterations=rep, step=step, plot=plot, path=args.outputPlot) elif args.mode == "test": sp_test_result = sp_test.launch_tests() wp_test_result = wp_test.launch_tests() r_test_result = r_test.launch_tests() gp_test_result = gp_test.launch_tests() if (sp_test_result and wp_test_result and r_test_result and gp_test_result): print "All tests passed with success" else: print "Some tests failed"