Exemplo n.º 1
0
def gen_random_vertex_positions(num_verts, num_edges, num_dims, min_pos,
                                max_pos, precision, out):
    if edges_in_complete_undirected_graph(num_verts) != num_edges:
        die('not yet implemented error: gen_random_vertex_positions only works for generating complete graphs'
            )

    # generate all of the coordinates in one big array
    coords = [
        __rnd.uniform(min_pos, max_pos) for _ in range(num_verts * num_dims)
    ]

    print_input_header(num_verts, num_edges, out)

    # print the edge weights for each pair
    fmt = '%u %u %.' + str(precision) + 'f'
    for i in range(0, num_verts):
        io = i * num_dims
        for j in range(i + 1, num_verts):
            jo = j * num_dims
            print >> out, fmt % (i + 1, j + 1,
                                 sqrt(
                                     sum([(coords[io + o] - coords[jo + o]) *
                                          (coords[io + o] - coords[jo + o])
                                          for o in range(num_dims)])))

    return "m=%d n=%d d=%d min=%.1f max=%.1f prec=%d seed=%s" % (
        num_verts, num_edges, num_dims, min_pos, max_pos, precision,
        str(__RND_SEED))
Exemplo n.º 2
0
def main(argv=sys.argv):
    if len(argv) != 2:
        die("""usage: check_with_diff.py INPUT_GRAPH
Checks the current mst for a given input file and reports the diff, if any.  It
does not do anything smart in terms of caching the correctness checker's output,
so it will be recomputed every time this is run.
""")
    else:
        input_graph = argv[1]

    if not os.path.exists(input_graph):
        die("%s not found" % input_graph)

    # get our mst output
    mst = get_path_to_mst_binary(make_sure_it_exists=False)
    mst_out = random_tmp_filename(10)
    if os.system('%s %s > %s' % (mst, input_graph, mst_out)) != 0:
        quiet_remove(mst_out)
        die("failed to run mst (or exited with an error code)")

    # get the checker's output
    checker = get_path_to_checker_binary(make_sure_it_exists=True)
    checker_out = random_tmp_filename(10)
    if os.system('%s %s true > %s' % (checker, input_graph, checker_out)) != 0:
        quiet_remove(mst_out)
        quiet_remove(checker_out)
        die("failed to run checker (or exited with an error code)")

    # check just the MST weight first
    mst_w = extract_answer(mst_out)
    checker_w = extract_answer(checker_out)
    fmt = '%.1f'  # tolerance to 1 decimal place
    str_mst_w = fmt % mst_w
    str_checker_w = fmt % checker_w
    if str_mst_w == str_checker_w:
        print 'Weights match! %s %s' % (str_mst_w, str_checker_w)
        quiet_remove(mst_out)
        quiet_remove(checker_out)
        return 0
    else:
        print 'Weight mistmatch, comparing vertices!! (checker_mst (%s) - our_mst (%s) = %s)' % (
            str(checker_w), str(mst_w), str(checker_w - mst_w))

    # sort them
    mst_out2 = random_tmp_filename(10)
    checker_out2 = random_tmp_filename(10)
    sort_and_order = get_path_to_project_root(
    ) + 'src/input/sort_and_order.py '
    os.system(sort_and_order + mst_out + ' 1 > ' + mst_out2)
    os.system(sort_and_order + checker_out + ' 1 > ' + checker_out2)

    # compare them
    os.system('diff %s %s && echo Edges are the same!' %
              (checker_out2, mst_out2))
    quiet_remove(mst_out)
    quiet_remove(mst_out2)
    quiet_remove(checker_out)
    quiet_remove(checker_out2)
    return 0
