Mastermind2368
Veteran
I'm currently taking an Intro to Machine Learning course, and my semester-long project focuses on using ML to help find new (human usable) 3x3 methods. I need some help coming up with metrics on how to quantify 3x3 methods. I definitely want to post my findings once the project is complete, but I'll go ahead and explain some of the basics of it right now.
At a high level, each 3x3 method has a dedicated file made with a custom TOML-like syntax, these are the DSL files (domain specific language). It defines all of the steps needed to solve a cube by specifying what pieces are added during that step. This is what an annotated CFOP DSL file looks like:
There's also a solver program which solves the cube using a custom defined method. This is a CFOP solution.
Now that I've explained the basics of how the DSL structure is defined, let's go back to the intention of the post - quantifying methods. In the end, I want to be able to take a method's DSL and extract features from it. These features will serve as training data, and will try to predict a method's "score" (details about the score aren't super relevant, but it's correlated to things like move count and number of moves per step). In the end, I want to have my machine learning model to take this data and accurately predict what makes a good scoring method. These are some features I'm currently extracting:
All of these features can be determined by statically analyzing a method, for example it's easy to tell how many steps a method has. They're definitely a good start but I need to extract more. One idea I have is to get a "score" for how many pieces within a step are on the same layer. But I think it would be helpful to have more features.
So, TLDR; does anyone have any ideas on what other features can be statically extracted from a method, given my method DSL? Would love to hear your ideas!
At a high level, each 3x3 method has a dedicated file made with a custom TOML-like syntax, these are the DSL files (domain specific language). It defines all of the steps needed to solve a cube by specifying what pieces are added during that step. This is what an annotated CFOP DSL file looks like:
Code:
[METHOD: CFOP| rotation=x2] // Method name + starting orientation
[STEP: cross] // Start off with empty cube, add cross edges
init_empty_cube
add_edge UF
add_edge UB
add_edge UR
add_edge UL
//Steps within a group can be solved in different "orders" depending on the
//option specified. "best_1" will consider all unsolved F2L pairs,
//and solve the one with the fewest moves. "best_N", where N >=1
//finds the best way to solve N steps.
//There are other orders such as "worst_N", "in_order", and "random"
[GROUP: F2L | order=best_1]
[STEP: pair_fr]
add_edge BR
add_corner UBR
[STEP: pair_fl]
add_edge BL
add_corner UBL
[STEP: pair_bl]
add_edge FL
add_corner UFL
[STEP: pair_br]
add_edge FR
add_corner UFR
[END GROUP]
// Before a brute force OLL search, it checks a cache to see if the algorithm was found.
// If not, it will output the discovered algorithm to the cache.
[STEP: oll | cache_alg=true | free_layer=D]
add_corners_orientation
add_edges_orientation
[STEP: pll | cache_alg=true | free_layer=D]
add_edge FD
add_edge BD
add_edge LD
add_edge RD
add_corner DFR
add_corner DBR
add_corner DBL
add_corner DFL
[END METHOD]
There's also a solver program which solves the cube using a custom defined method. This is a CFOP solution.
Example output when just running the solver:
Code:
F2 D2 U R F B R F2 R2 F2 L D' F' R U' R2 B U F R' L2 F2 L2 R' //scramble
x2 //orientation
R' F L B D B' //cross
U' B2 U' B U B2 //pair_bl
L' U' L2 F2 L' F2 //pair_fr
B U' B' F U' F' //pair_fl
L F2 D R D' F2 L' //pair_br
U2 F R U R2 U' R F' R' U R //oll
R' U L' U R U2 F R B2 R' F' B2 U L U //pll
Now that I've explained the basics of how the DSL structure is defined, let's go back to the intention of the post - quantifying methods. In the end, I want to be able to take a method's DSL and extract features from it. These features will serve as training data, and will try to predict a method's "score" (details about the score aren't super relevant, but it's correlated to things like move count and number of moves per step). In the end, I want to have my machine learning model to take this data and accurately predict what makes a good scoring method. These are some features I'm currently extracting:
Code:
+-------------------------------+---------------------------------------------------------------+
| Feature | Description |
+-------------------------------+---------------------------------------------------------------+
| num_steps | Total number of steps in the method |
| num_groups | Number of step groups the method is divided into |
| num_removes | Number of removal operations across all steps |
| avg_constraints_per_step | Average number of constraints added per step |
| max_constraints_per_step | Maximum constraints added in any single step |
| num_cache_alg_steps | Number of steps that require algorithms to solve |
| num_free_layer_steps | Number of algorithm steps that have a free layer |
| symmetry_depth | Number of steps to search when evaluating the best symmetry |
| num_symmetry_orientations | Number of distinct orientations considered under symmetry |
| num_edge_constraints | Total number of edge piece constraints across all steps |
| num_corner_constraints | Total number of corner piece constraints across all steps |
| num_orientation_constraints | Total number of orientation constraints across all steps |
| constraint_type_diversity | Measure of how varied the constraint types are across steps |
+-------------------------------+---------------------------------------------------------------+
All of these features can be determined by statically analyzing a method, for example it's easy to tell how many steps a method has. They're definitely a good start but I need to extract more. One idea I have is to get a "score" for how many pieces within a step are on the same layer. But I think it would be helpful to have more features.
So, TLDR; does anyone have any ideas on what other features can be statically extracted from a method, given my method DSL? Would love to hear your ideas!
Last edited: