Sign in to follow this  
Ichimawashi

First shot at a banzuke algorithm

Recommended Posts

13 hours ago, Jakusotsu said:

Before making my first GTB entry in 2003, I developed a semi-automated Excel sheet based on historical data (which I can't even remember anymore where I got it from - was it banzuke.com?).

Maybe Chiyozakura's old sumoinfo.de? That was my main entry point into "serious" sumo fandom around that time (aside from the SML archives).

Share this post


Link to post
Share on other sites
4 hours ago, Akinomaki said:

Sanyaku expanded by 3 slots at once, so that was really a two-slot demotion from M1w to M1e. In general they seem to have been more open to taking the sanyaku ranks into account in that era, probably because it went up and down in size much more often than later; a notable case is post-Aki 1959 where tons of maegashira 7-8's were moved up in rank terms, but none of them more than the 2 slot sanyaku expansion.

More generally, I don't think anything that happened before approximately 1967 - when makuuchi and juryo were shrunk to modern-ish sizes - is of any significant value as precedent for today's banzuke-making. Specifically for promotions/demotions between makuuchi and juryo one should probably also ignore everything up to the late 1980s due to the many periods where they didn't stick to the divisional capacity limits.

 

Quote

Different banzuke-making era altogether where East and West rikishi were ranked separately, not together. All West-side rikishi moved to the East side there, because the West won the tozai competition. Dewaminato simply stayed M4, it was not a promotion.

Quote

Ditto the sanyaku expansion (+2 here).

Quote

This one's completely outside any normal banzuke-making, as it was the last basho before they shunted all the Dewanoumi rikishi onto one banzuke side again. (Compare Natsu 1939 with Haru 1940.)

Quote

Another +2 sanyaku expansion.

Quote

The first case is the same 1943 West-East shuttle again, the second is the same sanyaku-expanding banzuke as the M1 example.


(There's actually one of the very few genuine 7-8 promotions in that 1960.07->.09 banzuke; one rikishi moved up from M9w to M7w, so 4 half-ranks against only 3 slots extra in sanyaku.)

 

Edited by Asashosakari
  • Like 1
  • Thanks 2

Share this post


Link to post
Share on other sites
16 hours ago, Jakusotsu said:

Reminds me of my old self 16 years ago. B-)

Before making my first GTB entry in 2003, I developed a semi-automated Excel sheet based on historical data (which I can't even remember anymore where I got it from - was it banzuke.com?). That immediately earned me 3rd place, and I really thought I crafted the philosopher's stone.

Of course it turned out to be a massive fluke, and I wisened up soon enough to abandon the whole idea.

Only 3rd in your debut GTB basho? I won the whole thing in my debut basho. :-)

  • Haha 1

Share this post


Link to post
Share on other sites
17 hours ago, Pandaazuma said:

Did you have a go at the Natsu banzuke with this, @Ichimawashi ?

30 points if he had played,  fourth from the bottom..

Edited by Kintamayama

Share this post


Link to post
Share on other sites
4 hours ago, Kintamayama said:

30 points if he had played,  fourth from the bottom..

Thanks, mate.

Share this post


Link to post
Share on other sites

I ran out of time, mostly due to a strange cold that I just can’t completely shake; perhaps next time I’ll enter and see if I can do better than the “preantepenultimate” spot.  I added some conditional formatting to highlight unlikely ups and downs not matching recent results, and another function to manually bump consecutive rikishi to the other’s slot and recheck for weird ups and downs, and played a bit with it, until I saw that the banzuke was already out.  It improved a bit but I think I had several way off, Takanosho way too high IIRC.  Even with the extra knobs to correct the places where the math creates rankings that don’t match the records it is a real art to minimize the discrepancies equally.  But I think even better than the “every rank carries with it some points, every record adds or subtracts points, calculate and sort” scheme would be one where you had some lookup table “M6e, 9-6, average rise to (I’m guessing here) M3w”, then resolve the spots with multiple rikishi to minimize the differences.  I doubt it is possible for a program to do much without human intervention at some point.  Which is kind of the idea I started with, I just wanted to get a closer look at the difficulties the banzuke experts face.

Share this post


Link to post
Share on other sites
3 hours ago, Ichimawashi said:

I ran out of time, mostly due to a strange cold that I just can’t completely shake; perhaps next time I’ll enter and see if I can do better than the “preantepenultimate” spot.  I added some conditional formatting to highlight unlikely ups and downs not matching recent results, and another function to manually bump consecutive rikishi to the other’s slot and recheck for weird ups and downs, and played a bit with it, until I saw that the banzuke was already out.  It improved a bit but I think I had several way off, Takanosho way too high IIRC.  Even with the extra knobs to correct the places where the math creates rankings that don’t match the records it is a real art to minimize the discrepancies equally.  But I think even better than the “every rank carries with it some points, every record adds or subtracts points, calculate and sort” scheme would be one where you had some lookup table “M6e, 9-6, average rise to (I’m guessing here) M3w”, then resolve the spots with multiple rikishi to minimize the differences.  I doubt it is possible for a program to do much without human intervention at some point.  Which is kind of the idea I started with, I just wanted to get a closer look at the difficulties the banzuke experts face.

It's one way, but if you're judging only one rikishi movement at a time, a ton of local minima appear. Let's ignore for a second if the global minima of your penalty function actually results in the real banzuke. You're never going to find it swapping single rikishi unless you get lucky or implement something nuts like MCTS. It might be easier if you get some clever way of moving sets of rikishi around. In any case, if you do find some method to guarantee global minimum every time in this situation it would be worth a nice journal paper.

  • Like 1

Share this post


Link to post
Share on other sites

OK, I admit I haven't spent as much time on this as I would like, and my first result in GTB (82nd of 83!) shows that my program and my interventions in the tricky bits seem to have a lot to learn.  Next time I'll try to beat two other entries....

  • Haha 1

Share this post


Link to post
Share on other sites
3 hours ago, Ichimawashi said:

OK, I admit I haven't spent as much time on this as I would like, and my first result in GTB (82nd of 83!) shows that my program and my interventions in the tricky bits seem to have a lot to learn.  Next time I'll try to beat two other entries....

This kind of thing fascinates me as there is probably some algorithm somewhere waiting to be found that could do a good job of predicting the banzuke. After all, we all go through our own mental algorithms based on the loose rules we know generally apply to banzuke making. It's just finding a way to translate that. Good luck with it.

Share this post


Link to post
Share on other sites

I'm quite sure there's an algorithm for creating a flawless banzuke. However, predicting is an impossible task since there is always more than one solution, and we'll never know which brand of sake the elders were sipping.

  • Like 1

Share this post


Link to post
Share on other sites
1 hour ago, Jakusotsu said:

I'm quite sure there's an algorithm for creating a flawless banzuke. However, predicting is an impossible task since there is always more than one solution, and we'll never know which brand of sake the elders were sipping.

This is obviously true, but it is also true that some methods are better than others as some players consistently predict it very accurately. A good algorithm is one that consistently outperforms the competition, not one that performs miracles. ;)

  • Thanks 1