Exemplo n.º 3
0
def main(argv=sys.argv):
    if len(argv) != 2:
        die("""usage: check_with_diff.py INPUT_GRAPH
Checks the current mst for a given input file and reports the diff, if any.  It
does not do anything smart in terms of caching the correctness checker's output,
so it will be recomputed every time this is run.
""")
    else:
        input_graph = argv[1]

    if not os.path.exists(input_graph):
        die("%s not found" % input_graph)

    # get our mst output
    mst = get_path_to_mst_binary(make_sure_it_exists=False)
    mst_out = random_tmp_filename(10)
    if os.system('%s %s > %s' % (mst, input_graph, mst_out)) != 0:
        quiet_remove(mst_out)
        die("failed to run mst (or exited with an error code)")

    # get the checker's output
    checker = get_path_to_checker_binary(make_sure_it_exists=True)
    checker_out = random_tmp_filename(10)
    if os.system('%s %s true > %s' % (checker, input_graph, checker_out)) != 0:
        quiet_remove(mst_out)
        quiet_remove(checker_out)
        die("failed to run checker (or exited with an error code)")

    # check just the MST weight first
    mst_w = extract_answer(mst_out)
    checker_w = extract_answer(checker_out)
    fmt = '%.1f' # tolerance to 1 decimal place
    str_mst_w = fmt % mst_w
    str_checker_w = fmt % checker_w
    if str_mst_w == str_checker_w:
        print 'Weights match! %s %s' % (str_mst_w, str_checker_w)
        quiet_remove(mst_out)
        quiet_remove(checker_out)
        return 0
    else:
        print 'Weight mistmatch, comparing vertices!! (checker_mst (%s) - our_mst (%s) = %s)' % (str(checker_w), str(mst_w), str(checker_w - mst_w))

    # sort them
    mst_out2 = random_tmp_filename(10)
    checker_out2 = random_tmp_filename(10)
    sort_and_order = get_path_to_project_root() + 'src/input/sort_and_order.py '
    os.system(sort_and_order + mst_out + ' 1 > ' + mst_out2)
    os.system(sort_and_order + checker_out + ' 1 > ' + checker_out2)

    # compare them
    os.system('diff %s %s && echo Edges are the same!' % (checker_out2, mst_out2))
    quiet_remove(mst_out)
    quiet_remove(mst_out2)
    quiet_remove(checker_out)
    quiet_remove(checker_out2)
    return 0
Exemplo n.º 4
0
def gen_random_vertex_positions(num_verts, num_edges, num_dims, min_pos, max_pos, precision, out):
    if edges_in_complete_undirected_graph(num_verts) != num_edges:
        die('not yet implemented error: gen_random_vertex_positions only works for generating complete graphs')

    # generate all of the coordinates in one big array
    coords = [__rnd.uniform(min_pos,max_pos) for _ in range(num_verts*num_dims)]

    print_input_header(num_verts, num_edges, out)

    # print the edge weights for each pair
    fmt = '%u %u %.' + str(precision) + 'f'
    for i in range(0, num_verts):
        io = i * num_dims
        for j in range(i+1, num_verts):
            jo = j * num_dims
            print >> out, fmt % (i+1, j+1, sqrt(sum([(coords[io+o]-coords[jo+o])*(coords[io+o]-coords[jo+o]) for o in range(num_dims)])))

    return "m=%d n=%d d=%d min=%.1f max=%.1f prec=%d seed=%s" % (num_verts, num_edges, num_dims,
                                                                 min_pos, max_pos, precision, str(__RND_SEED))
