1

Hi I have made this code. Τhe code generates all binary permutations of a string with a given number of zeros and ones, checks for adjacency based on a specific homogeneity condition (differing by exactly two consecutive bits), builds a graph of these permutations, and prints the graph with nodes sorted by their decimal values.

def homogeneity_check(n1, n2) -> bool:

    positions = [i for i in range(len(n1)) if n1[i] != n2[i]]

    if len(positions) == 2 and positions[1] == positions[0] + 1:
        return True
    
    return False
    
def find_permutations(s: str):
    def generate_permutations(s, current_index):
        if current_index == len(s) - 1:
            return [s]  # Αν φτάσουμε στο τέλος της αλυσίδας, επιστρέφουμε την τρέχουσα παραλλαγή
        
        perms = []
        for i in range(current_index, len(s)):
            # Ανταλλάζουμε τα στοιχεία στις θέσεις current_index και i
            s_list = list(s)
            s_list[current_index], s_list[i] = s_list[i], s_list[current_index]
            new_str = ''.join(s_list)
            
            # Βάζουμε την νέα παραλλαγή και συνεχίζουμε την αναδρομή
            perms.extend(generate_permutations(new_str, current_index + 1))
        
        return perms

    perms = set(generate_permutations(s, 0))  # Χρησιμοποιούμε set για να αποφύγουμε τα διπλότυπα
    print(sorted(perms))
    return sorted(perms)
    


def generate_graph(s,t):
    
    num = ("0" * s + "1" * t)
    perms = find_permutations(num)
    
    graph = {n: [] for n in perms} # Κενός γραφός, με λιστές που αντιπροσωπεύουν τους γείτονες

    for i in range(len(perms)):
        for j in range(i + 1, len(perms)):
            # if homogeneity_check(perms[i], perms[j]):
                graph[perms[i]].append(perms[j])
                graph[perms[j]].append(perms[i])
    return graph

def print_graph(graph):
    for node in sorted(graph, key=lambda x: int(x, 2)):
        node_decimal = int(node, 2)
        neighbors_decimal = sorted(int(neigh, 2) for neigh in graph[node])
        print(f"{node_decimal} -> {neighbors_decimal}")

I have this output with this input print_graph(generate_graph(2,4)):

15 -> [23]
23 -> [15, 27, 39]
27 -> [23, 29, 43]
29 -> [27, 30, 45]
30 -> [29, 46]
39 -> [23, 43]
43 -> [27, 39, 45, 51]
45 -> [29, 43, 46, 53]
46 -> [30, 45, 54]
51 -> [43, 53]
53 -> [45, 51, 54, 57]
54 -> [46, 53, 58]
57 -> [53, 58]
58 -> [54, 57, 60]
60 -> [58]

but I want this

 60 -> [58, 57, 54, 53, 46, 45, 30, 29]
 58 -> [60, 57, 51, 54, 43, 46, 27, 30]
 57 -> [60, 58, 53, 51, 45, 43, 29, 27]
54 -> [60, 58, 51, 53, 39, 46, 23, 30]
53 -> [60, 57, 54, 51, 45, 39, 29, 23]
46 -> [60, 58, 54, 43, 39, 45, 15, 30]
45 -> [60, 57, 53, 46, 43, 39, 29, 15]
30 -> [60, 58, 54, 46, 27, 23, 15, 29]
29 -> [60, 57, 53, 45, 30, 27, 23, 15]
51 -> [58, 57, 54, 53, 43, 39, 27, 23]
43 -> [58, 57, 46, 45, 51, 39, 27, 15]
27 -> [58, 57, 30, 29, 51, 43, 23, 15]
39 -> [54, 53, 46, 45, 51, 43, 23, 15]
23 -> [54, 53, 30, 29, 51, 27, 39, 15]
15 -> [46, 45, 30, 29, 43, 27, 39, 23]

can someone explain me what I am doing wrong. I can't understand how to find the other neighbours for each node.

3
  • Maybe first use print() (and print(type(...)), print(len(...)), etc.) to see which part of code is executed and what you really have in variables. It is called "print debugging" and it helps to see what code is really doing. Commented Apr 8 at 19:34
  • ericlippert.com/2014/03/05/how-to-debug-small-programs Commented Apr 8 at 19:58
  • Why do you think 15 and 46 should be adjacent? Their binary representations are 0b001111 and 0b101110 respectively. Not sure how that fits in with your requirement of "differing by exactly two consecutive bits". Commented Apr 8 at 20:39

1 Answer 1

5

You claim to expect 46 and 15 to be adjacent in the graph. But 46 represents 101110 and 15 represents 001111. Those are not adjacent by the adjacency rule that you've described (and coded). Therefore either your expectation is wrong, or your adjacency rule is wrong. (Spot checking, 23 represents 010111, which indeed should be the only thing adjacent to 001111 by your stated rule...)

You can get the output that you say you expect with the following changes.

First, change your homogeneity check to just swap 2 positions.

def homogeneity_check(n1, n2) -> bool:

    positions = [i for i in range(len(n1)) if n1[i] != n2[i]]

    if len(positions) == 2: # and positions[1] == positions[0] + 1:
        return True

    return False

Second, get rid of your debugging print in find_permutations:

def find_permutations(s: str):
    def generate_permutations(s, current_index):
        if current_index == len(s) - 1:
            return [s]  # Αν φτάσουμε στο τέλος της αλυσίδας, επιστρέφουμε την τρέχουσα παραλλαγή

        perms = []
        for i in range(current_index, len(s)):
            # Ανταλλάζουμε τα στοιχεία στις θέσεις current_index και i
            s_list = list(s)
            s_list[current_index], s_list[i] = s_list[i], s_list[current_index]
            new_str = ''.join(s_list)

            # Βάζουμε την νέα παραλλαγή και συνεχίζουμε την αναδρομή
            perms.extend(generate_permutations(new_str, current_index + 1))

        return perms

    perms = set(generate_permutations(s, 0))  # Χρησιμοποιούμε set για να αποφύγουμε τα διπλότυπα
    #print(sorted(perms))
    return sorted(perms)

Re-enable the homogeneity check in generate_graph:

def generate_graph(s,t):

    num = ("0" * s + "1" * t)
    perms = find_permutations(num)

    graph = {n: [] for n in perms} # Κενός γραφός, με λιστές που αντιπροσωπεύουν τους γείτονες

    for i in range(len(perms)):
        for j in range(i + 1, len(perms)):
            if homogeneity_check(perms[i], perms[j]):
                graph[perms[i]].append(perms[j])
                graph[perms[j]].append(perms[i])
    return graph

Add reverse=True to the sorts in print_graph:

def print_graph(graph):
    for node in sorted(graph, key=lambda x: int(x, 2), reverse=True):
        node_decimal = int(node, 2)
        neighbors_decimal = sorted((int(neigh, 2) for neigh in graph[node]), reverse=True)
        print(f"{node_decimal} -> {neighbors_decimal}")
Sign up to request clarification or add additional context in comments.

1 Comment

thank you very much that helped a lot !!!

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.