Share this post


Link to post
Share on other sites

I just remembered I had algorithm written in Excel VBA that I used to create a banzuke after torikumi simulations.  I never used it for GTB, but it kinda sorta works.  It only works on Sekiwake and lower.  I wrote it years ago as an afterthought from writing a workable torikumi picking simulator based on results like in RL, which was much much harder to get to yield reasonable results.  I'm fairly sure it works well given the proper inputs, but it also compacts the end of the banzuke instead of trying to fill in spots from Juryo, since those results weren't simulated.  It's somewhat obtuse and I can't remember half of what it does, but I'm confident someone writing algorithms will be able to figure it out.

Spoiler

'Class cNewBnzk:

Dim OldBanzuke(42) As cBanRik
Dim NewBanzuke(42) As Integer
Dim Ordered(42) As Integer
Dim FirstSK As Integer

Private Sub Class_Initialize()
Dim I As Integer, RikToAdd As cBanRik, Rank As String
For I = 1 To 16
    Rank = Sheets("trkm").Cells(I + 2, 1).Value
    If Rank = "k" Or Rank = "s" Then
        FirstSK = I
        Exit For
    End If
Next I
For I = FirstSK To 42
    Set RikToAdd = New cBanRik
    With RikToAdd
        .ID = I
        .Name = Sheets("trkm").Cells(I + 2, 47).Value
        .Wins = Sheets("trkm").Cells(I + 2, 46).Value
    End With
    Set OldBanzuke(I) = RikToAdd
Next I
End Sub

Sub DoStuff()
Dim I As Integer, J As Integer
For I = FirstSK To 42
    Ordered(I) = I