Exemplo n.º 5
0
def main(argv=sys.argv[1:],
         get_output_name_only=False,
         get_is_for_part2=False):
    usage = """usage: %prog [options] NUM_VERTICES
Generates a connected graph with no self-loops or parallel edges.  Output is
sent to the default filename (""" + get_path_to_generated_inputs() + """/with
V-E-SEED.g unless -e or -v are specified in which case a random filename is
used.)"""
    parser = OptionParser(usage)
    parser.add_option("-c",
                      "--correctness",
                      action="store_true",
                      default=False,
                      help="compute and log the correct output")
    parser.add_option(
        "-d",
        "--dont-generate",
        action="store_true",
        default=False,
        help="add the input to the inputs list file but do not generate it")
    parser.add_option(
        "-l",
        "--inputs-list-file",
        metavar="FILE",
        help=
        "set the file to store info about the new input to (default is usually fine)"
    )
    parser.add_option(
        "-m",
        "--may-use-existing",
        action="store_true",
        default=False,
        help="will not generate a new graph if the output file already exists")
    parser.add_option(
        "-n",
        "--num-edges",
        help="number of edges to put in the graph [default: complete graph]")
    parser.add_option(
        "-o",
        "--output-file",
        help=
        "where to output the generated graph [default is inputs/[<STYLE>-]<NUM_VERTICES>-<NUM_EDGES>-<RANDOM_SEED>.g"
    )
    parser.add_option(
        "-p",
        "--precision",
        type="int",
        default=1,
        help=
        "number of decimal points to specify for edge weights [default: %default]"
    )
    parser.add_option("-q",
                      "--quiet",
                      action="store_true",
                      default=False,
                      help="do not log any extraneous information to stdout")
    parser.add_option(
        "-r",
        "--random-seed",
        metavar="R",
        type="int",
        default=None,
        help=
        "what random seed to use [default: choose a truly random seed using urandom()]"
    )
    parser.add_option(
        "-s",
        "--style",
        help=
        "how to place edges [default: random with no self-loops or parallel edges]"
    )
    parser.add_option(
        "-t",
        "--dont-track",
        action="store_true",
        default=False,
        help="whether to log this input in our list of generated inputs")

    group = OptionGroup(parser, "Generation Type Options")
    group.add_option(
        "-e",
        "--edge-weight-range",
        metavar="MIN,MAX",
        help="range of edge weights (range inclusive) [default: [0.1,100000]]")
    group.add_option(
        "-v",
        "--vertex-pos-range",
        metavar="DIM,MIN,MAX",
        help=
        "dimensionality of vertex positions and the range of each dimension (range inclusive) [not used by default; mutually exclusive with -e]"
    )
    parser.add_option_group(group)

    (options, args) = parser.parse_args(argv)
    if len(args) < 1:
        parser.error("missing NUM_VERTICES")
    elif len(args) > 1:
        parser.error("too many arguments")

    # make sure --dont-generate isn't specified along with mutex switches
    if options.dont_generate:
        if options.correctness:
            parser.error('-c cannot be specified with --dont-generate')
        if options.dont_track:
            parser.error('-t cannot be specified with --dont-generate')
        if options.output_file:
            parser.error('-o cannot be specified with --dont-generate')

    # just return whether the input specified would be for part 2
    if get_is_for_part2:
        return options.edge_weight_range is not None or options.vertex_pos_range is not None

    # initialize the random number generator
    global __RND_SEED
    global __rnd
    if options.random_seed is not None:
        __RND_SEED = options.random_seed
    else:
        __RND_SEED = unpack(
            'Q', urandom(8))[0]  # generate a truly random 8-byte seed
    __rnd = Random(__RND_SEED)

    def print_if_not_quiet(msg):
        if not options.quiet:
            print msg

    # determine how many vertices should be in the graph
    try:
        num_verts = int(args[0])
    except ValueError:
        parser.error("NUM_VERTICES must be an integer")

    try:
        sne = options.num_edges
        if sne == 'c' or sne == 'complete' or sne is None:
            num_edges = edges_in_complete_undirected_graph(num_verts)
        else:
            num_edges = int(sne)
            if num_edges > edges_in_complete_undirected_graph(num_verts):
                parser.error(
                    "-n may not be larger than NUM_VERTICES*(NUM_VERTICES-1)/2 (complete graph may not have self-loops or parallel edges)"
                )
            elif num_edges < num_verts - 1:
                parser.error(
                    "-n may not be less than NUM_VERTICES-1 (graph must be connected)"
                )
    except ValueError:
        parser.error("-n must either be an integer or 'complete'")

    if options.precision <= 0:
        parser.error("-p must be at least 1")
    elif options.precision > 15:
        parser.error(
            "-p must be no more than 15 (doubles cannot accurately represent more than this)"
        )

    if options.style is not None:
        parser.error("option -s is not yet supported")
    else:
        style_str = ''

    if options.edge_weight_range and options.vertex_pos_range:
        parser.error("option -e and -v are mutually exclusive")

    # determine the output file to use
    if options.output_file is None:
        path = get_path_to_generated_inputs()
        if options.vertex_pos_range or options.edge_weight_range:
            options.output_file = path + 'other-' + str(__RND_SEED) + '.g'
        else:
            options.output_file = path + '%s%u-%u-%s.g' % (
                style_str, num_verts, num_edges, str(__RND_SEED))

    # special use of the method ... just return the name we would use
    if get_output_name_only:
        return options.output_file

    # open the desired output file
    if options.output_file == 'stdout':
        out = sys.stdout
    elif not options.dont_generate:
        if options.may_use_existing:
            if os.path.exists(options.output_file):
                print_if_not_quiet(
                    'skipping input generation: %s already exists' %
                    ppinput(options.output_file))
                return 0
        try:
            out = open(options.output_file, 'w')
        except IOError, errstr:
            die('generate_input: error: ' + errstr)
Exemplo n.º 6
0
def sh_or_die(cmd, msg):
    if os.system(cmd) != 0:
        die(cmd + ' failed: ' + msg)
Exemplo n.º 7
0
def sh_or_die(cmd, msg):
    if os.system(cmd) != 0:
        die(cmd + ' failed: ' + msg)
