Korean, Edit

AI for Generating Hypotheses, The Beginning of the Idea

Recommended Article : 【Evolutionary Behavioral Science】 Evolutionary Behavioral Science Index


a. Mathematical Logic Problems

b. Where is AI Heading?



“Exploration is like finding one’s way by asking for directions; it involves asking a question, answering it, discovering the next question, and then answering that, in a process that is connected as one.” - Max Perutz


Recently, I had a final interview at ETH Zurich. From now on, the final acceptance rate seems to be about 50%. The technology of spacetime transposition beyond spatial transposition was in front of my eyes, and they asked me how I would interpret this data. At that time, the keyword ‘hypothesis-generating AI’ came to my mind. It was a topic that received an intense reaction, but I thought it might have been esoteric to them and even overwhelming for me.

In fact, generating hypotheses through data was an insight I gained from the company where I had been working for over two years. Drug development is sometimes a marathon that lasts over 10 years, and many fail upon encountering unexpected clinical trial results in the final stages. Therefore, the company attempted smart drug development strategies, constructing storytelling by generating hypotheses in reverse based on clinical trial results. Thus, the approach of creating hypotheses from data was not foreign to me, and I thought that in the era of ChatGPT, AI could also generate hypotheses.

When I pondered where the idea of ‘hypothesis-generating AI’ came from, it seemed to start from the paper “Beyond RG: from parameter flow to metric flow” (Strandkvist, C. et al). It was a challenging but quite interesting mathematical theory of generating theories from high-dimensional parameters.


image

Figure. 1. Basic Terms


image

Figure. 2. Mathematical Representation of the Question of Interest


Mulling over this paper, as the dimensions of data increase and interpretability decreases, my plan to create a hypothesis-generating AI seemed not just a fanciful story but a truly feasible future. Therefore, I actually developed a machine learning algorithm, experimenting with establishing hypotheses and testing various aspects to find truly valid and appropriate hypotheses.

The specific problems I’m currently focusing on are as follows:

“There are six beads of the same size and shape. Among these, three are heavy, and the other three are light. However, the three heavy beads weigh the same, and the three light beads also weigh the same. Now, using a two-pan balance scale three times, separate the beads into heavy and light groups.”

There were the following considerations:

○ Machine learning code is divided into parts for generating strategies and verifying them.

○ The method of comparison using a balance scale always proceeds in groups of 3 vs 3, 2 vs 2, 1 vs 1. This is because it is difficult to obtain valid information in other cases. There was much deliberation on how to define the ‘information’ gained by comparing with a balance scale. In fact, it might be possible to define such ‘information’ probabilistically or algebraically. (ref) However, currently limited by my capabilities, I decided to actively utilize the necessary and sufficient condition of ‘narrowing down the possibilities’ captured by comparing with a balance scale, prioritizing combinatorial thinking.

○ The combinations of possible heavy sets given a strategy and balance scale comparison results are defined as potential heavy set(s). Here, not only cases where there is 1 potential heavy set but also cases with 0 are considered valid, as it’s necessary to avoid rejecting a truly valid strategy due to completely irrelevant information.

Now, let’s complete the code for creating and verifying strategies through several trials and errors.

3 vs 3 Given information like (1, 2, 3) > (4, 5, 6), (1, 2, 4) > (3, 5, 6), (1, 2, 5) > (3, 4, 6), output potential heavy set(s)


from itertools import combinations

def get_potential_heavy_sets(weighing1, weighing2, weighing3):
    # Initial beads
    beads = [1, 2, 3, 4, 5, 6]
    
    potential_heavy_sets1 = [combo for combo in combinations(beads, 3) if len(set(combo) & set(weighing1)) >= 2]    
    potential_heavy_sets2 = [combo for combo in combinations(beads, 3) if len(set(combo) & set(weighing2)) >= 2]
    potential_heavy_sets3 = [combo for combo in combinations(beads, 3) if len(set(combo) & set(weighing3)) >= 2]

    # Intersect the three potential heavy sets
    final_potential_heavy_sets = list(set(potential_heavy_sets1) & set(potential_heavy_sets2) & set(potential_heavy_sets3))
    
    return final_potential_heavy_sets