Next I
For I = FirstSK To 42
    For J = I + 1 To 42
        If IsHigher(Ordered(J), Ordered(I)) Then Swap I, J
    Next J
Next I
For I = FirstSK To 42
    If OldBanzuke(Ordered(I)).Placement > 42 Then Ordered(I) = 0
Next I
For I = FirstSK To 42
    FindNext I
    CollapseOrdered
Next I
For I = FirstSK To 42
    If NewBanzuke(I) <> 0 Then
        If (I - FirstSK) Mod 2 = 0 Then
            Sheets("Sheet1").Cells(2 + (I - FirstSK) / 2, 10).Value = OldBanzuke(NewBanzuke(I)).Name
        Else
            Sheets("Sheet1").Cells(2 + (I - FirstSK - 1) / 2, 11).Value = OldBanzuke(NewBanzuke(I)).Name
        End If
    End If
Next I
End Sub

Sub Swap(I As Integer, J As Integer)
Ordered(0) = Ordered(I)
Ordered(I) = Ordered(J)
Ordered(J) = Ordered(0)
End Sub

Function IsHigher(R1 As Integer, R2 As Integer) As Boolean
Dim R1P As Integer, R2P As Integer, R1W As Integer, R2W As Integer
R1P = OldBanzuke(R1).Placement
R2P = OldBanzuke(R2).Placement
R1W = OldBanzuke(R1).Wins
R2W = OldBanzuke(R2).Wins

If R1 < FirstSK + 2 Then
    R1P = R1P - 2
ElseIf R1 < FirstSK + 4 Then
    R1P = R1P - 1
End If
If R2 < FirstSK + 2 Then
    R2P = R2P - 2
ElseIf R2 < FirstSK + 4 Then
    R2P = R2P - 1
End If

If R1 = FirstSK And R1W > 7 And (R2 <> FirstSK + 1 Or R1W >= R2W) Then
    IsHigher = True
ElseIf R2 = FirstSK And R2W > 7 And (R1 <> FirstSK + 1 Or R2W >= R1W) Then
    IsHigher = False
ElseIf R1 = FirstSK + 1 And R1W > 7 Then
    IsHigher = True
ElseIf R2 = FirstSK + 1 And R2W > 7 Then
    IsHigher = False
ElseIf R1 = FirstSK + 2 And R1W > 7 And (R2 <> FirstSK + 3 Or R1W >= R2W) Then
    IsHigher = True
ElseIf R2 = FirstSK + 2 And R2W > 7 And (R1 <> FirstSK + 3 Or R2W >= R1W) Then
    IsHigher = False
ElseIf R1 = FirstSK + 3 And R1W > 7 Then
    IsHigher = True
ElseIf R2 = FirstSK + 3 And R2W > 7 Then
    IsHigher = False
ElseIf R1 < FirstSK + 2 And R1W = 7 Then
    IsHigher = True
ElseIf R2 < FirstSK + 2 And R2W = 7 Then
    IsHigher = False
ElseIf R1P > R2P Then
    IsHigher = False
ElseIf R2P > R1P Then
    IsHigher = True
ElseIf R1 < 17 And R2 > 16 Then
    IsHigher = True
ElseIf R2 < 17 And R1 > 16 Then
    IsHigher = False
ElseIf OldBanzuke(R1).Wins > OldBanzuke(R2).Wins Then
    IsHigher = True
Else
    IsHigher = False
End If
End Function

Sub FindNext(Spot As Integer)
Dim I As Integer, Lvl As Integer, NewSpot As Integer, Wins As Integer

For Lvl = 1 To 21
    For I = Spot To 42
        If Ordered(I) <> 0 Then
            Wins = OldBanzuke(Ordered(I)).Wins
            If Wins < 8 Then
                If IsAppMK(Ordered(I), Spot, Lvl) Then
                    NewBanzuke(Spot) = Ordered(I)
                    Ordered(I) = 0
                    Exit Sub
                End If
            Else
                If Ordered(I) = FirstSK + 4 And Spot > FirstSK + 3 Then
                    ForceIn Ordered(I), FirstSK + 3, Spot
                    Ordered(I) = 0
                    Exit Sub
                End If
                If Spot > 16 Then
                    If Ordered(I) - Spot < OldBanzuke(Ordered(I)).Wins - 7 Then
                        NewSpot = OldBanzuke(Ordered(I)).Placement + Wins - 7
                        ForceIn Ordered(I), NewSpot, Spot
                        Ordered(I) = 0
                        Exit Sub
                    End If
                End If
                If Ordered(I) - Spot < OldBanzuke(Ordered(I)).Wins * 4 - 29 + AppKK(Lvl) Then
                    NewBanzuke(Spot) = Ordered(I)
                    Ordered(I) = 0
                    Exit Sub
                End If
            End If
        End If
    Next I
