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()
Beispiel #16
0
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"