weighing1 = (1, 2, 3)  # Beads in the left pan during the first weighing
weighing2 = (1, 2, 4)  # Beads in the left pan during the second weighing
weighing3 = (1, 2, 5)  # Beads in the left pan during the third weighing

print("Possible sets of heavy beads:", get_potential_heavy_sets(weighing1, weighing2, weighing3))


3 vs 3 Strategy of (1, 2, 3) vs (4, 5, 6), (1, 2, 4) vs (3, 5, 6), (1, 2, 5) vs (3, 4, 6), output each potential heavy set(s)


from itertools import combinations

def potential_sets_for_weighing(weighing, beads, is_heavier):
    if is_heavier:
        return [combo for combo in combinations(beads, 3) if len(set(combo) & set(weighing)) >= 2]
    else:
        return [combo for combo in combinations(beads, 3) if len(set(combo) - set(weighing)) >= 2]

def get_all_potential_heavy_sets(weighing1, weighing2, weighing3):
    beads = [1, 2, 3, 4, 5, 6]
    results = []

    for state1 in [True, False]:  # True = heavier, False = lighter
        for state2 in [True, False]:
            for state3 in [True, False]:
                potential_sets1 = potential_sets_for_weighing(weighing1, beads, state1)
                potential_sets2 = potential_sets_for_weighing(weighing2, beads, state2)
                potential_sets3 = potential_sets_for_weighing(weighing3, beads, state3)

                intersected_sets = list(set(potential_sets1) & set(potential_sets2) & set(potential_sets3))
                if intersected_sets:
                    results.append({
                        "states": (state1, state2, state3),
                        "sets": intersected_sets
                    })

    return results

weighing1 = (1, 2, 3)
weighing2 = (1, 2, 4)
weighing3 = (1, 2, 5)

all_results = get_all_potential_heavy_sets(weighing1, weighing2, weighing3)
for result in all_results:
    states_str = ["heavier" if s else "lighter" for s in result["states"]]
    print(f"When weighing1 is {states_str[0]}, weighing2 is {states_str[1]}, and weighing3 is {states_str[2]}:")
    print("Possible sets of heavy beads:", result["sets"])
    print("----")


3 vs 3 Strategy of (1, 2, 3) vs (4, 5, 6), (1, 2, 4) vs (3, 5, 6), (1, 2, 5) vs (3, 4, 6), check if it always outputs 0-1 potential heavy set(s)


from itertools import combinations

def potential_sets_for_weighing(weighing, beads, is_heavier):
    if is_heavier:
        return [combo for combo in combinations(beads, 3) if len(set(combo) & set(weighing)) >= 2]
    else:
        return [combo for combo in combinations(beads, 3) if len(set(combo) - set(weighing)) >= 2]

def get_all_potential_heavy_sets(weighing1, weighing2, weighing3):
    beads = [1, 2, 3, 4, 5, 6]
    results = []

    for state1 in [True, False]:  # True = heavier, False = lighter
        for state2 in [True, False]:
            for state3 in [True, False]:
                potential_sets1 = potential_sets_for_weighing(weighing1, beads, state1)
                potential_sets2 = potential_sets_for_weighing(weighing2, beads, state2)
                potential_sets3 = potential_sets_for_weighing(weighing3, beads, state3)

                intersected_sets = list(set(potential_sets1) & set(potential_sets2) & set(potential_sets3))
                if intersected_sets:
                    results.append(len(intersected_sets) <= 1)  # Store True if there's only one potential heavy set

    return all(results)  # Returns True if all strategies result in a unique potential heavy set

weighing1 = (1, 2, 3)
weighing2 = (1, 2, 4)
weighing3 = (1, 2, 5)

result = get_all_potential_heavy_sets(weighing1, weighing2, weighing3)
if result:
    print("All cases always output only one potential heavy set.")
else:
    print("There exists a case that does not output a unique potential heavy set.")


3 vs 3 Conclusion 1. When comparing 3 vs 3 three times, check if there is a valid strategy for all cases : None


from itertools import combinations

def potential_sets_for_weighing(weighing, beads, is_heavier):
    if is_heavier:
        return [combo for combo in combinations(beads, 3) if len(set(combo) & set(weighing)) >= 2]
    else:
        return [combo for combo in combinations(beads, 3) if len(set(combo) - set(weighing)) >= 2]