Next Lvl
End Sub

Function IsAppMK(Rik As Integer, Spot As Integer, Lvl As Integer) As Boolean
Dim Wins As Integer, Place As Integer, SanBonus As Integer
If Rik < FirstSK + 2 Then
    SanBonus = 3
ElseIf Rik < FirstSK + 4 Then
    SanBonus = 2
ElseIf Rik < 17 Then
    SanBonus = 1
End If
If OldBanzuke(Rik).Placement > 42 Then
    IsAppMK = False
    Exit Function
End If
Wins = OldBanzuke(Rik).Wins
Select Case Spot
Case FirstSK
    IsAppMK = False
Case FirstSK + 1
    If Rik = FirstSK And Wins = 7 And Lvl > 2 Then
        IsAppMK = True
    Else
        IsAppMK = False
    End If
Case FirstSK + 2
    If Rik < FirstSK + 2 And Wins = 7 Then
        IsAppMK = True
    Else
        IsAppMK = False
    End If
Case FirstSK + 3
    If Wins = 7 And (Rik < FirstSK + 2 Or (Rik = FirstSK + 2 And Lvl > 2)) Then
        IsAppMK = True
    Else
        IsAppMK = False
    End If
Case Is > FirstSK + 3
    If Spot - Rik >= AppLossMK(Wins, Lvl + SanBonus) Then
        IsAppMK = True
    Else
        IsAppMK = False
    End If
End Select
End Function

Function AppLossMK(Wins As Integer, Lvl As Integer) As Integer
Select Case Wins
Case 7
    If Lvl < 3 Then
        AppLossMK = 2
    ElseIf Lvl < 6 Then
        AppLossMK = 1
    Else
        AppLossMK = 0
    End If
Case 6
    Select Case Lvl
    Case 1
        AppLossMK = 6
    Case 2, 3
        AppLossMK = 5
    Case 4, 5
        AppLossMK = 4
    Case 6, 7, 8
        AppLossMK = 3
    Case 9, 10, 11
        AppLossMK = 2
    Case Is > 12
        AppLossMK = 1
    End Select
Case 5
    Select Case Lvl
    Case 1
        AppLossMK = 10
    Case 2
        AppLossMK = 9
    Case 3, 4
        AppLossMK = 8
    Case 5, 6
        AppLossMK = 7
    Case 7, 8
        AppLossMK = 6
    Case 9, 10, 11
        AppLossMK = 5
    Case 12, 13, 14
        AppLossMK = 4
    Case Is > 15
        AppLossMK = 3
    End Select
Case 4
    Select Case Lvl
    Case 1
        AppLossMK = 13
    Case 2
        AppLossMK = 12
    Case 3
        AppLossMK = 11
    Case 4, 5
        AppLossMK = 10
    Case 6, 7
        AppLossMK = 9
    Case 8, 9
        AppLossMK = 8
    Case 10, 11, 12
        AppLossMK = 7
    Case 13, 14, 15
        AppLossMK = 6
    Case Is > 15
        AppLossMK = 5
    End Select
Case 3
    Select Case Lvl
    Case 1 To 5
        AppLossMK = 17 - Lvl
    Case 6
        AppLossMK = 12
    Case 7, 8
        AppLossMK = 11
    Case 9, 10
        AppLossMK = 10
    Case 11, 12
        AppLossMK = 9
    Case 13, 14, 15
        AppLossMK = 8
    Case Is > 16
        AppLossMK = 7
    End Select
Case 2
    Select Case Lvl
    Case 1 To 6
        AppLossMK = 20 - Lvl
    Case 7
        AppLossMK = 14
    Case 8, 9
        AppLossMK = 13
    Case 10, 11
        AppLossMK = 12
    Case 12, 13
        AppLossMK = 11
    Case 14, 15, 16
        AppLossMK = 10
    Case Is > 17
        AppLossMK = 9
    End Select
