예제 #1
0
    def __init__(self):
        super().__init__()
        unsorted_matrix = common.initialize_matrix(
            self.arguments['number_of_vertices'])

        # fill the matrix
        for i in range(self.arguments['number_of_vertices']):
            for j in range(i):
                if random.random() < self.arguments['edge_probability']:
                    unsorted_matrix[i][j] = unsorted_matrix[j][i] = 1

        # sort the matrix
        indices = sorted(range(self.arguments['number_of_vertices']),
                         key=lambda x: sum(unsorted_matrix[x]),
                         reverse=True)
        matrix = common.initialize_matrix(self.arguments['number_of_vertices'])
        for i, old_i in enumerate(indices):
            for j, old_j in enumerate(indices):
                matrix[i][j] = unsorted_matrix[old_i][old_j]

        # output the matrix
        with open(CLIQUE_FILENAME, 'w') as f:
            f.write('n = {};\n'.format(self.arguments['number_of_vertices']))
            if 'size_of_clique' in self.arguments:
                f.write('k = {};\n'.format(self.arguments['size_of_clique']))
            f.write(dzn_formatting.matrix(matrix))
예제 #2
0
    def __init__(self,
                 data_file,
                 int_version,
                 vertex_properties,
                 edge_properties,
                 index_parser=lambda s: int(s) - 1):
        '''v_properties and e_properties are lists of tuples (n, f), where n is the name of the property and f is a function
        taking an XML node/edge tag and returning the desired property'''
        self.number_of_vertices = 0
        self.number_of_edges = 0
        self.int_version = int_version
        Vertex = namedtuple('Vertex', [p[0] for p in vertex_properties])
        Edge = namedtuple('Edge', [p[0] for p in edge_properties])
        self.vertices = []
        self.adjacency_matrix = []
        self.edges = []

        for element in ElementTree.parse(data_file).getroot()[0]:
            if element.tag == 'node':
                self.number_of_vertices += 1
                self.vertices.append(
                    Vertex(*[f(element) for _, f in vertex_properties]))
            else:
                self.number_of_edges += 1

                # If this is the first edge, then we know how many vertices there are and we can initialize the matrix
                if self.edges == []:
                    self.edges = common.initialize_matrix(
                        self.number_of_vertices, None)
                    self.adjacency_matrix = common.initialize_matrix(
                        self.number_of_vertices)

                f, t = [index_parser(j) for j in element.attrib.values()]
                self.edges[f][t] = self.edges[t][f] = Edge(
                    *[f(element) for _, f in edge_properties])
                self.adjacency_matrix[f][t] = self.adjacency_matrix[t][f] = 1
예제 #3
0
    def __init__(self):
        # parse the command line arguments
        self.first_command_line_argument = 2
        self.check_command_line_arguments()
        self.arguments = [(int(sys.argv[i - 2]), float(sys.argv[i - 1]),
                           float(sys.argv[i]))
                          for i in range(4, len(sys.argv), 3)]

        # call the superclass to generate the 2 graphs
        self.generate_and_write_to_file()
        n1 = self.arguments[0][0]
        n2 = self.arguments[1][0]

        # generate the labels
        labels = [
        ]  # labels[i] is a list of labels for all vertices of graph i
        for n, _, l in self.arguments:
            labels.append([
                random.randint(1, n1 + n2) if random.random() < l else 0
                for j in range(n)
            ])

        # write then to the file already generated by SubgraphGenerator
        with open(SUBGRAPH_FILENAME, 'a') as f:
            for i in range(len(self.arguments)):
                f.write('vLabel{} = [{}];\n'.format(
                    i + 1, ', '.join(map(str, labels[i]))))

        # assign a new 'name' for all pairs of vertices that can be matched
        encoding = {}
        n = 0
        for v1 in range(n1):
            for v2 in range(n2):
                if labels[0][v1] == labels[1][v2]:
                    encoding[(v1, v2)] = n
                    n += 1

        # generate an adjacency matrix for the clique problem
        clique = common.initialize_matrix(n)
        for (a, b), (c, d) in itertools.product(encoding, repeat=2):
            if a != c and b != d and self.matrices[0][a][c] == self.matrices[
                    1][b][d]:
                clique[encoding[(a, b)]][encoding[(c, d)]] = 1

        # write it to file
        with open(CLIQUE_FILENAME, 'w') as f:
            f.write('n = {};\n'.format(n))
            f.write(dzn_formatting.matrix(clique))
예제 #4
0
    def __init__(self):
        super().__init__()

        n1 = self.arguments[0][0]
        n2 = self.arguments[1][0]
        clique = common.initialize_matrix(n1 * n2)
        for v2, u2 in itertools.product(range(n2), repeat=2):
            if u2 == v2:
                continue
            for v1, u1 in itertools.product(range(n1), repeat=2):
                if u1 != v1 and self.matrices[0][v1][u1] == self.matrices[1][
                        v2][u2]:
                    clique[v1 * n2 + v2][u1 * n2 + u2] = 1

        with open(CLIQUE_FILENAME, 'w') as f:
            f.write('n = {};\n'.format(n1 * n2))
            f.write(dzn_formatting.matrix(clique))
예제 #5
0
    def generate_and_write_to_file(self):
        self.matrices = [
            common.initialize_matrix(self.arguments[i][0])
            for i in range(len(self.arguments))
        ]

        for i in range(len(self.arguments)):
            for j in range(self.arguments[i][0]):
                for k in range(j):
                    if random.random() < self.arguments[i][1]:
                        self.matrices[i][j][k] = self.matrices[i][k][j] = 1

        with open(SUBGRAPH_FILENAME, 'w') as f:
            for i in range(len(self.arguments)):
                f.write('n{} = {};\n'.format(i + 1, self.arguments[i][0]))
                f.write(
                    dzn_formatting.matrix(self.matrices[i],
                                          'adjacent' + str(i + 1)))
예제 #6
0
 def get_edge_substitution_cost(self, other, i1, i2, j1, j2):
     start_freq = len(self.edges[i1][i2].types)
     end_freq = len(other.edges[j1][j2].types)
     if start_freq == 0 or end_freq == 0:
         return 0
     n = start_freq + end_freq
     matrix = common.initialize_matrix(n)
     for i in range(start_freq):
         for j in range(end_freq):
             if self.edges[i1][i2].types[i] != other.edges[j1][j2].types[j]:
                 matrix[i][j] = 2 * self.tau_edge
         for j in range(end_freq, n):
             matrix[i][j] = self.tau_edge if j - end_freq == i else float(
                 'inf')
     for i in range(start_freq, n):
         for j in range(end_freq):
             matrix[i][j] = self.tau_edge if i - start_freq == j else float(
                 'inf')
     return (1 - self.alpha) * sum(
         [matrix[i][j] for i, j in Munkres().compute(matrix)])
import sys
import common
import dzn_formatting

# Converts DIMACS graph files into DZN format
if len(sys.argv) < 2:
    print('Usage: python {} DIMACS_file'.format(sys.argv[0]))
    exit()

with open(sys.argv[1]) as in_file, open(
        sys.argv[1][:sys.argv[1].rfind('.')] + '.dzn', 'w') as out_file:
    for line in in_file:
        if line[0] == 'p':
            n = int(line.split()[2])
            matrix = common.initialize_matrix(n)
            out_file.write('n = {};\n'.format(n))
        elif line[0] == 'e':
            v1, v2 = [int(v) - 1 for v in line.split()[1:]]
            matrix[v1][v2] = matrix[v2][v1] = 1
    out_file.write(dzn_formatting.matrix(matrix))