Setup and release notes

A quick shortcut button to go in and out of presentation mode (this can also be done using the “Format->Screen Environment” menu).

Initialization code for the presentation. It needs to be run before any of the interactive parts of the presentation can be used.

Needs["Combinatorica`"];

StartStopPresentationButton[]:=DynamicModule[{buttonlabel,buttonaction},
buttonlabel=Style["Start Presentation",Black];Button[Dynamic[buttonlabel],If[(ScreenStyleEnvironment/.Options[EvaluationNotebook[],ScreenStyleEnvironment])=="Working",
(buttonlabel=Style["Stop Presentation",Darker[Red]];SetOptions[EvaluationNotebook[],ScreenStyleEnvironment->"SlideShow"]),
(buttonlabel=Style["Start Presentation",Black];SetOptions[EvaluationNotebook[],ScreenStyleEnvironment->"Working"])]&,ImageSize->240]
];

OEISLookup[sequence_]:=Module[{url},
  url = "http://oeis.org/search?q=";
  Do[url = url<>ToString[sequence[[i]]]<>If[i<Length[sequence],"%2C","&languge=english&go=Search"] ,{i,1,Length[sequence]}];
  SystemOpen[url]
];

AECCourseOutline[]:=DynamicModule[{lecturestrings,grid,permutation,buttonlabel},
buttonlabel="";
lecturestrings={
"The most important formula in combinatorics",
"Longest increasing subsequences",
"Limit shapes",
"Asymptotic enumeration techniques: Stirling's formula, saddle point analysis",
"Advanced asymptotic enumeration techniques: the Hardy-Ramanujan formula and some recent generalizations",
"If time permits: other things"
};
grid=
Grid[Table[{Style["•",28,RGBColor[0,0.45,0.72]],Style[If[k==Length[lecturestrings],"","Lecture "<>ToString[k]<>": "]<>lecturestrings[[k]],24,FontFamily->"Helvetica Neue"]},{k,1,Length[lecturestrings]}],Alignment->Left,Spacings->{1,2}];
Column[{
Dynamic[grid],
"",
Button[Dynamic[buttonlabel],(buttonlabel="Randomize order";permutation=RandomPermutation[Length[lecturestrings]];grid=
Grid[Table[{Style["•",28,RGBColor[0,0.45,0.72]],Style[If[permutation[[k]]==Length[lecturestrings],"","Lecture "<>ToString[k]<>": "]<>lecturestrings[[permutation[[k]]]],24,FontFamily->"Helvetica Neue"]},{k,1,Length[lecturestrings]}],Alignment->Left,Spacings->{1,2}];)&,ImageSize->200]
}]
];

(* *******
The next command is adapted from the discussion on
http://mathematica.stackexchange.com/questions/88346/framing-a-combination-of-cells-in-the-notebook 
******* *)
framecells[]:=Button["Frame Multiple Cells",
  With[{cells = Cells[NotebookSelection[InputNotebook[]]]},
   MapThread[
    Function[{frame, pos},
     MapAt[
      SetOptions[#,
        CellMargins -> {{121, 81}, {0, 0}},
        CellFrame   -> {{2, 2}, frame},
        Background  -> LightBlue] &,
      cells,
      pos
     ]
    ],
    {{{0, 2}, {0, 0}, {2, 0}}, {1, 2 ;; -2, -1}}
   ]
  ]
] // CreatePalette


OSP[n_]:=Module[{per,walk,j,t},
per=Table[k,{k,1,n}];j=0;
walk={per};
While[j<n(n-1)/2,
t=RandomInteger[{1,n-1}];
While[per[[t]]>per[[t+1]],
t=RandomInteger[{1,n-1}];
];
per[[{t,t+1}]]={per[[t+1]],per[[t]]};
AppendTo[walk,per];
j=j+1;
];
walk
];

OSPGraphics[n_]:=Map[Graphics[{PointSize[0.05],
						Table[{ColorData["Rainbow"][(k-1)/(n-1)],
								Point[{k,#[[k]]}]},{k,1,n}]}]&,OSP[n]];

CornerGrowth[n_]:=Module[{par,walk,steps,j,t},
par={1};j=0;
walk={par};
steps={1};
While[j<n-1,
t=RandomInteger[{1,Length[par]+1}];
While[1<t≤Length[par]&&par[[t]]==par[[t-1]],
t=RandomInteger[{1,Length[par]+1}];
];
If[t==Length[par]+1,AppendTo[par,1],par[[t]]=par[[t]]+1];
AppendTo[walk,par];
AppendTo[steps,t];
j=j+1;
];
{walk,steps}
];
CornerGrowthGraphics[n_]:=Module[{walk,steps},
{walk,steps}=CornerGrowth[n];
Table[
Graphics[{PointSize[0.03],
Table[{If[i==steps[[k]]&&j==walk[[k]][[i]],Hue[(k-1)/(n-1)],Black],
Point[{i,j}]},{i,1,Length[walk[[k]]]},{j,1,walk[[k]][[i]]}]},
PlotRange->{{0.5,walk[[n]][[1]]+0.5},{0.5,Length[walk[[n]]]+0.5}}]
,{k,1,n}]
];

YoungDiagram[partition_]:=Module[{transpose,p1,p2},
p1=Prepend[partition,partition[[1]]];
transpose=TransposePartition[partition];
p2=Prepend[transpose,transpose[[1]]];
Graphics[
Join[Table[Line[{{0,i-1},{p1[[i]],i-1}}],{i,1,Length[p1]}],Table[Line[{{i-1,0},{i-1,p2[[i]]}}],{i,1,Length[p2]}]
]
]
];
YoungTableau[tableau_]:=Graphics[
{
YoungDiagram[Map[Length,tableau]][[1]],
Table[Style[Text[tableau[[i]][[j]],{j-1/2,i-1/2}],25],{i,1,Length[tableau]},{j,1,Length[tableau[[i]]]}]
}
];

SublevelTableau[tableau_,level_]:=Select[Map[Function[list,Select[list,#≤level&]],tableau],#≠{}&];AllSublevelTableaux[tableau_]:=Table[SublevelTableau[tableau,k],{k,1,Max[Flatten[tableau]]}];
AllSublevelTableauxGraphics[tableau_]:=Map[Show[YoungTableau[#],PlotRange->{{0,Length[tableau]},{0,Length[tableau[[1]]]}}]&,AllSublevelTableaux[tableau]];

HookLengthTableau[partition_]:=Module[{transpose},
transpose=TransposePartition[partition];
Table[partition[[i]]-j+transpose[[j]]-i+1,{i,1,Length[partition]},{j,1,partition[[i]]}]
];

FormattedNumberOfSYT[partition_]:=Module[{hooklengths,n},
n=Apply[Plus,partition];
hooklengths=Flatten[HookLengthTableau[partition]];
Inactive[Factorial][n]/Apply[Inactive[Times],hooklengths]
];

NumberOfSYT[partition_]:=Module[{hooklengths,n},
n=Apply[Plus,partition];
hooklengths=Flatten[HookLengthTableau[partition]];
Factorial[n]/Apply[Times,hooklengths]
];

HookGraphics[partition_,box_]:=Module[{transpose},
transpose=TransposePartition[partition];
Graphics[{RGBColor[0.9,0,0,0.3],EdgeForm[{Black,AbsoluteThickness[2]}],Map[Rectangle[{#[[2]]-1,#[[1]]-1},{#[[2]],#[[1]]}]&,Join[Table[{box[[1]],j},{j,box[[2]],partition[[box[[1]]]]}],
Table[{i,box[[2]]},{i,box[[1]]+1,transpose[[box[[2]]]]}]
]]}]
];

HookVisualization[partition_,box_]:=Graphics[{HookGraphics[partition,box][[1]],YoungDiagram[partition][[1]]}];

InteractiveHookVisualization[partition_]:=
DynamicModule[{pt={0.5,0.5},showhookslens=False},Column[{ClickPane[Dynamic@
Show[HookVisualization[partition,Reverse[Ceiling[pt]]],
If[showhooklens,YoungTableau[HookLengthTableau[partition]],{}],ImageSize->400
]
,(pt=#)&],"Click any box in the Young diagram to show its hook",Row[{
Checkbox[Dynamic[showhooklens]]," Check this box to show the hook lengths"
}]}]];

HookBoxes[partition_,box_]:=Module[{transpose},
transpose=TransposePartition[partition];
Join[Table[{box[[1]],j},{j,box[[2]],partition[[box[[1]]]]}],
Table[{i,box[[2]]},{i,box[[1]]+1,transpose[[box[[2]]]]}]
]
];

HookWalk[partition_]:=Module[{transpose,box,nextbox,hook,walk,height,width},
transpose=TransposePartition[partition];
width=partition[[1]];
height=Length[partition];
box={1,width+1};
While[box[[2]]>partition[[box[[1]]]],
box[[1]]=RandomInteger[{1,height}];
box[[2]]=RandomInteger[{1,width}];
];
walk={box};
While[box[[2]]<partition[[box[[1]]]]||box[[1]]<transpose[[box[[2]]]],
hook=HookBoxes[partition,box];
nextbox=box;
While[nextbox==box,nextbox=hook[[RandomInteger[{1,Length[hook]}]]]];
AppendTo[walk,nextbox];
box=nextbox;
];
walk
];

HookWalkGraphics[hookwalk_]:=
Table[Graphics[{AbsolutePointSize[12],RGBColor[0.2,0.1,0.6],Table[Point[{hookwalk[[k]][[2]]-1/2,hookwalk[[k]][[1]]-1/2}],{k,1,j}],
Line[Table[{hookwalk[[k]][[2]]-1/2,hookwalk[[k]][[1]]-1/2},{k,1,j}]]
}
],{j,1,Length[hookwalk]}];

HookWalkAnimation[partition_]:=Module[{hookwalk,hookwalkgraphics},
hookwalk=HookWalk[partition];
hookwalkgraphics=HookWalkGraphics[hookwalk];Table[Show[YoungDiagram[partition],hookwalkgraphics[[Floor[1+(m+1)/3]]],
If[Mod[m,3]≠0,HookGraphics[partition,hookwalk[[Floor[1+m/3]]]],{}]
],{m,0,-2+3Length[hookwalkgraphics]}]
];

HookWalkInteractiveVisualization[partition_]:=DynamicModule[{animatedwalk=ListAnimate[HookWalkAnimation[partition],AnimationRepetitions->1,FrameLabel->{{"",""},{"",Style["Visualization of the hook walk on a Young diagram",16]}}]},
Column[{Dynamic[animatedwalk],Button["Do another hook walk",(animatedwalk=ListAnimate[HookWalkAnimation[partition],AnimationRepetitions->1,FrameLabel->{{"",""},{"",Style["Visualization of the hook walk on a Young diagram",16]}}])&]}]
];

ReverseHookGraphics[partition_,box_]:=Module[{transpose},
transpose=TransposePartition[partition];
Graphics[{RGBColor[0.9,0,0,0.3],EdgeForm[{Black,AbsoluteThickness[2]}],Map[Rectangle[{#[[2]]-1,#[[1]]-1},{#[[2]],#[[1]]}]&,Join[Table[{box[[1]],j},{j,1,box[[2]]}],
Table[{i,box[[2]]},{i,1,box[[1]]-1}]
]]}]
];

ReverseHookVisualization[partition_,box_]:=Graphics[{ReverseHookGraphics[partition,box][[1]],YoungDiagram[partition][[1]]}];

InteractiveReverseHookVisualization[partition_]:=
DynamicModule[{pt={0.5,Length[partition]-0.5},showhookslens=False,hooklengths=HookLengthTableau[partition]},Column[{ClickPane[Dynamic@
Show[ReverseHookVisualization[partition,Reverse[Ceiling[pt]]],
If[showhooklens,Graphics[
{Gray,Table[
If[(i≠Ceiling[pt[[2]]]&&j≠Ceiling[pt[[1]]])||(i==Ceiling[pt[[2]]]&&j==Ceiling[pt[[1]]]),
Text[hooklengths[[i]][[j]],{j-0.5,i-0.5}],
{Black,Style[Text[ToString[hooklengths[[i]][[j]]]<>"/"<>ToString[hooklengths[[i]][[j]]-1],{j-0.5,i-0.5}],Larger]}
],
{i,1,Length[hooklengths]},{j,1,Length[hooklengths[[i]]]}]}
],{}],ImageSize->400
]
,(pt=#)&],"Click a corner in the Young diagram to show its reverse hook",Row[{
Checkbox[Dynamic[showhooklens]]," Check this box to show the hook lengths"
}]}]];

MySubsetToPathFunction[n_,subset_]:=Module[{complement,seq1,seq2,j},
seq1={1};j=1;
Do[AppendTo[seq1,Last[seq1]+If[j>Length[subset]||k<subset[[j]],0,j=j+1;1]],{k,1,n}];
complement=Complement[Range[1,n],subset];
seq2={1};j=1;
Do[AppendTo[seq2,Last[seq2]+If[j>Length[complement]||k<complement[[j]],0,j=j+1;1]],{k,1,n}];
Table[{seq1[[k]],seq2[[k]]},{k,1,n+1}]
];

LineWithDisks[points_]:={Line[points],RGBColor[0.2,0.1,0.6],AbsolutePointSize[12],Map[Point,points]};

HookWalkProjectionsVisualization[partition_,hproj_,vproj_]:=Module[{yd,hprojdots,vprojdots,linesgraphics},
yd=YoungDiagram[partition];
hprojdots=Table[Point[{hproj[[j]]-0.5,-0.5}],{j,1,Length[hproj]}];
vprojdots=Table[Point[{-0.5,vproj[[j]]-0.5}],{j,1,Length[vproj]}];
linesgraphics=Map[LineWithDisks[Table[{hproj[[#[[k]][[1]]]]-0.5,vproj[[#[[k]][[2]]]]-0.5},{k,1,Length[#]}]]&
,Map[MySubsetToPathFunction[Length[hproj]+Length[vproj]-2,#]&,Subsets[Range[Length[hproj]+Length[vproj]-2],{Length[hproj]-1}]]
];
ListAnimate[Table[Graphics[{YoungDiagram[partition][[1]],
{AbsolutePointSize[6],hprojdots,vprojdots},
{RGBColor[0,0,0,0],EdgeForm[Red],Rectangle[{0,-0.8},{partition[[1]],-0.2},RoundingRadius->0.3]},
{RGBColor[0,0,0,0],EdgeForm[Red],Rectangle[{-0.8,0},{-0.2,Length[partition]},RoundingRadius->0.3]},
{Red,Style[Text["A⋃{a}",{partition[[1]]/2,-1.3}],20],
Style[Text["B⋃{b}",{-2,Length[partition]/2}],20],
Style[Text["(a,b)",{Max[hproj-0.3],Max[vproj]+0.5}],20]},
{Black,linesgraphics[[k]]}}],{k,1,Length[linesgraphics]}],FrameLabel->{{"",""},{"",Style["Hook walks with prescribed horizontal and vertical projections",16]}}]
];

LongestDecreasingSubsequence[permutation_]:=Reverse[LongestIncreasingSubsequence[Reverse[permutation]]];
LIS[permutation_]:=Length[LongestIncreasingSubsequence[permutation]];
LDS[permutation_]:=Length[LongestDecreasingSubsequence[permutation]];

PatienceSorting[perm_]:=Module[{stacks,stackshistory},
If[perm=={},Return[{}]];
stacks={{perm[[1]]}};
stackshistory={stacks};
Do[If[perm[[j]]>Last[stacks][[1]],AppendTo[stacks,{perm[[j]]}],
PrependTo[stacks[[Min[Select[Range[Length[stacks]],stacks[[#]][[1]]>perm[[j]]&]]]],perm[[j]]]
];
AppendTo[stackshistory,stacks]
,{j,2,Length[perm]}];
Prepend[stackshistory,{}]
];

(*PatienceSortingVisualization[perm_]:=Module[{stackshistory,width,height},
stackshistory=PatienceSorting[perm];
width=Length[Last[stackshistory]];
height=Max[Map[Length,Last[stackshistory]]];
ListAnimate[Table[
Column[{
Graphics[{
Table[{Style[Text[stackshistory[[n]][[k]][[j]],{k-1/2,j-1/2}],20],
{RGBColor[0,0,0,0],EdgeForm[Black],Rectangle[{k-1,j-1},{k,j}]}
},{k,1,Length[stackshistory[[n]]]},{j,1,Length[stackshistory[[n]][[k]]]}]
},PlotRange->{{-0.1,width+0.1},{-0.1,height+0.1}},ImageSize->450],
Graphics[{
Table[Style[Text[perm[[k]],{k,0}],{14,If[k<n-1,Bold,If[k==n-1,{Bold,Red},{}]]}],{k,1,Length[perm]}]},ImageSize->450,PlotRange->{{0,Length[perm]+1},{-1,1}}]
},Frame->All],
{n,1,Length[stackshistory]}],FrameLabel->{{Style["The stacks",16],""},{Style["The permutation",16],Style["Patience sorting of a permutation",20]}},AnimationRepetitions->1,DefaultDuration->Length[stackshistory]]
];*)

PatienceSortingWithPointers[perm_]:=Module[{stacks,stackshistory,index},
If[perm=={},Return[{}]];
stacks={{{perm[[1]],0}}};
stackshistory={stacks};
Do[If[perm[[j]]>Last[stacks][[1]][[1]],AppendTo[stacks,{{perm[[j]],1}}],
index=Min[Select[Range[Length[stacks]],stacks[[#]][[1]][[1]]>perm[[j]]&]];
PrependTo[stacks[[index]],{perm[[j]],1}];
If[Length[stacks]>index,Do[stacks[[index+1]][[m]][[2]]=stacks[[index+1]][[m]][[2]]+1,{m,1,Length[stacks[[index+1]]]}]]
];
AppendTo[stackshistory,stacks]
,{j,2,Length[perm]}];
Prepend[stackshistory,{}]
];

PatienceSortingAnimation[perm_,showpointers_]:=Module[{stackshistory,width,height,pt1,pt2,dist,c1,c2},
stackshistory=PatienceSortingWithPointers[perm];
width=Length[Last[stackshistory]];
height=Max[Map[Length,Last[stackshistory]]];
Table[
Column[{
Graphics[{
Table[{Style[Text[stackshistory[[n]][[k]][[j]][[1]],{k-1/2,j-1/2}],20],
{RGBColor[0,0,0,0],EdgeForm[Black],Rectangle[{k-1,j-1},{k,j}]},
If[showpointers&&k>1,
pt1={k-1/2,j-1/2};
pt2={k-3/2,stackshistory[[n]][[k]][[j]][[2]]-1/2};
dist=Norm[pt1-pt2];
c1=0.2/dist;
c2=1-c1;
{Arrowheads[0.022],RGBColor[0,0,0.75],Arrow[{c2*pt1+c1*pt2,c2*pt2+c1*pt1}]}
,{}]
},{k,1,Length[stackshistory[[n]]]},{j,1,Length[stackshistory[[n]][[k]]]}]
},PlotRange->{{-0.1,width+0.1},{-0.1,height+0.1}},ImageSize->450],
Graphics[{
Table[Style[Text[perm[[k]],{k,0}],{14,If[k<n-1,Bold,If[k==n-1,{Bold,Red},{}]]}],{k,1,Length[perm]}]},ImageSize->450,PlotRange->{{0,Length[perm]+1},{-1,1}}]
},Frame->All],
{n,1,Length[stackshistory]}]
];

PatienceSortingVisualization[permutation_]:=Manipulate[
patiencesortinganimation1=PatienceSortingAnimation[permutation,False];
patiencesortinganimation2=PatienceSortingAnimation[permutation,True];
If[showpointers,patiencesortinganimation2[[k]],patiencesortinganimation1[[k]]],{{k,1,"Time"},1,Length[permutation]+1,1},{{showpointers,False,"Show pointers"},Checkbox},FrameLabel->{{Style["The stacks",16],""},{Style["The permutation",16],Style["Patience sorting of a permutation",20]}}
];


RSKInsertion[tableau_,newsymbol_]:=Module[{newtableau,row,col,currentsymbol,nextsymbol},
If[Length[tableau]==0,Return[{{newsymbol}}]];
newtableau=tableau;
currentsymbol=newsymbol;
row=1;
While[row≤Length[newtableau],
col=Min[Select[Range[Length[newtableau[[row]]]],(newtableau[[row]][[#]]>currentsymbol)&]];
If[col==∞,
AppendTo[newtableau[[row]],currentsymbol];
Return[newtableau];
];
nextsymbol=newtableau[[row]][[col]];
newtableau[[row]][[col]]=currentsymbol;
currentsymbol=nextsymbol;
row=row+1;
];
AppendTo[newtableau,{currentsymbol}];
Return[newtableau];
];

RSKPTableau[permutation_]:=Module[{Ptableau},
Ptableau={};
Do[Ptableau=RSKInsertion[Ptableau,permutation[[j]]],{j,1,Length[permutation]}];
Ptableau
];

RSKInsertionWithBumpingRoute[tableau_,newsymbol_]:=Module[{newtableau,row,col,currentsymbol,nextsymbol,bumpingroute},
If[Length[tableau]==0,Return[{{{newsymbol}},{{1,1}}}]];
newtableau=tableau;
currentsymbol=newsymbol;
row=1;
bumpingroute={};
While[row≤Length[newtableau],
col=Min[Select[Range[Length[newtableau[[row]]]],(newtableau[[row]][[#]]>currentsymbol)&]];
If[col==∞,
AppendTo[newtableau[[row]],currentsymbol];
AppendTo[bumpingroute,{row,Length[newtableau[[row]]]}];
Return[{newtableau,bumpingroute}];
];
nextsymbol=newtableau[[row]][[col]];
newtableau[[row]][[col]]=currentsymbol;
currentsymbol=nextsymbol;
AppendTo[bumpingroute,{row,col}];
row=row+1;
];
AppendTo[bumpingroute,{row,1}];
AppendTo[newtableau,{currentsymbol}];
Return[{newtableau,bumpingroute}];
];

RSKTableaux[permutation_]:=Module[{Ptableau,Qtableau,bumpingroute,addedbox},
Ptableau={};
Qtableau={};
Do[
{Ptableau,bumpingroute}=RSKInsertionWithBumpingRoute[Ptableau,permutation[[j]]];
addedbox=Last[bumpingroute];
If[Length[Qtableau]<addedbox[[1]],AppendTo[Qtableau,{j}],
AppendTo[Qtableau[[addedbox[[1]]]],j]
],{j,1,Length[permutation]}];
{Ptableau,Qtableau}
];

RSKTableauxAndBumpingRoutesWithHistory[permutation_]:=Module[{Ptableau,Qtableau,bumpingroute,Ptabhistory,Qtabhistory,bumpingrouteshistory,addedbox},
Ptableau={};
Qtableau={};
Ptabhistory={};
Qtabhistory={};
bumpingrouteshistory={};
Do[
{Ptableau,bumpingroute}=RSKInsertionWithBumpingRoute[Ptableau,permutation[[j]]];
AppendTo[bumpingrouteshistory,bumpingroute];
addedbox=Last[bumpingroute];
If[Length[Qtableau]<addedbox[[1]],AppendTo[Qtableau,{j}],
AppendTo[Qtableau[[addedbox[[1]]]],j]];
AppendTo[Ptabhistory,Ptableau];
AppendTo[Qtabhistory,Qtableau];
,{j,1,Length[permutation]}];
{Ptabhistory,Qtabhistory,bumpingrouteshistory}
];

RSKAnimation[permutation_,showbumpingroutes_,showQtableaux_]:=Module[{Ptabs,Qtabs,bumpingroutes,width,height},
{Ptabs,Qtabs,bumpingroutes}=RSKTableauxAndBumpingRoutesWithHistory[permutation];
width=Length[Last[Ptabs][[1]]];
height=Length[Last[Ptabs]];
Table[Row[{
Graphics[{
YoungTableau[Ptabs[[k]]][[1]],
Style[Text["P",{width/2,-0.4}],{20,Italic}],
If[showQtableaux,Style[Text["Q",{width*3/2+2,-0.4}],{20,Italic}],{}],
If[showQtableaux,Translate[YoungTableau[Qtabs[[k]]][[1]],{width+2,0}],,{}],
If[showbumpingroutes,{RGBColor[1,0,0,0.3],Table[Rectangle[Reverse[bumpingroutes[[k]][[j]]]-{1,1},Reverse[bumpingroutes[[k]][[j]]]],{j,1,Length[bumpingroutes[[k]]]}]},{}],
Line[{{-0.05,-0.75},{2width+2.1,-0.75}}]
},
PlotRange->{{-0.05,2width+2.1},{-0.8,height+0.05}},ImageSize->700],
(*******)
Graphics[{
Table[Style[Text[permutation[[m]],{m,0}],{14,If[m<k,Bold,If[m==k,{Bold,Red},{}]]}],{m,1,Length[permutation]}]},ImageSize->700,PlotRange->{{0,Length[permutation]+1},{-0.3,0.3}}]
},Frame->all]
,{k,1,Length[Ptabs]}]
];

RSKVisualization[permutation_]:=Manipulate[
rskanimation1=RSKAnimation[permutation,False,False];
rskanimation2=RSKAnimation[permutation,True,False];
rskanimation3=RSKAnimation[permutation,False,True];
rskanimation4=RSKAnimation[permutation,True,True];
If[showbumpingroutes&&showQtableaux,rskanimation4[[time]],
If[showbumpingroutes&&!showQtableaux,rskanimation2[[time]],
If[!showbumpingroutes&&showQtableaux,rskanimation3[[time]],
rskanimation1[[time]]]]]
,{{time,1,"Time"},1,Length[permutation],1,ImageSize->600},{{showbumpingroutes,False,"Show bumping routes"},Checkbox},{{showQtableaux,False,"Show Q tableau"},Checkbox},FrameLabel->{{"",""},{Style["The permutation",16],Style["The RSK algorithm",20]}}
];

Ω[u_]:=(2/π)(u ArcSin[(u/(Sqrt[2]))]+(Sqrt[2-(u^2)]));
PlancherelLimitShapeRotated=Show[
Plot[{Ω[u],Abs[u]},{u,-(Sqrt[2]),(Sqrt[2])},AspectRatio->Automatic,
   PlotStyle->{{Black,Thick}},
   Filling->{1->{2}},
   FillingStyle->RGBColor[0,0.5,0.2,0.4],
   AxesLabel->{Style["u",16,Italic],Style["v",16,Italic]}],
Graphics[{GrayLevel[0.5],
Table[Line[{{u,u},{u-0.03,u+0.03}}],{u,0,(Sqrt[2]),(Sqrt[2])/4}],
Table[Line[{{-u,u},{-u+0.03,u+0.03}}],{u,0,(Sqrt[2]),(Sqrt[2])/4}],
Table[Line[{{u,u},{u-0.015,u+0.015}}],{u,0,(Sqrt[2]),(Sqrt[2])/20}],
Table[Line[{{-u,u},{-u+0.015,u+0.015}}],{u,0,(Sqrt[2]),(Sqrt[2])/20}],
Style[Text["x",{(Sqrt[2])+0.12,(Sqrt[2])+0.12}],16,Italic],
Style[Text["y",{-(Sqrt[2])-0.12,(Sqrt[2])+0.12}],16,Italic],
Text["1.0",{(1/2)(Sqrt[2])+0.05,(1/2)(Sqrt[2])-0.07}],
Text["2.0",{(Sqrt[2])+0.05,(Sqrt[2])-0.07}],
Text["1.0",{-(1/2)(Sqrt[2])-0.05,(1/2)(Sqrt[2])-0.07}],
Text["2.0",{-(Sqrt[2])-0.05,(Sqrt[2])-0.07}],
Line[{{0,0},{(Sqrt[2])+0.05,(Sqrt[2])+0.05}}],
Line[{{0,0},{-(Sqrt[2])-0.05,(Sqrt[2])+0.05}}]
}],PlotRange->All,ImageSize->450
];

PlancherelLimitShape=Rotate[Show[Plot[{Ω[u],Abs[u]},{u,-(Sqrt[2]),(Sqrt[2])},AspectRatio->Automatic,
   PlotStyle->{{Black,Thick}},
   Filling->{1->{2}},
   FillingStyle->RGBColor[0,0.5,0.2,0.4],
   Axes->False],ImageSize->450],-π/4,{0,0}];

UniformPartitionLimitShape=Show[Plot[-(Sqrt[6])/π Log[1-Exp[-π x/(Sqrt[6])]],{x,0.0478378,2.2},AspectRatio->Automatic,PlotStyle->{Black,Thick},PlotRange->{{-0.02,2.5},{-0.02,2.5}},Axes->False,Filling->{1->Axis},FillingStyle->LightPurple],
Plot[-(Sqrt[6])/π Log[1-Exp[-π x/(Sqrt[6])]],{x,2.2,2.5},PlotStyle->{Black,Thick,Dashing[Small]},Filling->{1->0},FillingStyle->LightPurple],
Plot[-(Sqrt[6])/π Log[1-Exp[-π x/(Sqrt[6])]],{x,0,0.0478378},PlotStyle->{Black,Thick,Dashing[Small]},Filling->{1->0},FillingStyle->LightPurple],
Graphics[{Thick,Line[{{0,2.2},{0,0},{2.2,0}}],
{Dashing[Small],Line[{{0,2.2},{0,2.5}}],Line[{{2.2,0},{2.5,0}}]}
}]];

Release notes

Created with Mathematica 10.3.

Release history and log of changes:

This version: August 5, 2016 (improved slide 25)

Initial version: August 1, 2016

Combinatorics at the interface of probability, analysis and experimental mathematics

Dan Romik

Algorithmic and Enumerative Combinatorics Summer School
RISC (Hagenberg, Austria), August 2016

Introduction: what all those fancy words mean

I’m interested in, and will try to teach you something about, the following subjects:

Combinatorics: studying interesting discrete families of objects, their properties, natural mappings between them, enumeration, connections to algebra.

Probability: what happens when you perform a probabilistic experiment involving random combinatorial objects.

Analysis: how we can use calculus, complex analysis and related math to derive asymptotic results about combinatorics and probability.

Experimental mathematics: using computers to discover, visualize and do interesting (and completely rigorous) mathematics.

Some examples

Stirling’s formula

Table[n!,{n,1,10}]

Table[Product[k,{k,1,n}],{n,1,10}]

n! ~ (Sqrt[2π n])((((n/e)))^n)

The Hardy-Ramanujan formula

Table[PartitionsP[n],{n,0,20}]

CoefficientList[Series[Product[1/(1-(x^k)),{k,1,20}],{x,0,20}],x]

p(n) ~ (1/(4(Sqrt[3])n))(e^(π(Sqrt[2n/3])))

The hook-length formula

(Subscript[d, λ]) = ((n!)/((Subscript[Π, (i,j)]) (Subscript[h, λ])(i,j)))

The alternating sign matrix theorem

(Subscript[A, n]) = ((1!×4!×7!×10!×...×(3n-2)!)/(n!(n+1)!... (2n-1)!))

Corner growth process

CornerGrowthGraphics[200]//ListAnimate

Directed adjacent transposition random walk

OSPGraphics[20]//ListAnimate

Longest increasing subsequences

mypermutation=RandomPermutation[12]

lis=LongestIncreasingSubsequence[mypermutation]

Length[lis]

Table[Length[LongestIncreasingSubsequence[RandomPermutation[k]]],{k,1,100}]//ListPlot

Course outline

The most important formula in combinatorics

(according to MathOverflow: http://mathoverflow.net/questions/214927/important-formulas-in-combinatorics)

A partition of a positive integer n is a way of expressing n as a sum of positive integers, with the order of summands being unimportant (for this reason, summands are usually written in decreasing order). Example: 11=5+3+1+1+1.

Partitions can be represented graphically as Young diagrams:

YoungDiagram[{5,3,1,1,1}]

Given a partition λ of n, a standard Young tableau (SYT) of shape λ is a filling of the boxes of the Young diagram with the numbers 1,... ,n such that the numbers along each row and column are increasing.

YoungTableau[{{1,2,3,6,11},{4,5,8},{7},{9},{10}}]

A Young tableau can be thought of as a “wall-building sequence”, i.e., a sequence of instructions for growing the Young diagram starting with the empty diagram by successively adding boxes.

AllSublevelTableauxGraphics[{{1,2,3,6,11},{4,5,8},{7},{9},{10}}]//ListAnimate

Equivalently, a Young tableau of shape λ encodes a path from the diagram □ containing a single square to λ in the Young graph of all Young diagrams.

The Young graph

Question: for a given Young diagram λ, how many standard Young tableaux are there? That is, in how many ways can we build a wall of bricks of shape λ by successively laying unit square bricks, starting from the bottom left corner and growing the wall up and to the right?

The answer is given in the following remarkable theorem.

The most important formula in combinatorics (continued)

Theorem (the hook-length formula; Frame-Thrall-Robinson 1954). The number (Subscript[d, λ]) of SYT of shape λ is n! divided by the product of the hook lengths of the boxes of λ, where n is the number of boxes.

The theorem involves the concept of the hook of a box in a Young diagram - the set of boxes that include the box, the part of its row that lies to its right, and the part of its column that lies above it. The hook length is the number of boxes in the hook.

Here is an interactive visualization of hooks and hook lengths.

InteractiveHookVisualization[{10,10,6,6,3,3,2,1}]

And here is an example of using the hook-length formula.

(Subscript[d, λ])==FormattedNumberOfSYT[{5,3,1,1,1}]==NumberOfSYT[{5,3,1,1,1}]//TraditionalForm

Proof of the hook-length formula

The hook-length formula has many proofs. I’ll present my favorite one, a probabilistic proof due to Greene-Nijenhuis-Wilf (1979).

Denote (Subscript[e, λ])=((n!)/((Subscript[Π, (i,j)]) (Subscript[h, λ])(i,j))), the number we are claiming counts SYT of shape λ. Our goal is to prove that (Subscript[d, λ])=(Subscript[e, λ]) for all Young diagrams λ. The proof will be by induction on the number of boxes. Note that (Subscript[d, λ]) satisfies an obvious recurrence

(Subscript[d, λ])=(Subscript[Σ, μ->λ]) (Subscript[d, μ]),

where the sum ranges over all Young diagrams μ from which λ can be obtained by the addition of a single new box. Clearly it will be enough to prove that, similarly,

(Subscript[e, λ])=(Subscript[Σ, μ->λ]) (Subscript[e, μ])

(since for the Young diagram □ with one box, (Subscript[d, □])=(Subscript[e, □])=1, which gives the induction base). Equivalently, we will aim to show that

(Subscript[Σ, μ->λ]) p(μ,λ)=1,

where we denote p(μ,λ)=(Subscript[e, μ])/(Subscript[e, λ]). The idea is to show that p(μ,λ) are probabilities (and so obviously they must sum up to 1...).

Claim. p(μ,λ) is the probability that a hook walk on λ ends in the box λ\μ.

The hook walk is a random walk on the boxes of λ. It consists of: (1) choosing a uniformly random box in λ as the starting point; (2) successively moving from the current box to a new box chosen uniformly at random from the hook of the current box. The walk ends when we reach a corner box (a box with hook length 1, from which there is nowhere else to move to). Here is an illustration:

HookWalkInteractiveVisualization[{10,10,10,8,7,6,6,5,4,2,2,2,1,1}]

Clearly if we prove the Claim, it will follow that the sum over μ of p(μ,λ) is 1, which will complete the proof.

Proof of the hook-length formula (continued)

To prove the Claim, observe that in the ratio

p(μ,λ)=(Subscript[e, μ])/(Subscript[e, λ])=(((n-1)!)/((Subscript[Π, (i,j)]) (Subscript[h, μ])(i,j)))/((n!)/((Subscript[Π, (i,j)]) (Subscript[h, λ])(i,j)))

there is a lot of cancellation, since the hook lengths of μ and λ are mostly the same, except on the reverse hook of the cell c=λ\μ:

InteractiveReverseHookVisualization[{8,4,4,2,2,1}]

After this cancellation we are left with the expression

p(μ,λ)=(1/n)(Subscript[Π, (i,j) ∈ reverse hook of c])[(((Subscript[h, λ])(i,j))/((Subscript[h, λ])(i,j)-1))].

Each of the factors (((Subscript[h, λ])(i,j))/((Subscript[h, λ])(i,j)-1)) in this product can be rewritten as 1+(1/((Subscript[h, λ])(i,j)-1)). Expanding out the product of (1+...) factors, we arrive at an expression of the form

p(μ,λ)=(Subscript[Σ, A]) (Subscript[Σ, B]) Q(A,B)

where the first sum ranges over subsets A⊂{1,...,a-1}, the second sum ranges over subsets B⊂{1,...,b-1} (and c=(a,b) is the box λ\μ), and where we denote

Q(A,B)=(1/n)(Subscript[Π, i∈A])(1/((Subscript[h, λ])(i,b)-1))×(Subscript[Π, j∈B])(1/((Subscript[h, λ])(a,j)-1)).

Proof of the hook-length formula (continued)

Next, I claim that Q(A,B) is itself the probability for the hook walk to go through a particular family of paths that eventually terminate in the cell c, such that when we sum over all possible pairs of sets A,B we get all the possible paths (and therefore the total probability that the hook walk terminates at c).

Specifically, let P(A,B) denote the probability for the hook walk to start at the box with coordinates (min(A⋃{a}),min(B⋃{b})) and to eventually reach c=(a,b) through a sequence of steps ((Subscript[x, 1]),(Subscript[y, 1]))->((Subscript[x, 2]),(Subscript[y, 2]))->...->((Subscript[x, k]),(Subscript[y, k])) such that A⋃{a}={(Subscript[x, 1]),...,(Subscript[x, k])} and B⋃{b}={(Subscript[y, 1]),...,(Subscript[y, k])}. I.e., these are hook walks that have the sets A⋃{a} and B⋃{b} as their horizontal and vertical projections, respectively.

HookWalkProjectionsVisualization[{10,8,8,8,6,3,2,1,1},{2,3,6},{1,3,4,5}]

Our goal is to prove that Q(A,B)=P(A,B), which would finish the proof.

We can do this by checking that both P(A,B) and Q(A,B) satisfy

P(⌀,⌀)=(1/n),     Q(⌀,⌀)=(1/n)

and that both functions satisfy the recurrence

P(A,B) = (1/((Subscript[h, λ])((Subscript[i, 1]),(Subscript[j, 1]))-1))( P(A\{(Subscript[i, 1])},B) + P(A,B\{(Subscript[j, 1])}) )
Q(A,B) = (1/((Subscript[h, λ])((Subscript[i, 1]),(Subscript[j, 1]))-1))( Q(A\{(Subscript[i, 1])},B) + Q(A,B\{(Subscript[j, 1])}) )

where (Subscript[i, 1])=min(A), (Subscript[j, 1])=min(B). For P(A,B) this is obvious from the definition of the hook walk. For Q(A,B) we need to check this from the definition. I leave it as an exercise to show that after some easy manipulation, this claim about Q(A,B) reduces to the claim that

((Subscript[h, λ])((Subscript[i, 1]),b)-1) + ((Subscript[h, λ])(a,(Subscript[j, 1]))-1) = (Subscript[h, λ])((Subscript[i, 1]),(Subscript[j, 1]))-1,

which is indeed true! 

Once we have the recurrence relations for P(A,B) and Q(A,B), it follows by induction on 
|A⋃B| that Q(A,B)=P(A,B), and the proof is complete.

□

Some useful resources

The web page for this course: https://www.math.ucdavis.edu/~romik/aec-2016/ , where you can download this Mathematica presentation and the homework.

D. Romik. The Surprising Mathematics of Longest Increasing Subsequences. Cambridge University Press, 2014. Available to download from https://www.math.ucdavis.edu/~romik/book/

My software page, with cool simulation apps and Mathematica packages. https://www.math.ucdavis.edu/~romik/software/

R. P. Stanley. Enumerative Combinatorics, Vol. 2. Cambridge University Press, 1999.

D. E. Knuth. The Art of Computer Programming, Vol. 3.

P. Flajolet, R. Sedgewick. Analytic Combinatorics. Cambridge University Press, 2009. Available to download from http://algo.inria.fr/flajolet/Publications/AnaCombi/anacombi.html

R. Pemantle, Wilson. Analytic Combinatorics in Several Variables. Cambridge University Press, 2013. Available to download from https://www.math.upenn.edu/~pemantle/ACSV.pdf

M. Petkovsek, H. Wilf, D. Zeilberger. A=B. A K Peters, 1996. Available to download from https://www.math.upenn.edu/~wilf/AeqB.html

SageMath - open source mathematical software. http://www.sagemath.org/

Mathematica - commercial mathematical software by Wolfram Research. http://www.wolfram.com/mathematica/

Which mathematical software should you use?

I don’t know! But you should definitely use some mathematical software...

I’ve used Mathematica for many years. Happy with it, but paying through the nose. Major drawbacks: it’s expensive, has draconian licensing restrictions, and you will only be able to share your code with other Mathematica users. Major advantage: it’s awesome.

SageMath is newer (created in 2005). It is free, open source, highly extensible, and in recent years has become a very powerful tool for many types of research in pure math, particularly algebraic combinatorics. There is a great community of developers working to improve it. I’m working on becoming more proficient with it.

Ask me for a more detailed comparison. Would love to hear other opinions, including about other mathematical software applications (Maple, Matlab, ...) that I have no experience with.

Homework and exercise sessions

We have two exercise sessions, on Tuesday and Thursday.

I prepared a homework problem set that we can discuss, which can be accessed through the course web page I set up at 
https://www.math.ucdavis.edu/~romik/aec-2016/ 
(or go to my home page, click "Teaching" to go to the teaching page and you'll find the link).

I also prepared some experimental math projects you can work on. You can access the Mathematica package for these projects, aec2016-experimental-math.nb (or a PDF printout of it), on the course web page.

At the exercise session we can also discuss open-ended questions, brainstorm ideas for research problems, work on programming in Mathematica or SageMath, etc.

Questions?

Animate[Graphics[{Style[Text["?",{0,0}],FontFamily->"Helvetica Neue",ColorData["Rainbow"][((Cos[π t])^2)],50+130((Sin[π t])^2)]},ImageSize->150,PlotRange->{{-1,1},{-1,1}}],{{t,0,""},0,1},AnimationRate->0.5,Paneled->False]/.(AppearanceElements->_)->(AppearanceElements->{})

Time for lunch!

SmileyFrownyPic[happiness_]:=Graphics[{AbsoluteThickness[6],
Circle[{0,0},1],Disk[{-0.4,0.4},{0.1,0.1}],Disk[{0.4,0.4},{0.1,0.1}],
Circle[{0,-0.5+0.5happiness},{0.5,0.5happiness},{-π/2-1,-π/2+1}]
}];
Animate[SmileyFrownyPic[ happiness],{{happiness,0,""},0,1},Paneled->False,AnimationRepetitions->1,AnimationRate->0.2]/.(AppearanceElements->_)->(AppearanceElements->{})

Longest increasing subsequences

Given a permutation σ, we are interested in increasing subsequences and decreasing subsequences of σ, and in particular in how long of an (increasing, or decreasing, or monotone) subsequence can typically be extracted. Define

LIS(σ) = maximal length of an increasing subsequence of σ
LDS(σ) = maximal length of a decreasing subsequence of σ

Example.

mypermutation=RandomPermutation[10]

LongestIncreasingSubsequence[mypermutation]

LIS[mypermutation]

LongestDecreasingSubsequence[mypermutation]

LDS[mypermutation]

Note: the longest increasing/decreasing subsequence is usually not unique.

The Ulam-Hammersley problem (Ulam 1961; Hammersley 1972). Let (Subscript[L, n]) = E(LIS((Subscript[σ, n]))), the expected length of a longest increasing subsequence of a uniformly random permutation (Subscript[σ, n]) of order n. How does (Subscript[L, n]) behave asymptotically as n->∞?

Table[LIS[RandomPermutation[k]],{k,1,100}]//ListPlot

Longest increasing subsequences (continued)

It is not hard to see that the correct order of magnitude for (Subscript[L, n]) is (Sqrt[n]), in the following sense:

Theorem. We have

(1/2)(Sqrt[n])≤ (Subscript[L, n])≤ 3(Sqrt[n])

for all sufficiently large n≥1.

The lower bound follows easily from

The Erdős-Szekeres theorem (1935). If σ is a permutation of order n>r×s where r,s≥1 are integers, then either LIS(σ)>r or LDS(σ)>s.

Exercise. Find (by yourself or online) at least 3 different proofs of this famous result.

Exercise. Prove that the Erdős-Szekeres theorem implies that for a permutation σ of order n,

LIS(σ)×LDS(σ)≥n.

Exercise. Explain how this implies the lower bound, and show that in fact the bound can be strengthened by removing the constant (1/2).

To prove the upper bound on (Subscript[L, n]) we need to do a bit of asymptotic analysis. Define

(Subscript[X, n,k])= the number of increasing subsequences of (Subscript[σ, n]) (the random permutation) of length k. Clearly we have the bound

Prob[LIS((Subscript[σ, n]))≥k]≤Prob[(Subscript[X, n,k])≥1]≤E((Subscript[X, n,k]))=(1/(k!))(({{n}, {k}}))

(where E((Subscript[X, n,k])) denotes the expected value of (Subscript[X, n,k])). So it is enough to check that this quantity is very small (more precisely, bounded by (e^(-c(Sqrt[n]))) for some positive constant c) if k is larger than, say, 2.8(Sqrt[n]), since that would imply that

(Subscript[L, n])=E(LIS((Subscript[σ, n])))=(Subscript[Σ, k=1]^n)Prob[LIS((Subscript[σ, n]))≥k]≤2.8(Sqrt[n])+(Subscript[Σ, 2.8(Sqrt[n])≤k≤n])Prob[LIS((Subscript[σ, n]))≥k]≤2.8(Sqrt[n])+n (e^(-c(Sqrt[n]))),

which easily implies our claim.

Where does the 2.8(Sqrt[n]) come from? Well, actually a quick computation using Stirling's formula will show that any constant multiple D(Sqrt[n]) will work as long as D>e=2.71828... .

Exercise. Show that for any D>e there exists a constant c>0 such that if k≥D(Sqrt[n]) then

(1/(k!))(({{n}, {k}}))<((n^k)/(((k!))^2))<(e^(-c(Sqrt[n]))).

Hammersley’s theorem

Hammersley (1972) proved (using relatively advanced probabilistic methods that I won’t discuss - see Chapter 1 in my book) the following stronger result about the asymptotic behavior of (Subscript[L, n]):

Theorem. The limit Λ=(lim_(n->∞))((Subscript[L, n])/(Sqrt[n])) exists.

From the arguments sketched above, we see that (1/2)≤Λ≤e. Hammersley also proved the slightly stronger bounds (π/2)≤Λ<2.5. Numerical simulations by Ulam suggested that Λ≈1.97. In fact, it turns out that the correct value is Λ=2. This was proved in 1977 by Vershik and Kerov and independently (except for a small gap in their proof) by Logan and Shepp.

The journey that leads to the result that Λ=2 is even more interesting than the result itself and will require us to introduce several new and powerful ideas.

Computing LIS(σ): patience sorting

In order to understand the behavior of (Subscript[L, n]), a first step is to answer an even more fundamental algorithmic question, namely, what is an efficient way to compute LIS(σ)? (E.g., if there were no efficient algorithm, that would suggest that analyzing the asymptotic behavior of LIS((Subscript[σ, n])) for a random permutation may be hopeless...)

It turns out that there is an elegant algorithm for computing LIS(σ), known as patience sorting. (An elaboration on this idea will lead us directly to the combinatorics of Young tableaux.)

The idea of patience sorting: scan the permutation from left to write, and lay out the numbers 
in “stacks”, according to the following simple rules:

1) Each new number x is placed at the bottom of the leftmost stack whose previous bottom number is greater than x.
2 ) If there is no such stack, x starts a new stack to the right of all the existing ones.

Here is a visualization of this process:

mypermutation=RandomPermutation[16]

PatienceSortingVisualization[mypermutation]

Lemma. The number of stacks at the end of the patience sorting process is precisely LIS(σ).

Proof. Assume σ has an increasing subsequence σ((Subscript[j, 1]))<...<σ((Subscript[j, k])), of length k, where (Subscript[j, 1])<...<(Subscript[j, k]). By the construction, the number σ((Subscript[j, 2])) must go in a stack to the right of the stack containing σ((Subscript[j, 1])), the number σ((Subscript[j, 3])) must go in a stack to the right of the stack containing σ((Subscript[j, 2])), and so on. So the number of stacks at the end is at least k.

Conversely, assume that at the end of the process there are m stacks. We add to the graphic visualization of patience sorting a pointer from each number x to the number that lay at the bottom of the stack to the left of x at the time x was added (go back to the visualization above and check the “Show pointers” box). Now, starting at any number on the rightmost stack and following the sequence of pointers all the way back to the leftmost stack, we get an increasing subsequence of length m. This proves that the number of stacks at the end is at most LIS(σ). Combining these two bounds proves the lemma.

□

The RSK algorithm

Patience sorting becomes even more useful and accessible to a rigorous analysis when we apply it recursively. Note that any numbers that get pushed up to the second row or higher of a stack in patience sorting are irrelevant for the purpose of evaluating LIS(σ), equal to the number of stacks, which only depends on the evolution of the bottom numbers in each stack. We can therefore do anything we want with the numbers in the higher rows.

One option is to simply discard those numbers and ignore them. That is a good idea if one is only interested in an efficient algorithmic implementation of the function LIS(σ). It also has some theoretical value, and leads to an interesting stochastic process called Hammersley’s particle system, which I will not discuss here.

Another option is to apply patience sorting recursively to the numbers that get pushed to the second row - i.e., once a number is sent to the second row it can choose its stack once again according to the usual patience sorting rule, and then a number that gets pushed up to the third row can again choose a new stack, etc.

The resulting procedure is called the RSK algorithm, or the Robinson-Schensted-Knuth algorithm, or the Robinson-Schensted algorithm (all those names are correct, although the last one is historically more accurate, since Knuth’s contribution was to introduce a generalization of the algorithm which we will not discuss).

Let’s see the algorithm in action.

RSKVisualization[mypermutation]

The RSK algorithm has a few more bells and whistles that suggest themselves naturally when one plays with the algorithm a bit: 

First, by successively inputting the entries of a permutation of order n, one naturally gets a standard Young tableau P whose shape is a Young diagram of order n. This is already a good sign - a Young tableau seems like a nicer object that a collection of stacks of numbers. The tableau P is known as the insertion tableau associated with the permutation

Second, an interesting thing to look at are the bumping routes - the paths along which numbers are bumped from one row up to the next one in each insertion step. (The above visualization has an option to view the bumping routes - try it.)

Third, we can keep track of the order in which new boxes were added to the standard Young tableau P. The data structure that records this information is itself a standard Young tableau of the same shape as P! This new tableau is denoted Q, and is called the recording tableau associated with the permutation. It can also be shown in the interactive visualization above.

Fourth, the reason the recording tableau is important is that it enables the algorithm to be reversed - from the two tableaux P and Q one can recover the original permutation through a sequence of deletion steps in which numbers are bumped down and out of the tableau P (instead of into P and up its rows).

We have thus proved the following theorem.

Theorem. The RSK algorithm is a mapping that associates with each permutation σ∈(Subscript[S, n]) a triple (λ,P,Q), where λ is a Young diagram of order n, and P and Q are both standard Young tableau of shape λ. Moreover, RSK is a bijection, and under this mapping we have the relation

(Subscript[λ, 1]) (the length of the first row of λ)=LIS(σ).

By equating cardinalities on both sides of the RSK bijection, we get an interesting identity:

Corollary. For each n≥1 we have

(((Subscript[Σ, λ is a partition of n])((Subscript[d, λ])))^2)=n!.

Back to the Ulam-Hammersley problem

We now have the tools to relate the Ulam-Hammersley problem in a direct way to the combinatorics of Young tableaux.

Corollary.

Prob[LIS((Subscript[σ, n]))=k] = (Underscript[Σ,  λ a partition of n, (Subscript[λ, 1])=k])(((Subscript[d, λ])^2)/(n!))

We can think of the function (Subscript[p, n])(λ):=((Subscript[d, λ])^2)/n! as a probability measure on Young diagrams of order n. It is called the Plancherel measure. (In addition to its connection to longest increasing subsequences, it plays an important role in the representation theory of the symmetric group.)

The Ulam-Hammersley problem has therefore been reduced to the question of understanding the length of the first row in a random Young diagram chosen according to Plancherel measure.

Fortunately, this question can in fact be solved. A key idea: answer a harder question of understanding the entire shape of the Young diagram rather than just the first row. This leads directly to our next topic: limit shapes.

A survey of limit shapes

In this lecture we investigate the phenomenon of limit shapes of random combinatorial objects, in which a random discrete object sampled from a combinatorial family is drawn graphically and its shape converges to a limiting continuous curve in the limit as some size parameter N->∞.

Aside from the discussion and illustrations in this Mathematica notebook, the phenomena I will describe can be experienced using interactive simulation apps I created (Mac only, unfortunately...). They can be downloaded from my software page https://www.math.ucdavis.edu/~romik/software/ .

Some examples we will look at include:

Plancherel measure, solution of the Ulam-Hammersley problem

Random square Young tableaux, uniformly random Erdős-Szekeres permutations

Corner growth process

Uniformly random partitions

Arctic circle theorem

Bumping routes in RSK

Oriented swap process

Random sorting networks

The limit shape of Plancherel-random partitions

After reformulating the Ulam-Hammersley problem as a question on the behavior of Plancherel-random Young diagrams, it makes sense to ask what shape does a typical such diagram of order n take when n is large.

This problem was solved in 1978 by Vershik and Kerov, and independently by Logan and Shepp.

A key idea: take a continuum limit of the hook length formula. For a hypothetical limit shape f:[0,∞)->[0,∞), a monotone (weakly) decreasing function satisfying

(∫_0^∞) f(x)  \[DifferentialD]x=1,

define the hook integral H(f) by

H(f)=(∫_0^∞)(∫_0^(f(x)))log((Subscript[h, f])(x,y))  \[DifferentialD]y  \[DifferentialD]x,

where

(Subscript[h, f])(x,y)=f(x)-y+(f^(-1))(y)-x

is the (continuous analogue of the) hook length of the “box” at (x,y).

It is not hard to show that the limit shape of Plancherel measure is precisely the function f(x) that minimizes the hook integral, since the Young diagrams with this approximate shape therefore have the highest probability w.r.t. Plancherel measure. The question has been transformed into a (still quite difficult) problem in analysis. Vershik-Kerov/Logan-Shepp proved:

Limit shape theorem for Plancherel-random Young diagrams. The limit shape is the curve y=(SubStar[f])(x) given in the rotated coordinate system

u=((x-y)/(Sqrt[2])),        v=((x+y)/(Sqrt[2]))

by the formula

Ω(u)=(2/2)((Sqrt[2-(u^2)])+u (sin^(-1))((u/(Sqrt[2]))))              (|u|≤(Sqrt[2])).

Here are some pictures of the limit shape.

In particular, since (SubStar[f])(0)=2, this proves (up to some technical details, which are not hard to fill in) that LIS((Subscript[σ, n]))≈2(Sqrt[n]), and therefore completes the solution of the Ulam-Hammersley problem!

Random square Young tableaux

The techniques developed by Vershik-Kerov and Logan-Shepp can be used to prove additional interesting results about random Young tableaux and longest increasing subsequences. 

Specifically, consider the behavior of uniformly random square Young tableaux of size n×n as n grows large. Let’s explore this using a simulation app.

Young tableaux can be visualized as 3D discrete surfaces (stacks of cubes)

Limit shape theorem for random square Young tableaux (Pittel-R. 2004). The limit shape of random square Young tableaux is given in rotated coordinates by

(Subscript[Ω, α])(u)=(2/π)u (tan^(-1))((((1-2α)u)/(Sqrt[2α(1-α)-(u^2)])))+((Sqrt[2])/π)(tan^(-1))(((Sqrt[2(2α(1-α)-(u^2))])/(1-2α)))            (|u|≤(Sqrt[2u(1-u)]))

(for α≤1/2, and then by the symmetry property (Subscript[Ω, α])(u)=(Sqrt[2])-(Subscript[Ω, 1-α])(u) for α>1/2).

The limit shape, shown as a family of curves or as a 3D surface

The key idea: use the hook-length formula, and a hook integral similar to the one introduced by Vershik-Kerov/Logan-Shepp. If f:[0,1]->[0,1] is a weakly decreasing function satisfying

(∫_0^1)f(x)dx = α

for some fixed α∈(0,1), then the probability that the kth sublevel-diagram (where k≈α n) of the random square Young tableau is a Young diagram λ is equal to the product of tableau-counting factors

Prob[k-th sublevel shape = λ] = (((Subscript[d, λ])(Subscript[d, \[Square]\λ]))/(Subscript[d, \[Square]])).

If λ is a shape that approximates the curve f(x), this probability will be roughly (up to some nuisance factors) of the form (e^(J(f))), where J(f) is a hook integral

J(f)=(∫_0^1)(∫_0^1)log |(Subscript[h, f])(x,y)|dx dy.

Again, the problem becomes that of finding the function (Subscript[f, α])(x) satisfying the assumptions that minimizes this integral. This can be solved.

Random Erdős-Szekeres permutations

The result on the limit shape of random square Young tableaux has an application to the study of Erdős-Szekeres permutations. These are permutations that are extremal examples for the Erdős-Szekeres theorem, namely, they are permutations of order (n^2) for which the longest monotone subsequence is of length precisely n (the minimum it could possibly be according to the theorem). 

The structure of these permutations is explained by the following combinatorial result.

Theorem (R. 2005). 1) Erdős-Szekeres permutations of order (n^2) are in bijection with pairs (P,Q) of square n×n Young tableaux.

2) The number of Erdős-Szekeres permutations of order (n^2) is

(((((((n^2))!)/(1×(2^2)×(3^3)×...×(n^n)×(((n+1))^(n-1))×(((n+2))^(n-2))×...×(((2n-1))^1)))))^2)

3. ("The tableau sandwich theorem") The bijection has the following explicit description: if P=(Subscript[((Subscript[P, i,j])), 1≤i,j≤n]) and Q=(Subscript[((Subscript[Q, i,j])), 1≤i,j≤n]) then the permutation σ associated to the pair (P,Q) by the bijection is given by

σ((Subscript[P, i,j]))=(Subscript[Q, n+1-i,j])         (1≤i,j≤n)

(that is, graphically, σ is computed from a “sandwich” of P and Q...).

Part 2 of the theorem follows from part 1. Part 1 is a consequence of the RSK algorithm, since if RSK maps a permutation σ to the triple (λ,P,Q), then as we have seen, LIS(σ) is equal to the length of the first row of λ, but it’s also true (though we haven’t proved it) that LDS(σ) is equal to the length of the first column of λ. Thus Erdős-Szekeres permutations correspond precisely to triple (λ,P,Q) where λ has (n^2) boxes and its first row and column are both of length n, and therefore must be a n×n square diagram.

For the proof of part 3 of the theorem, see Chapter 3 in my book. It is a fairly immediate consequence of a not-very-hard combinatorial lemma that says that when the RSK algorithm is applied to an Erdős-Szekeres permutation, all the bumping routes are vertical lines. (A nice exercise: try to prove this yourself.) Here is an example illustrating this:

RSKVisualization[{13,10,20,15,3,22 ,23 ,2,9,25,17,21,14,7,8,1,4,5,16,11,24,19,18,6,12}]

Using the above characterization of Erdős-Szekeres permutations, together with the limit shape theorem for random square Young tableaux, the following result can be proved.

Limit shape theorem for random Erdős-Szekeres permutations. The limit shape of random E-S permutations is given by the quartic curve

((((x^2)-(y^2)))^2)+2((x^2)+(y^2))=3.

A random Erdős-Szekeres permutation and its limit shape

Other interesting limit shapes

The limit shape of uniformly random partitions of n is given by the equation

(e^(-(π/(Sqrt[6]))x))+(e^(-(π/(Sqrt[6]))y))=1

(Szalay-Turan 1977; Vershik 1996)

The idea: let x>0 be a parameter, and take independent random variables

(Subscript[R, k])~(Subscript[Geom, 0])((Subscript[p, k])=1-(x^k)),    k=1,2,3,...

then consider the random partition of (the random integer) N=(Subscript[Σ, k=1]^∞)k (Subscript[R, k]) that has (Subscript[R, 1]) parts equal to 1, (Subscript[R, 2]) parts equal to 2, (Subscript[R, 3]) parts equal to 3, etc.

It can be shown that:

1) Conditioned on the event {N=n}, this is a uniformly random partition of n.
2) For the choice x≈1-(π/(Sqrt[6n])) of the value of the parameter x, this event has “high” probability (where “high” means this probability decays to 0 as a function of n, but only polynomially fast...). 
3) One can then analyze the limit shape of the random partition without the conditioning, and then show that the conditioning does not spoil things.

This is analysis is strongly related to the proof of the Hardy-Ramanujan formula, which we will discuss later.

The limit shape of uniformly random partitions

The corner growth process: growing a random partition by successively adding boxes at uniformly random positions (equivalently: a simple random walk on the Young graph). H. Rost (1981) proved that the limit shape is given by the equation

(Sqrt[x])+(Sqrt[y])=1

The limit shape of the corner growth process

The mathematics of this process, described in Chapters 4-5 in my book, is also extremely interesting. It is related to an important process in probability theory called the totally asymmetric simple exclusion process (usually referred to as TASEP), which can be thought of as a model for traffic jams, queues at service stations, etc.

The limit shapes of bumping routes in RSK were described in a paper I wrote with Piotr Sniady in 2013.

The limit shapes of RSK bumping routes

Other shapes you can expore using my Mac simulation apps:

The limit shape of the oriented swap process

The (conjectural) limit shape of random sorting networks

The arctic circle theorem

Introduction to asymptotic enumeration

In this part of the lectures we will discuss (using cutting-edge blackboard technology):

Stirling’s formula, the saddle point method

The Hardy-Ramanujan formula

Advanced asymptotic enumeration techniques, application to the enumeration of representations of SU(3).