Case 1
    Select Case Lvl
    Case 1 To 7
        AppLossMK = 23 - Lvl
    Case 8
        AppLossMK = 16
    Case 9, 10
        AppLossMK = 15
    Case 11, 12
        AppLossMK = 14
    Case 13, 14
        AppLossMK = 13
    Case 15, 16
        AppLossMK = 12
    Case Is > 16
        AppLossMK = 11
    End Select
Case 0
    Select Case Lvl
    Case 1 To 8
        AppLossMK = 26 - Lvl
    Case 9
        AppLossMK = 18
    Case 10, 11
        AppLossMK = 17
    Case 12, 13
        AppLossMK = 16
    Case 14, 15
        AppLossMK = 15
    Case 16, 17
        AppLossMK = 14
    Case Is > 17
        AppLossMK = 13
    End Select
End Select
End Function

Sub ForceIn(Rik As Integer, NewSpot As Integer, Spot As Integer)
Dim I As Integer
For I = Spot To NewSpot + 1 Step -1
    NewBanzuke(I) = NewBanzuke(I - 1)
Next I
NewBanzuke(NewSpot) = Rik
End Sub

Sub CollapseOrdered()
Dim I As Integer, J As Integer
For I = 42 To FirstSK Step -1
    If Ordered(I) = 0 Then
        For J = I - 1 To FirstSK Step -1
            If Ordered(J) <> 0 Then
                Ordered(I) = Ordered(J)
                Ordered(J) = 0
                Exit For
            End If
        Next J
    End If
Next I
End Sub

Function AppKK(Level As Integer)
Select Case Level
Case 1
    AppKK = 0
Case Is > 1
    AppKK = 4 + 2 * (Level - 2)
End Select
End Function

'End Class

'Class cBanRik:
'(some of this is unnecessary, as it started out as a torikumi simulator)

Dim cName As String
Dim cID As Integer
Dim cWins As Integer

Property Get ID() As Integer
    ID = cID
End Property

Property Let ID(Rik As Integer)
    cID = Rik
End Property

Property Get Wins() As Integer
    Wins = cWins
End Property

Property Let Wins(Ws As Integer)
    cWins = Ws
End Property

Property Get Name() As String
    Name = cName
End Property

Property Let Name(Shikona As String)
    cName = Shikona
End Property

Property Get Placement() As Integer
    Placement = cID + 30 - 4 * cWins
End Property


'End Class

 

Sub DoBnzk()
Dim NewBanzuke As New cNewBnzk
NewBanzuke.DoStuff
End Sub

 

 

Have fun!

  • Like 2

Share this post


Link to post
Share on other sites

Looking over it, the basic gist of it is to calculate the by-the-numbers location of each rikishi on the next banzuke, use a number of criteria to resolve ties in placement, not promote MK rikishi, force promotion of KK rikishi, and use a set of criteria to determine when a less-the-the-numbers demotion of MKs is appropriate given the difficulty of finding someone to take the spot.

This is what it came up with for the most recent banzuke.  Keep in mind that rikishi who have demotable records are automatically dropped from the division, and no one is brought up from Juryo, and the last X spots are blank if X rikishi are demoted.

image.png.ff089d86019d265a87e0c649fcf0e4d0.png   

Assuming it would get the Y+O right, that's 39 points down through M9, where things would break down after that due to rikishi entering from Juryo this time around.  It would get the relative placement right of the remaining rikishi until Kaisei-Yago-Enho, which are all wrong, though the position of Enho is right by coincidence; again, it really breaks down near the bottom of the division because it doesn't attempt to fill in Juryo rikishi.  It promotes Chiyomaru and Sadanoumi because the promotion of Tochinoshin means that it thinks it isn't promoting them; they are at the same number position on the banzuke, but those numbered positions correspond to half-rank differences in Maegashira because of the addition of an Ozeki. 

So because of all the faults mentioned I never tried using it for GTB, but it worked for what it was designed to do, which was calculate the relative likelihood of rikishi landing at each banzuke spot, mainly the ones in the joi, because I would run a tournament simulation a number of times and work out where everyone would land.  I have no idea why I was interested enough in this information to write an extremely complicated torikumi simulator (that used relative win likelihoods from my prediction engine) and slightly less complicated banzuke algorithm, given that it's of no apparent use for any of the sumo games.  I probably just had sumo on the brain and wanted something that engaged my mind while looking for a job.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this