def get_all_potential_heavy_sets(weighing1, weighing2, weighing3):
    beads = [1, 2, 3, 4, 5, 6]
    results = []

    for state1 in [True, False]:  # True = heavier, False = lighter
        for state2 in [True, False]:
            for state3 in [True, False]:
                potential_sets1 = potential_sets_for_weighing(weighing1, beads, state1)
                potential_sets2 = potential_sets_for_weighing(weighing2, beads, state2)
                potential_sets3 = potential_sets_for_weighing(weighing3, beads, state3)

                intersected_sets = list(set(potential_sets1) & set(potential_sets2) & set(potential_sets3))
                if intersected_sets:
                    results.append(len(intersected_sets) <= 1)  # Store True if there's only one potential heavy set

    return all(results)  # Returns True if all strategies result in a unique potential heavy set

beads = [1, 2, 3, 4, 5, 6]

successful_combinations = []

for weighing1 in combinations(beads, 3):
    for weighing2 in combinations(beads, 3):
        for weighing3 in combinations(beads, 3):
            result = get_all_potential_heavy_sets(weighing1, weighing2, weighing3)
            if result:
                successful_combinations.append((weighing1, weighing2, weighing3))

print("Combinations of (weighing1, weighing2, weighing3) that always output only one potential heavy set:")
for combo in successful_combinations:
    print(combo)


2 vs 2 Given information like (1, 2) > (4, 5), (1, 2) > (3, 5), (1, 2) > (3, 4), output potential heavy set(s)


from itertools import combinations

def get_potential_heavy_sets_for_2_vs_2(weighing1_1, weighing1_2, weighing2_1, weighing2_2, weighing3_1, weighing3_2):
    beads = [1, 2, 3, 4, 5, 6]
    
    # Identify potential heavy sets for each weighing
    potential_heavy_sets1 = []
    for comb in combinations(beads, 3):
        if len( set(weighing1_1) & set(comb) ) > len( set(weighing1_2) & set(comb) ):
            potential_heavy_sets1.append(comb)

    potential_heavy_sets2 = []
    for comb in combinations(beads, 3):
        if len( set(weighing2_1) & set(comb) ) > len( set(weighing2_2) & set(comb) ):
            potential_heavy_sets2.append(comb)
    
    potential_heavy_sets3 = []
    for comb in combinations(beads, 3):
        if len( set(weighing3_1) & set(comb) ) > len( set(weighing3_2) & set(comb) ):
            potential_heavy_sets3.append(comb)    

    # Intersect the potential heavy sets to identify common sets
    final_potential_heavy_sets = list(set(potential_heavy_sets1) & set(potential_heavy_sets2) & set(potential_heavy_sets3))
    
    return final_potential_heavy_sets

weighing1_1 = (1, 2)  # Beads in the left pan during the first weighing
weighing1_2 = (4, 5)  # Beads in the right pan during the first weighing
weighing2_1 = (1, 2)  # Beads in the left pan during the second weighing
weighing2_2 = (3, 5)  # Beads in the right pan during the second weighing
weighing3_1 = (1, 2)  # Beads in the left pan during the third weighing
weighing3_2 = (3, 4)  # Beads in the right pan during the third weighing

print("Possible sets of heavy beads:", get_potential_heavy_sets_for_2_vs_2(weighing1_1, weighing1_2, weighing2_1, weighing2_2, weighing3_1, weighing3_2))


2 vs 2 Strategy of (1, 2) vs (4, 5), (1, 2) vs (3, 5), (1, 2) vs (3, 4), output each potential heavy set(s)


from itertools import combinations, product

