|
14 | 14 | 350 Bridge Parkway, Redwood City CA 94065. ISBN 0-201-50943-1. |
15 | 15 | For ordering information, call 1-800-447-2226. |
16 | 16 |
|
17 | | -These programs can be obtained on Macintosh and MS-DOS disks by sending |
18 | | -$15.00 to Discrete Mathematics Disk, Wolfram Research Inc., |
19 | | -PO Box 6059, Champaign, IL 61826-9905. (217)-398-0700. |
| 17 | +These (and related) programs are available by anonymous ftp.cs.sunysb.edu |
| 18 | +in the pub/Combinatorica directory. They can also be obtained on |
| 19 | +Macintosh and MS-DOS disks by sending $15.00 to Discrete Mathematics Disk, |
| 20 | +Wolfram Research Inc., PO Box 6059, Champaign, IL 61826-9905. (217)-398-0700. |
20 | 21 |
|
21 | 22 | Any comments, bug reports, or requests to get on the Combinatorica |
22 | 23 | mailing list should be forwarded to: |
|
32 | 33 | *) |
33 | 34 | (* :Context: DiscreteMath`Combinatorica` |
34 | 35 | *) |
35 | | -(* :Package Version: .9 (2/29/92 Beta Release) |
36 | | -*) |
| 36 | +(* :Package Version: .91 (3/23/95 Beta Release) |
| 37 | + *) |
37 | 38 |
|
38 | 39 | (**** Note: some very small changes have been made to make this |
39 | | -to work with Mathics 1.1.1 ****) |
| 40 | +to work with Mathics3 ****) |
40 | 41 |
|
41 | | -(* :Copyright: Copyright 1990, 1991, 1992 by Steven S. Skiena |
| 42 | +(* :Copyright: Copyright 1990--1995 by Steven S. Skiena |
42 | 43 |
|
43 | 44 | This package may be copied in its entirety for nonprofit purposes only. |
44 | 45 | Sale, other than for the direct cost of the media, is prohibited. This |
|
54 | 55 | incidental, or consequential damages. |
55 | 56 | *) |
56 | 57 | (* :History: |
| 58 | + Version .9 by Steven S. Skiena, February 1992. |
57 | 59 | Version .8 by Steven S. Skiena, July 1991. |
58 | 60 | Version .7 by Steven S. Skiena, January 1991. |
59 | 61 | Version .6 by Steven S. Skiena, June 1990. |
|
77 | 79 | and Graph Theory with Mathematica", |
78 | 80 | Addison-Wesley Publishing Co. |
79 | 81 | *) |
80 | | -(* :Mathematica Version: 0.9.0 for Mathics |
81 | | - This is Mathematica Version 0.9 adapted for Mathics. |
| 82 | +(* :Mathematica Version: 2.3 |
82 | 83 | *) |
83 | 84 |
|
84 | | -BeginPackage["DiscreteMath`CombinatoricaV0.9`"] |
85 | | -Unprotect[All] |
86 | | -Unprotect[Subsets] |
| 85 | +BeginPackage["DiscreteMath`CombinatoricaV0.91`"] |
87 | 86 |
|
88 | 87 | Graph::usage = "Graph[g,v] is the header for a graph object where g is an adjacency matrix and v is a list of vertices." |
89 | 88 |
|
|
137 | 136 |
|
138 | 137 | ChromaticNumber::usage = "ChromaticNumber[g] computes the chromatic number of the graph, the fewest number of colors necessary to color the graph." |
139 | 138 |
|
140 | | -ChromaticPolynomial::usage = "ChromaticPolynomial[g,z] returns the chromatic polynomial P(z) of graph g, which counts the number of ways to color g with exactly z colors." |
| 139 | +ChromaticPolynomial::usage = "ChromaticPolynomial[g,z] returns the chromatic polynomial P(z) of graph g, which counts the number of ways to color g with at most z colors." |
141 | 140 |
|
142 | 141 | CirculantGraph::usage = "CirculantGraph[n,l] constructs a circulant graph on n vertices, meaning the ith vertex is adjacent to the (i+j)th and (i-j)th vertex, for each j in list l." |
143 | 142 |
|
|
599 | 598 |
|
600 | 599 | (* Section 1.1.1 Lexicographically Ordered Permutions, Pages 3-4 *) |
601 | 600 |
|
| 601 | +LexicographicPermutations[{}] := {{}} |
| 602 | + |
602 | 603 | LexicographicPermutations[{l_}] := {{l}} |
603 | 604 |
|
604 | 605 | LexicographicPermutations[{a_,b_}] := {{a,b},{b,a}} |
|
626 | 627 | RankPermutation[p_?PermutationQ] := (p[[1]]-1) (Length[Rest[p]]!) + |
627 | 628 | RankPermutation[ Map[(If[#>p[[1]], #-1, #])&, Rest[p]] ] |
628 | 629 |
|
629 | | -(* UP, and UnrankPermutation come from the V2.1 code. |
630 | | - There is some problem in the v0.9 code and rather than try to fix that |
631 | | - we use the newer version |
632 | | - *) |
633 | | -UP[r_Integer, n_Integer] := |
634 | | - Module[{r1 = r, q = n!, i}, |
635 | | - Table[r1 = Mod[r1, q]; |
636 | | - q = q/(n - i + 1); |
637 | | - Quotient[r1, q] + 1, |
638 | | - {i, n} |
639 | | - ] |
640 | | - ] |
641 | | -UnrankPermutation[r_Integer, {}] := {} |
642 | | -UnrankPermutation[r_Integer, l_List] := |
643 | | - Module[{s = l, k, t, p = UP[Mod[r, Length[l]!], Length[l]], i}, |
644 | | - Table[k = s[[t = p[[i]] ]]; |
645 | | - s = Delete[s, t]; |
646 | | - k, |
647 | | - {i, Length[ p ]} |
648 | | - ] |
649 | | - ] |
650 | | -UnrankPermutation[r_Integer, n_Integer?Positive] := |
651 | | - UnrankPermutation[r, Range[n]] |
652 | | -NthPermutation[r_Integer, l_List] := UnrankPermutation[r, l] |
| 630 | +NthPermutation[n1_Integer,l_List] := |
| 631 | + Block[{k, n=n1, s=l, i}, |
| 632 | + Table[ |
| 633 | + n = Mod[n,(i+1)!]; |
| 634 | + k = s [[Quotient[n,i!]+1]]; |
| 635 | + s = Complement[s,{k}]; |
| 636 | + k, |
| 637 | + {i,Length[l]-1,0,-1} |
| 638 | + ] |
| 639 | + ] |
653 | 640 |
|
654 | 641 | NextPermutation[p_?PermutationQ] := |
655 | 642 | NthPermutation[ RankPermutation[p]+1, Sort[p] ] |
|
658 | 645 |
|
659 | 646 | (*** FIXME: |
660 | 647 | ListPlot[ RandomPermutation1[30]] |
661 | | -shows that RandomPermutaion1 isn't good. Therefore we use RandomPermutation2 |
| 648 | +shows that RandomPermutaiton1 isn't good. Therefore we use RandomPermutation2 |
662 | 649 | for RandomPermutation. |
663 | 650 | ****) |
664 | 651 |
|
|
675 | 662 | p |
676 | 663 | ] |
677 | 664 |
|
| 665 | +(* rocky: RandomPermutation1 not random, so use RandomPermutation2 *) |
678 | 666 | RandomPermutation[n_Integer?Positive] := RandomPermutation2[n] |
679 | 667 |
|
680 | 668 | (* Section 1.1.4 Permutation from Transpostions, Page 11 *) |
|
723 | 711 | Solution[space_List,index_List,count_Integer] := |
724 | 712 | Module[{i}, Table[space[[ i,index[[i]] ]], {i,count}] ] |
725 | 713 |
|
| 714 | +DistinctPermutations[s_List] := Permutations[s] /; (Length[s] == 1) |
| 715 | + |
726 | 716 | DistinctPermutations[s_List] := |
727 | 717 | Module[{freq,alph=Union[s],n=Length[s]}, |
728 | 718 | freq = Map[ (Count[s,#])&, alph]; |
|
797 | 787 | ReflexiveQ[r_?SquareMatrixQ] := |
798 | 788 | Module[{i}, Apply[And, Table[(r[[i,i]]!=0),{i,Length[r]}] ] ] |
799 | 789 |
|
800 | | -TransitiveQ[r_?SquareMatrixQ] := TransitiveQ[ Graph[v,RandomVertices[Length[r]]] ] |
| 790 | +TransitiveQ[r_?SquareMatrixQ] := TransitiveQ[ Graph[r,RandomVertices[Length[r]]] ] |
801 | 791 | TransitiveQ[r_Graph] := IdenticalQ[r,TransitiveClosure[r]] |
802 | 792 |
|
803 | 793 | SymmetricQ[r_?SquareMatrixQ] := (r === Transpose[r]) |
|
904 | 894 |
|
905 | 895 | (* 1.3.1 Inversion Vectors, Page 27 *) |
906 | 896 | FromInversionVector[vec_List] := |
907 | | - Block[{n=Length[vec]+1,i,p={n}}, |
| 897 | + Module[{n=Length[vec]+1,i,p}, |
| 898 | + p={n}; |
908 | 899 | Do [ |
909 | 900 | p = Insert[p, i, vec[[i]]+1], |
910 | 901 | {i,n-1,1,-1} |
|
1040 | 1031 | Join[ prev, Map[(Append[#,First[l]])&,Reverse[prev]] ] |
1041 | 1032 | ] |
1042 | 1033 |
|
1043 | | -(* We have a builtin that does this. |
1044 | | -GrayCode doesn't work? |
| 1034 | +(* rocky hacked: is already in Mathics3 |
1045 | 1035 | Subsets[l_List] := GrayCode[l] |
1046 | 1036 | Subsets[n_Integer] := GrayCode[Range[n]] |
1047 | 1037 | *) |
|
1095 | 1085 | ] |
1096 | 1086 | ] |
1097 | 1087 | ]] |
1098 | | - ] |
| 1088 | + ] /; (k <= Length[set]) |
1099 | 1089 |
|
1100 | 1090 | PartitionQ[p_List] := (Min[p]>0) && Apply[And, Map[IntegerQ,p]] |
1101 | 1091 |
|
|
1133 | 1123 | Show[ |
1134 | 1124 | Graphics[ |
1135 | 1125 | Join[ |
1136 | | - {PointSize[ Min[0.04,1/(2 Max[p])] ]}, |
| 1126 | + {PointSize[ Min[0.05,1/(2 Max[p])] ]}, |
1137 | 1127 | Table[Point[{i,j}], {j,n}, {i,p[[j]]}] |
1138 | 1128 | ], |
1139 | 1129 | {AspectRatio -> 1, PlotRange -> All} |
1140 | 1130 | ] |
1141 | 1131 | ] |
1142 | 1132 | ] |
1143 | 1133 |
|
| 1134 | +TransposePartition[{}] := {} |
| 1135 | + |
1144 | 1136 | TransposePartition[p_List] := |
1145 | 1137 | Module[{s=Select[p,(#>0)&], i, row, r}, |
1146 | 1138 | row = Length[s]; |
|
1176 | 1168 | ] |
1177 | 1169 | ] |
1178 | 1170 |
|
| 1171 | +(* from Paul Chase *) |
| 1172 | + |
1179 | 1173 | RandomPartition[n_Integer?Positive] := |
1180 | | - Module[{mult = Table[0,{n}],j,d,m = n}, |
1181 | | - While[ m != 0, |
1182 | | - {j,d} = NextPartitionElement[m]; |
1183 | | - m -= j d; |
1184 | | - mult[[d]] += j; |
1185 | | - ]; |
1186 | | - Flatten[Map[(Table[#,{mult[[#]]}])&,Reverse[Range[n]]]] |
1187 | | - ] |
1188 | | - |
1189 | | -NextPartitionElement[n_Integer] := |
1190 | | - Module[{d=0,j,m,z=RandomInteger[] n PartitionsP[n],done=False,flag}, |
1191 | | - While[!done, |
1192 | | - d++; m = n; j = 0; flag = False; |
1193 | | - While[ !flag, |
1194 | | - j++; m -=d; |
1195 | | - If[ m > 0, |
1196 | | - z -= d PartitionsP[m]; |
1197 | | - If[ z <= 0, flag=done=True], |
1198 | | - flag = True; |
1199 | | - If[m==0, z -=d; If[z <= 0, done = True]] |
1200 | | - ]; |
1201 | | - ]; |
1202 | | - ]; |
1203 | | - {j,d} |
1204 | | - ] |
| 1174 | + Module[{mult = Table[0, {n}], j, d, r=n, z}, |
| 1175 | + While[ (r > 0), |
| 1176 | + d = 1; j = 0; |
| 1177 | + z = Random[] r PartitionsP[r]; |
| 1178 | + While [z >= 0, |
| 1179 | + j++; |
| 1180 | + If [r-j*d < 0, {j=1; d++;}]; |
| 1181 | + z -= j*PartitionsP[r-j*d]; |
| 1182 | + ]; |
| 1183 | + r -= j d; |
| 1184 | + mult[[j]] += d; |
| 1185 | + ]; |
| 1186 | + Reverse[Flatten[Table[Table[j, {mult[[j]]}], {j, Length[mult]}]]] |
| 1187 | + ] |
1205 | 1188 |
|
1206 | 1189 | NumberOfCompositions[n_,k_] := Binomial[ n+k-1, n ] |
1207 | 1190 |
|
|
1250 | 1233 |
|
1251 | 1234 | ShapeOfTableau[t_List] := Map[Length,t] |
1252 | 1235 |
|
| 1236 | +(* Section 2.3.1 Insertion and Deletion, Page 64 *) |
1253 | 1237 | InsertIntoTableau[e_Integer,{}] := { {e} } |
1254 | 1238 |
|
1255 | 1239 | InsertIntoTableau[e_Integer, t1_?TableauQ] := |
1256 | | - Module[{item=e,row=0,col,t=t1}, |
| 1240 | + Block[{item=e,row=0,col,t=t1}, |
1257 | 1241 | While [row < Length[t], |
1258 | 1242 | row++; |
1259 | 1243 | If [Last[t[[row]]] <= item, |
|
2693 | 2677 | Graph[reduction,Vertices[g]] |
2694 | 2678 | ] |
2695 | 2679 |
|
2696 | | -HasseDiagram[g_Graph] := |
2697 | | - Module[{r,rank,m,stages,freq=Table[0,{V[g]}]}, |
2698 | | - r = TransitiveReduction[ RemoveSelfLoops[g] ]; |
2699 | | - rank = RankGraph[ |
2700 | | - MakeUndirected[r], |
2701 | | - Select[Range[V[g]],(InDegree[r,#]==0)&] |
2702 | | - ]; |
2703 | | - m = Max[rank]; |
2704 | | - rank = MapAt[(m)&,rank,Position[OutDegree[r],0]]; |
2705 | | - stages = Distribution[ rank ]; |
2706 | | - Graph[ |
2707 | | - Edges[r], |
2708 | | - Table[ |
2709 | | - m = ++ freq[[ rank[[i]] ]]; |
2710 | | - {(m-1) + (1-stages[[rank[[i]] ]])/2, rank[[i]]}, |
2711 | | - {i,V[g]} |
| 2680 | +(*thanks Christoph Strnadl*) |
| 2681 | + |
| 2682 | +HasseDiagram[g_,fak_:1] := |
| 2683 | + Module[{r, rank, m, stages, freq=Table[0,{V[g]}], |
| 2684 | + adjm, first}, |
| 2685 | + r = TransitiveReduction[ RemoveSelfLoops[g] ]; |
| 2686 | + adjm = ToAdjacencyLists[r]; |
| 2687 | + rank = Table[ 0,{ V[g]} ]; |
| 2688 | + first = Select[ Range[ V[g]], InDegree[r,#]==0& ]; |
| 2689 | + rank = MakeLevel[ first, 1, adjm, rank]; |
| 2690 | + first = Max[rank]; |
| 2691 | + stages = Distribution[ rank ]; |
| 2692 | + Graph[ |
| 2693 | + Edges[r], |
| 2694 | + Table[ |
| 2695 | + m = ++ freq[[ rank[[i]] ]]; |
| 2696 | + { ((m-1) + (1-stages[[rank[[i]] ]])/2) fak^(first-rank[[i]]), |
| 2697 | + rank[[i]] }, |
| 2698 | + {i, V[g]} |
2712 | 2699 | ] |
2713 | 2700 | ] |
2714 | | - ] /; AcyclicQ[RemoveSelfLoops[g],Directed] |
| 2701 | + ] /; AcyclicQ[ RemoveSelfLoops[g],Directed ] |
| 2702 | + |
| 2703 | +(* |
| 2704 | + * SetLevel[{p1,p2,...},lvl,rank] sets the positions p1, p2,.. of |
| 2705 | + * list rank to the level lvl, if the old entry at that position |
| 2706 | + * is less than level. |
| 2707 | + *) |
| 2708 | +SetLevel[l_List,lvl_,rank_List] := |
| 2709 | + Module[ {r=rank}, |
| 2710 | + If[ r[[#]] < lvl, r[[#]] = lvl ] & /@ l; |
| 2711 | + r |
| 2712 | + ] |
| 2713 | + |
| 2714 | +(* |
| 2715 | + * MakeLevel[l,level,adjm,rank] constructs recursively the ranks of |
| 2716 | + * each vertex according to the adjacency matrix adjm of the graph. |
| 2717 | + * rank is the current ranking, level the new level to assign and |
| 2718 | + * l = {v1,v2,..} the list of vertices to be set to level. |
| 2719 | + *) |
| 2720 | +MakeLevel[{},_,_,rank_] := rank |
| 2721 | + |
| 2722 | +MakeLevel[l_List,lvl_,adjm_List,r_List] := |
| 2723 | + Module[ {rank=r, v, lst=l }, |
| 2724 | + rank = SetLevel[lst,lvl,rank]; (* make this level ready *) |
| 2725 | + While[ lst != {}, |
| 2726 | + v = First[lst]; |
| 2727 | + rank = MakeLevel[adjm[[v]], lvl+1,adjm,rank]; |
| 2728 | + lst = Rest[lst]; |
| 2729 | + ]; |
| 2730 | + rank |
| 2731 | + ] |
| 2732 | + |
| 2733 | +(* |
| 2734 | + * HasseDiagram[g] renders a graph corresponding to the HasseDiagram of |
| 2735 | + * the partial order induced by the directed graph g. |
| 2736 | + * HasseDiagram[g,fac] renders the HasseDiagram in which each vertex' |
| 2737 | + * position is stretched by factor fac. In each stage that factor |
| 2738 | + * is taken to the power of the distance to the 1 element. |
| 2739 | + *) |
| 2740 | + |
2715 | 2741 |
|
2716 | 2742 | TopologicalSort[g_Graph] := |
2717 | 2743 | Module[{g1 = RemoveSelfLoops[g],e,indeg,zeros,v}, |
|
3180 | 3206 | (aj < Max[b]) |
3181 | 3207 | ] |
3182 | 3208 |
|
3183 | | -KSetPartitions::usage = "KSetPartitions[set, k] returns the list of set partitions of set with k blocks. KSetPartitions[n, k] returns the list of set partitions of {1, 2, ..., n} with k blocks. If all set partitions of a set are needed, use the function SetPartitions." |
3184 | | -KSetPartitions[{}, 0] := {{}} |
3185 | | -KSetPartitions[s_List, 0] := {} |
3186 | | -KSetPartitions[s_List, k_Integer] := {} /; (k > Length[s]) |
3187 | | -KSetPartitions[s_List, k_Integer] := {Map[{#} &, s]} /; (k === Length[s]) |
3188 | | -KSetPartitions[s_List, k_Integer] := |
3189 | | - Block[{$RecursionLimit = Infinity}, |
3190 | | - Join[Map[Prepend[#, {First[s]}] &, KSetPartitions[Rest[s], k - 1]], |
3191 | | - Flatten[ |
3192 | | - Map[Table[Prepend[Delete[#, j], Prepend[#[[j]], s[[1]]]], |
3193 | | - {j, Length[#]} |
3194 | | - ]&, |
3195 | | - KSetPartitions[Rest[s], k] |
3196 | | - ], 1 |
3197 | | - ] |
3198 | | - ] |
3199 | | - ] /; (k > 0) && (k < Length[s]) |
3200 | | - |
3201 | | -KSetPartitions[0, 0] := {{}} |
3202 | | -KSetPartitions[0, k_Integer?Positive] := {} |
3203 | | -KSetPartitions[n_Integer?Positive, 0] := {} |
3204 | | -KSetPartitions[n_Integer?Positive, k_Integer?Positive] := KSetPartitions[Range[n], k] |
3205 | | - |
3206 | | -SetPartitions::usage = "SetPartitions[set] returns the list of set partitions of set. SetPartitions[n] returns the list of set partitions of {1, 2, ..., n}. If all set partitions with a fixed number of subsets are needed use KSetPartitions." |
3207 | | - |
3208 | | -SetPartitions[{}] := {{}} |
3209 | | -SetPartitions[s_List] := Flatten[Table[KSetPartitions[s, i], {i, Length[s]}], 1] |
3210 | | - |
3211 | | -SetPartitions[0] := {{}} |
3212 | | -SetPartitions[n_Integer?Positive] := SetPartitions[Range[n]] |
3213 | | - |
3214 | | - |
3215 | 3209 | End[] |
3216 | 3210 |
|
3217 | 3211 | Protect[ |
|
0 commit comments