Exemplo n.º 8
0
def main(argv=sys.argv[1:], get_output_name_only=False, get_is_for_part2=False):
    usage = """usage: %prog [options] NUM_VERTICES
Generates a connected graph with no self-loops or parallel edges.  Output is
sent to the default filename (""" + get_path_to_generated_inputs() + """/with
V-E-SEED.g unless -e or -v are specified in which case a random filename is
used.)"""
    parser = OptionParser(usage)
    parser.add_option("-c", "--correctness",
                      action="store_true", default=False,
                      help="compute and log the correct output")
    parser.add_option("-d", "--dont-generate",
                      action="store_true", default=False,
                      help="add the input to the inputs list file but do not generate it")
    parser.add_option("-l", "--inputs-list-file",
                      metavar="FILE",
                      help="set the file to store info about the new input to (default is usually fine)")
    parser.add_option("-m", "--may-use-existing",
                      action="store_true", default=False,
                      help="will not generate a new graph if the output file already exists")
    parser.add_option("-n", "--num-edges",
                      help="number of edges to put in the graph [default: complete graph]")
    parser.add_option("-o", "--output-file",
                      help="where to output the generated graph [default is inputs/[<STYLE>-]<NUM_VERTICES>-<NUM_EDGES>-<RANDOM_SEED>.g")
    parser.add_option("-p", "--precision",
                      type="int", default=1,
                      help="number of decimal points to specify for edge weights [default: %default]")
    parser.add_option("-q", "--quiet",
                      action="store_true", default=False,
                      help="do not log any extraneous information to stdout")
    parser.add_option("-r", "--random-seed",
                      metavar="R", type="int", default=None,
                      help="what random seed to use [default: choose a truly random seed using urandom()]")
    parser.add_option("-s", "--style",
                      help="how to place edges [default: random with no self-loops or parallel edges]")
    parser.add_option("-t", "--dont-track",
                      action="store_true", default=False,
                      help="whether to log this input in our list of generated inputs")

    group = OptionGroup(parser, "Generation Type Options")
    group.add_option("-e", "--edge-weight-range",
                     metavar="MIN,MAX",
                     help="range of edge weights (range inclusive) [default: [0.1,100000]]")
    group.add_option("-v", "--vertex-pos-range",
                     metavar="DIM,MIN,MAX",
                     help="dimensionality of vertex positions and the range of each dimension (range inclusive) [not used by default; mutually exclusive with -e]")
    parser.add_option_group(group)

    (options, args) = parser.parse_args(argv)
    if len(args) < 1:
        parser.error("missing NUM_VERTICES")
    elif len(args) > 1:
        parser.error("too many arguments")

    # make sure --dont-generate isn't specified along with mutex switches
    if options.dont_generate:
        if options.correctness:
            parser.error('-c cannot be specified with --dont-generate')
        if options.dont_track:
            parser.error('-t cannot be specified with --dont-generate')
        if options.output_file:
            parser.error('-o cannot be specified with --dont-generate')

    # just return whether the input specified would be for part 2
    if get_is_for_part2:
        return options.edge_weight_range is not None or options.vertex_pos_range is not None

    # initialize the random number generator
    global __RND_SEED
    global __rnd
    if options.random_seed is not None:
        __RND_SEED = options.random_seed
    else:
        __RND_SEED = unpack('Q', urandom(8))[0]  # generate a truly random 8-byte seed
    __rnd = Random(__RND_SEED)

    def print_if_not_quiet(msg):
        if not options.quiet:
            print msg

    # determine how many vertices should be in the graph
    try:
        num_verts = int(args[0])
    except ValueError:
        parser.error("NUM_VERTICES must be an integer")

    try:
        sne = options.num_edges
        if sne == 'c' or sne == 'complete' or sne is None:
            num_edges = edges_in_complete_undirected_graph(num_verts)
        else:
            num_edges = int(sne)
            if num_edges > edges_in_complete_undirected_graph(num_verts):
                parser.error("-n may not be larger than NUM_VERTICES*(NUM_VERTICES-1)/2 (complete graph may not have self-loops or parallel edges)")
            elif num_edges < num_verts - 1:
                parser.error("-n may not be less than NUM_VERTICES-1 (graph must be connected)")
    except ValueError:
        parser.error("-n must either be an integer or 'complete'")

    if options.precision <= 0:
        parser.error("-p must be at least 1")
    elif options.precision > 15:
        parser.error("-p must be no more than 15 (doubles cannot accurately represent more than this)")

    if options.style is not None:
        parser.error("option -s is not yet supported")
    else:
        style_str = ''

    if options.edge_weight_range and options.vertex_pos_range:
        parser.error("option -e and -v are mutually exclusive")

    # determine the output file to use
    if options.output_file is None:
        path = get_path_to_generated_inputs()
        if options.vertex_pos_range or options.edge_weight_range:
            options.output_file = path + 'other-' + str(__RND_SEED) + '.g'
        else:
            options.output_file = path + '%s%u-%u-%s.g' % (style_str, num_verts, num_edges, str(__RND_SEED))

    # special use of the method ... just return the name we would use
    if get_output_name_only:
        return options.output_file

    # open the desired output file
    if options.output_file == 'stdout':
        out = sys.stdout
    elif not options.dont_generate:
        if options.may_use_existing:
            if os.path.exists(options.output_file):
                print_if_not_quiet('skipping input generation: %s already exists' % ppinput(options.output_file))
                return 0
        try:
            out = open(options.output_file, 'w')
        except IOError, errstr:
            die('generate_input: error: ' + errstr)