def get_potential_heavy_sets_for_2_vs_2(weighing1_1, weighing1_2, weighing2_1, weighing2_2, weighing3_1, weighing3_2):
    beads = [1, 2, 3, 4, 5, 6]

    scenarios = {
        ">": lambda w1, w2, comb: len(set(w1) & set(comb)) > len(set(w2) & set(comb)),
        "<": lambda w1, w2, comb: len(set(w1) & set(comb)) < len(set(w2) & set(comb)),
        "=": lambda w1, w2, comb: len(set(w1) & set(comb)) == len(set(w2) & set(comb))
    }

    results = {}

    for outcome1, outcome2, outcome3 in product(scenarios.keys(), repeat=3):
        potential_heavy_sets1 = [comb for comb in combinations(beads, 3) if scenarios[outcome1](weighing1_1, weighing1_2, comb)]
        potential_heavy_sets2 = [comb for comb in combinations(beads, 3) if scenarios[outcome2](weighing2_1, weighing2_2, comb)]
        potential_heavy_sets3 = [comb for comb in combinations(beads, 3) if scenarios[outcome3](weighing3_1, weighing3_2, comb)]

        intersected_sets = list(set(potential_heavy_sets1) & set(potential_heavy_sets2) & set(potential_heavy_sets3))

        results[(outcome1, outcome2, outcome3)] = intersected_sets

    return results

weighing1_1 = (1, 2)
weighing1_2 = (4, 5)
weighing2_1 = (1, 2)
weighing2_2 = (3, 5)
weighing3_1 = (1, 2)
weighing3_2 = (3, 4)

all_results = get_potential_heavy_sets_for_2_vs_2(weighing1_1, weighing1_2, weighing2_1, weighing2_2, weighing3_1, weighing3_2)
for outcome, heavy_sets in all_results.items():
    print(f"Outcome {outcome}: {heavy_sets}")


2 vs 2 Strategy of (1, 2) > (4, 5), (1, 2) > (3, 5), (1, 2) > (3, 4), check if it always outputs 0-1 potential heavy set(s)


from itertools import combinations, product

def get_potential_heavy_sets_for_2_vs_2(weighing1_1, weighing1_2, weighing2_1, weighing2_2, weighing3_1, weighing3_2):
    beads = [1, 2, 3, 4, 5, 6]

    scenarios = {
        ">": lambda w1, w2, comb: len(set(w1) & set(comb)) > len(set(w2) & set(comb)),
        "<": lambda w1, w2, comb: len(set(w1) & set(comb)) < len(set(w2) & set(comb)),
        "=": lambda w1, w2, comb: len(set(w1) & set(comb)) == len(set(w2) & set(comb))
    }

    results = {}
    always_0_or_1 = True

    for outcome1, outcome2, outcome3 in product(scenarios.keys(), repeat=3):
        potential_heavy_sets1 = [comb for comb in combinations(beads, 3) if scenarios[outcome1](weighing1_1, weighing1_2, comb)]
        potential_heavy_sets2 = [comb for comb in combinations(beads, 3) if scenarios[outcome2](weighing2_1, weighing2_2, comb)]
        potential_heavy_sets3 = [comb for comb in combinations(beads, 3) if scenarios[outcome3](weighing3_1, weighing3_2, comb)]

        intersected_sets = list(set(potential_heavy_sets1) & set(potential_heavy_sets2) & set(potential_heavy_sets3))

        # Check if the length of intersected_sets is not 0 or 1
        if len(intersected_sets) not in [0, 1]:
            always_0_or_1 = False

        results[(outcome1, outcome2, outcome3)] = intersected_sets

    return always_0_or_1

weighing1_1 = (1, 2)
weighing1_2 = (4, 5)
weighing2_1 = (1, 2)
weighing2_2 = (3, 5)
weighing3_1 = (1, 2)
weighing3_2 = (3, 4)

check_condition = get_potential_heavy_sets_for_2_vs_2(weighing1_1, weighing1_2, weighing2_1, weighing2_2, weighing3_1, weighing3_2)

if check_condition:
    print("The strategy always outputs 0 or 1 potential heavy sets for each scenario.")
else:
    print("The strategy doesn't always output 0 or 1 potential heavy sets for each scenario.")


2 vs 2 Conclusion 2. When comparing 2 vs 2 three times, check if there is a valid strategy for all cases : None


from itertools import combinations, product

def get_potential_heavy_sets_for_2_vs_2(weighing1_1, weighing1_2, weighing2_1, weighing2_2, weighing3_1, weighing3_2):
    beads = [1, 2, 3, 4, 5, 6]

    scenarios = {
        ">": lambda w1, w2, comb: len(set(w1) & set(comb)) > len(set(w2) & set(comb)),
        "<": lambda w1, w2, comb: len(set(w1) & set(comb)) < len(set(w2) & set(comb)),
        "=": lambda w1, w2, comb: len(set(w1) & set(comb)) == len(set(w2) & set(comb))
    }

    for outcome1, outcome2, outcome3 in product(scenarios.keys(), repeat=3):
        potential_heavy_sets1 = [comb for comb in combinations(beads, 3) if scenarios[outcome1](weighing1_1, weighing1_2, comb)]
        potential_heavy_sets2 = [comb for comb in combinations(beads, 3) if scenarios[outcome2](weighing2_1, weighing2_2, comb)]
        potential_heavy_sets3 = [comb for comb in combinations(beads, 3) if scenarios[outcome3](weighing3_1, weighing3_2, comb)]

        intersected_sets = list(set(potential_heavy_sets1) & set(potential_heavy_sets2) & set(potential_heavy_sets3))

        # Return False if the length of intersected_sets is not 0 or 1
        if len(intersected_sets) not in [0, 1]:
            return False

    return True

all_2_combinations = list(combinations([1, 2, 3, 4, 5, 6], 2))

# Filter combinations to ensure the two beads do not have any intersection.
filtered_combinations = [(a, b) for a, b in product(all_2_combinations, repeat=2) if len(set(a) & set(b)) == 0]

valid_weighings = []

# Use itertools.product to replace nested loops
for weighing1, weighing2, weighing3 in product(filtered_combinations, repeat=3):
    if get_potential_heavy_sets_for_2_vs_2(*weighing1, *weighing2, *weighing3):
        valid_weighings.append((weighing1, weighing2, weighing3))
            
for weigh in valid_weighings:
    print(weigh)


(1, 2, 3) vs (1, 2, 3) Conclusion 3. Verify if there is a valid strategy for all cases when performing an arbitrary balance scale comparison three times : None


from itertools import combinations, product

beads = [1, 2, 3, 4, 5, 6]

# Part 1: Refactor existing methods

# 3 vs 3
scenarios_3v3 = {
    ">": True,  # Left is heavier
    "<": False  # Right is heavier
}

def potential_heavy_3v3(weighing1, weighing2, outcome):
    is_heavier = scenarios_3v3[outcome]
    if is_heavier:
        return [combo for combo in combinations(beads, 3) if len(set(combo) & set(weighing1)) >= 2]
    else:
        return [combo for combo in combinations(beads, 3) if len(set(combo) & set(weighing2)) >= 2]

# 2 vs 2
scenarios_2v2 = {
    ">": lambda w1, w2, comb: len(set(w1) & set(comb)) > len(set(w2) & set(comb)),
    "<": lambda w1, w2, comb: len(set(w1) & set(comb)) < len(set(w2) & set(comb)),
    "=": lambda w1, w2, comb: len(set(w1) & set(comb)) == len(set(w2) & set(comb))
}

def potential_heavy_2v2(weighing1, weighing2, outcome):
    return [comb for comb in combinations(beads, 3) if scenarios_2v2[outcome](weighing1, weighing2, comb)]

# 1 vs 1
scenarios_1v1 = {
    ">": lambda w1, w2, comb: w1 in comb and w2 not in comb,  # w1 is potentially heavier
    "<": lambda w1, w2, comb: w2 in comb and w1 not in comb,  # w2 is potentially heavier
    "=": lambda w1, w2, comb: w1 in comb and w2 in comb or w1 not in comb and w2 not in comb
}

def potential_heavy_1v1(weighing1, weighing2, outcome):
    # If the weighings are individual beads, wrap them in a tuple
    weighing1 = (weighing1,) if isinstance(weighing1, int) else weighing1
    weighing2 = (weighing2,) if isinstance(weighing2, int) else weighing2

    return [comb for comb in combinations(beads, 3) if scenarios_1v1[outcome](weighing1[0], weighing2[0], comb)]


# Part 2: Combined method
def find_valid_weighings():
    valid_weighings = []

    # Weighing strategies
    weighings = {
        3: list(combinations(beads, 3)),
        2: list(combinations(beads, 2)),
        1: beads
    }

    weighing_functions = {
        3: potential_heavy_3v3,
        2: potential_heavy_2v2,
        1: potential_heavy_1v1
    }
    
    for size1 in [3, 2, 1]:
        for weighing1_left in weighings[size1]:
            for weighing1_right in weighings[size1]:
                if weighing1_left == weighing1_right:
                    continue
                for size2 in [3, 2, 1]:
                    for weighing2_left in weighings[size2]:
                        for weighing2_right in weighings[size2]:
                            if weighing2_left == weighing2_right:
                                continue
                            for size3 in [3, 2, 1]:
                                for weighing3_left in weighings[size3]:
                                    for weighing3_right in weighings[size3]:
                                        if weighing3_left == weighing3_right:
                                            continue
                                            
                                        if isinstance(weighing1_left, int):
                                            weighing1_left = (weighing1_left,)
                                        if isinstance(weighing1_right, int):
                                            weighing1_right = (weighing1_right,)

                                        if isinstance(weighing2_left, int):
                                            weighing2_left = (weighing2_left,)
                                        if isinstance(weighing2_right, int):
                                            weighing2_right = (weighing2_right,)

                                        if isinstance(weighing3_left, int):
                                            weighing3_left = (weighing3_left,)
                                        if isinstance(weighing3_right, int):
                                            weighing3_right = (weighing3_right,)

                                        if set(weighing1_left) & set(weighing1_right):
                                            continue
                                        if set(weighing2_left) & set(weighing2_right):
                                            continue
                                        if set(weighing3_left) & set(weighing3_right):
                                            continue
                                        
                                        results = []
                                        
                                        for outcome1 in (scenarios_2v2 if size1 == 2 else (scenarios_1v1 if size1 == 1 else scenarios_3v3)):
                                            for outcome2 in (scenarios_2v2 if size2 == 2 else (scenarios_1v1 if size2 == 1 else scenarios_3v3)):
                                                for outcome3 in (scenarios_2v2 if size3 == 2 else (scenarios_1v1 if size3 == 1 else scenarios_3v3)):

                                                    potential1 = weighing_functions[size1](weighing1_left, weighing1_right, outcome1)
                                                    potential2 = weighing_functions[size2](weighing2_left, weighing2_right, outcome2)
                                                    potential3 = weighing_functions[size3](weighing3_left, weighing3_right, outcome3)

                                                    intersected_sets = list(set(potential1) & set(potential2) & set(potential3))
                                                    results.append(len(intersected_sets) <= 1) # clearly identify which one is heavy or unrealistic

                                        if all(results):
                                            valid_weighings.append(((weighing1_left, weighing1_right), 
                                                                    (weighing2_left, weighing2_right), 
                                                                    (weighing3_left, weighing3_right)))
                                            print(valid_weighings)

    return valid_weighings

# Part 3: Execute the combined method
valid_weighings = find_valid_weighings()

# Print the results
print("Valid combinations:")
for weigh in valid_weighings:
    print(weigh)


I couldn’t find the answer and reviewed various cases, gaining important insights. In fact, the solution should not be structured as a simultaneous game but as a sequential game. For example, the answer is as follows, and the reason I didn’t further develop the code is purely due to my whim.



Answer

⑴ Assign numbers 1 to 6 to the given 6 balls.

Step 1. Compare (1, 2) with (3, 4).

Case 1. (1, 2) > (3, 4)

① Heavy ball combinations

○ (1, 2, 3)

○ (1, 2, 4)

○ (1, 2, 5)

○ (1, 2, 6)

○ (1, 5, 6)

○ (2, 5, 6)

Step 2. Compare ball 3 with ball 6

Step 3. Depending on the result of Step 2, use the following different strategies.

○ 3 > 6 : No further action, decide on (1, 2, 3)

○ 3 = 6 : Compare ball 4 with ball 5 to uniquely decide between (1, 2, 4 ), (1, 2, 5 )

○ 3 < 6 : Compare ball 1 with ball 2 to uniquely decide between ( 1 , 2 , 6), ( 1 , 5, 6), (2 , 5, 6)

Case 2. (1, 2) = (3, 4)

① Heavy ball combinations

○ (1, 3, 5)

○ (1, 3, 6)

○ (1, 4, 5)

○ (1, 4, 6)

○ (2, 3, 5)

○ (2, 3, 6)

○ (2, 4, 5)

○ (2, 4, 6)

Step 2. Compare (1, 3) with (2, 5).

Step 3. Depending on the result of Step 2, use the following different strategies.

○ (1, 3) > (2, 5) : Compare ball 4 with ball 5 to uniquely decide among (1, 3, 5 ), (1, 3, 6), (1, 4, 6)

○ (1, 3) = (2, 5) : Compare ball 1 with ball 2 to uniquely decide between ( 1 , 4, 5), ( 2 , 3, 6)

○ (1, 3) < (2, 5) : Compare ball 3 with ball 6 to uniquely decide among (2, 3 , 5), (2, 4, 5), (2, 4, 6 )


Wrong Answer. Starting with 3 vs 3 : Step 1 reduces the possibilities to 10, and in Step 2, dividing into 3, 3, 4, but in Step 3, the 4-part cannot be determined

** Assign numbers 1 to 6 to the given 6 balls.

Step 1. Compare (1, 2, 3) with (4, 5, 6). By symmetry, we can assume (1, 2, 3) < (4, 5, 6). The combinations of heavy balls are as follows.

① (1, 4, 5)

② (1, 4, 6)

③ (1, 5, 6)

④ (2, 4, 5)

⑤ (2, 4, 6)

⑥ (2, 5, 6)

⑦ (3, 4, 5)

⑧ (3, 4, 6)

⑨ (3, 5, 6)

⑩ (4, 5, 6)

Step 2. Compare (1, 4) with (2, 5).

Step 3. Depending on the result of Step 2, use the following different strategies.

① In case (1, 4) > (2, 5) : The combinations of heavy balls are only (1, 4, 5 ), (1, 4, 6), ( 3 , 4, 6), so compare ball 3 with ball 5.

○ 3 > 5 : (3, 4, 6) is the heavy set

○ 3 = 5 : (1, 4, 6) is the heavy set

○ 3 < 5 : (1, 4, 5) is the heavy set

② In case (1, 4) < (2, 5) : The combinations of heavy balls are only (2, 4 , 5), (2, 5, 6), ( 3 , 5, 6), so compare ball 3 with ball 4.

○ 3 > 4 : (3, 5, 6) is the heavy set

○ 3 = 4 : (2, 5, 6) is the heavy set

○ 3 < 4 : (2, 4, 5) is the heavy set

③ In case (1, 4) = (2, 5) : The combinations of heavy balls are (2, 4, 6), (3, 4, 5), (1, 5, 6), (4, 5, 6), so it is impossible to uniquely decide them with one comparison by the pigeonhole principle. ( Failure )


image


Such codes were completed on ChatGPT 4.0, starting from simple cases to generalization (cf. low-dimension → high-dimension). Even if only such history is provided to ChatGPT, it’s expected that similar trials-and-errors can be performed to establish a final problem-solving strategy for similar types of problems. As if several LLMs like ChatGPT combined into a cascaded control circuit could become an AI that generates hypotheses (strategies).

One of the seven major mathematical problems, the P vs NP problem implies that ‘generalizing the solving of mathematical problems’ can also be a mathematical problem. With the overwhelming performance of ChatGPT and prompt engineering available now, if a general methodology for solving mathematical problems (i.e., a suitable open/closed serial/parallel control circuit) can be established, the implementation of hypothesis-generating AI, strategy-generating AI may not be far off. To build such a general methodology, it’s necessary to understand how our collective intelligence has been organized, and that aligns with the path I want to pursue.

However, a drawback of the above solution is its obsession with covering all possible cases. AlphaGo overcame the pattern of placing the next move in Go, a game with overwhelmingly many possibilities, and AlphaFold2 and RFDiffusion were able to create high-performance AIs by significantly reducing model complexity based on biophysics background knowledge. To create hypotheses more intelligently, it seems necessary to present ways not to obsess over all possible cases from the early stages.



Input : 2023.10.07 02:18

results matching ""

    No results matching ""