Skip to content

Commit 3533163

Browse files
committed
Use recently-found V0.91 m version
1 parent 6bfaeb3 commit 3533163

File tree

1 file changed

+111
-124
lines changed

1 file changed

+111
-124
lines changed

mathics/packages/DiscreteMath/CombinatoricaV0.9.m

Lines changed: 111 additions & 124 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
12
(* :Title: Combinatorica
23
*)
34
(* :Author:
@@ -14,9 +15,10 @@
1415
350 Bridge Parkway, Redwood City CA 94065. ISBN 0-201-50943-1.
1516
For ordering information, call 1-800-447-2226.
1617
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.
18+
These (and related) programs are available by anonymous ftp.cs.sunysb.edu
19+
in the pub/Combinatorica directory. They can also be obtained on
20+
Macintosh and MS-DOS disks by sending $15.00 to Discrete Mathematics Disk,
21+
Wolfram Research Inc., PO Box 6059, Champaign, IL 61826-9905. (217)-398-0700.
2022
2123
Any comments, bug reports, or requests to get on the Combinatorica
2224
mailing list should be forwarded to:
@@ -32,13 +34,13 @@
3234
*)
3335
(* :Context: DiscreteMath`Combinatorica`
3436
*)
35-
(* :Package Version: .9 (2/29/92 Beta Release)
36-
*)
37+
(* :Package Version: .91 (3/23/95 Beta Release)
38+
*)
3739

3840
(**** Note: some very small changes have been made to make this
39-
to work with Mathics 1.1.1 ****)
41+
to work with Mathics3 ****)
4042

41-
(* :Copyright: Copyright 1990, 1991, 1992 by Steven S. Skiena
43+
(* :Copyright: Copyright 1990--1995 by Steven S. Skiena
4244
4345
This package may be copied in its entirety for nonprofit purposes only.
4446
Sale, other than for the direct cost of the media, is prohibited. This
@@ -54,6 +56,7 @@
5456
incidental, or consequential damages.
5557
*)
5658
(* :History:
59+
Version .9 by Steven S. Skiena, February 1992.
5760
Version .8 by Steven S. Skiena, July 1991.
5861
Version .7 by Steven S. Skiena, January 1991.
5962
Version .6 by Steven S. Skiena, June 1990.
@@ -77,13 +80,10 @@
7780
and Graph Theory with Mathematica",
7881
Addison-Wesley Publishing Co.
7982
*)
80-
(* :Mathematica Version: 0.9.0 for Mathics
81-
This is Mathematica Version 0.9 adapted for Mathics.
83+
(* :Mathematica Version: 2.3
8284
*)
8385

84-
BeginPackage["DiscreteMath`CombinatoricaV0.9`"]
85-
Unprotect[All]
86-
Unprotect[Subsets]
86+
BeginPackage["DiscreteMath`CombinatoricaV0.91`"]
8787

8888
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."
8989

@@ -137,7 +137,7 @@
137137

138138
ChromaticNumber::usage = "ChromaticNumber[g] computes the chromatic number of the graph, the fewest number of colors necessary to color the graph."
139139

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."
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 at most z colors."
141141

142142
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."
143143

@@ -599,6 +599,8 @@
599599

600600
(* Section 1.1.1 Lexicographically Ordered Permutions, Pages 3-4 *)
601601

602+
LexicographicPermutations[{}] := {{}}
603+
602604
LexicographicPermutations[{l_}] := {{l}}
603605

604606
LexicographicPermutations[{a_,b_}] := {{a,b},{b,a}}
@@ -626,42 +628,22 @@
626628
RankPermutation[p_?PermutationQ] := (p[[1]]-1) (Length[Rest[p]]!) +
627629
RankPermutation[ Map[(If[#>p[[1]], #-1, #])&, Rest[p]] ]
628630

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]
631+
NthPermutation[n1_Integer,l_List] :=
632+
Module[{k, n=n1, s=l, i},
633+
Table[
634+
n = Mod[n,(i+1)!];
635+
k = s [[Quotient[n,i!]+1]];
636+
s = Complement[s,{k}];
637+
k,
638+
{i,Length[l]-1,0,-1}
639+
]
640+
]
653641

654642
NextPermutation[p_?PermutationQ] :=
655643
NthPermutation[ RankPermutation[p]+1, Sort[p] ]
656644

657645
(* Section 1.1.3 RandomPermutations, Pages 6-7 *)
658646

659-
(*** FIXME:
660-
ListPlot[ RandomPermutation1[30]]
661-
shows that RandomPermutaion1 isn't good. Therefore we use RandomPermutation2
662-
for RandomPermutation.
663-
****)
664-
665647
RandomPermutation1[n_Integer?Positive] :=
666648
Map[ Last, Sort[ Map[({RandomInteger[],#})&,Range[n]] ] ]
667649

@@ -675,7 +657,7 @@
675657
p
676658
]
677659

678-
RandomPermutation[n_Integer?Positive] := RandomPermutation2[n]
660+
RandomPermutation[n_Integer?Positive] := RandomPermutation1[n]
679661

680662
(* Section 1.1.4 Permutation from Transpostions, Page 11 *)
681663
MinimumChangePermutations[l_List] :=
@@ -723,6 +705,8 @@
723705
Solution[space_List,index_List,count_Integer] :=
724706
Module[{i}, Table[space[[ i,index[[i]] ]], {i,count}] ]
725707

708+
DistinctPermutations[s_List] := Permutations[s] /; (Length[s] == 1)
709+
726710
DistinctPermutations[s_List] :=
727711
Module[{freq,alph=Union[s],n=Length[s]},
728712
freq = Map[ (Count[s,#])&, alph];
@@ -797,7 +781,7 @@
797781
ReflexiveQ[r_?SquareMatrixQ] :=
798782
Module[{i}, Apply[And, Table[(r[[i,i]]!=0),{i,Length[r]}] ] ]
799783

800-
TransitiveQ[r_?SquareMatrixQ] := TransitiveQ[ Graph[v,RandomVertices[Length[r]]] ]
784+
TransitiveQ[r_?SquareMatrixQ] := TransitiveQ[ Graph[r,RandomVertices[Length[r]]] ]
801785
TransitiveQ[r_Graph] := IdenticalQ[r,TransitiveClosure[r]]
802786

803787
SymmetricQ[r_?SquareMatrixQ] := (r === Transpose[r])
@@ -904,7 +888,8 @@
904888

905889
(* 1.3.1 Inversion Vectors, Page 27 *)
906890
FromInversionVector[vec_List] :=
907-
Block[{n=Length[vec]+1,i,p={n}},
891+
Module[{n=Length[vec]+1,i,p},
892+
p={n};
908893
Do [
909894
p = Insert[p, i, vec[[i]]+1],
910895
{i,n-1,1,-1}
@@ -1040,8 +1025,7 @@
10401025
Join[ prev, Map[(Append[#,First[l]])&,Reverse[prev]] ]
10411026
]
10421027

1043-
(* We have a builtin that does this.
1044-
GrayCode doesn't work?
1028+
(* rocky hacked: is already in Mathics3
10451029
Subsets[l_List] := GrayCode[l]
10461030
Subsets[n_Integer] := GrayCode[Range[n]]
10471031
*)
@@ -1095,7 +1079,7 @@
10951079
]
10961080
]
10971081
]]
1098-
]
1082+
] /; (k <= Length[set])
10991083

11001084
PartitionQ[p_List] := (Min[p]>0) && Apply[And, Map[IntegerQ,p]]
11011085

@@ -1133,14 +1117,16 @@
11331117
Show[
11341118
Graphics[
11351119
Join[
1136-
{PointSize[ Min[0.04,1/(2 Max[p])] ]},
1120+
{PointSize[ Min[0.05,1/(2 Max[p])] ]},
11371121
Table[Point[{i,j}], {j,n}, {i,p[[j]]}]
11381122
],
11391123
{AspectRatio -> 1, PlotRange -> All}
11401124
]
11411125
]
11421126
]
11431127

1128+
TransposePartition[{}] := {}
1129+
11441130
TransposePartition[p_List] :=
11451131
Module[{s=Select[p,(#>0)&], i, row, r},
11461132
row = Length[s];
@@ -1176,32 +1162,23 @@
11761162
]
11771163
]
11781164

1165+
(* from Paul Chase *)
1166+
11791167
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-
]
1168+
Module[{mult = Table[0, {n}], j, d, r=n, z},
1169+
While[ (r > 0),
1170+
d = 1; j = 0;
1171+
z = Random[] r PartitionsP[r];
1172+
While [z >= 0,
1173+
j++;
1174+
If [r-j*d < 0, {j=1; d++;}];
1175+
z -= j*PartitionsP[r-j*d];
1176+
];
1177+
r -= j d;
1178+
mult[[j]] += d;
1179+
];
1180+
Reverse[Flatten[Table[Table[j, {mult[[j]]}], {j, Length[mult]}]]]
1181+
]
12051182

12061183
NumberOfCompositions[n_,k_] := Binomial[ n+k-1, n ]
12071184

@@ -2693,25 +2670,67 @@
26932670
Graph[reduction,Vertices[g]]
26942671
]
26952672

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]}
2673+
(*thanks Christoph Strnadl*)
2674+
2675+
HasseDiagram[g_,fak_:1] :=
2676+
Module[{r, rank, m, stages, freq=Table[0,{V[g]}],
2677+
adjm, first},
2678+
r = TransitiveReduction[ RemoveSelfLoops[g] ];
2679+
adjm = ToAdjacencyLists[r];
2680+
rank = Table[ 0,{ V[g]} ];
2681+
first = Select[ Range[ V[g]], InDegree[r,#]==0& ];
2682+
rank = MakeLevel[ first, 1, adjm, rank];
2683+
first = Max[rank];
2684+
stages = Distribution[ rank ];
2685+
Graph[
2686+
Edges[r],
2687+
Table[
2688+
m = ++ freq[[ rank[[i]] ]];
2689+
{ ((m-1) + (1-stages[[rank[[i]] ]])/2) fak^(first-rank[[i]]),
2690+
rank[[i]] },
2691+
{i, V[g]}
27122692
]
27132693
]
2714-
] /; AcyclicQ[RemoveSelfLoops[g],Directed]
2694+
] /; AcyclicQ[ RemoveSelfLoops[g],Directed ]
2695+
2696+
(*
2697+
* SetLevel[{p1,p2,...},lvl,rank] sets the positions p1, p2,.. of
2698+
* list rank to the level lvl, if the old entry at that position
2699+
* is less than level.
2700+
*)
2701+
SetLevel[l_List,lvl_,rank_List] :=
2702+
Module[ {r=rank},
2703+
If[ r[[#]] < lvl, r[[#]] = lvl ] & /@ l;
2704+
r
2705+
]
2706+
2707+
(*
2708+
* MakeLevel[l,level,adjm,rank] constructs recursively the ranks of
2709+
* each vertex according to the adjacency matrix adjm of the graph.
2710+
* rank is the current ranking, level the new level to assign and
2711+
* l = {v1,v2,..} the list of vertices to be set to level.
2712+
*)
2713+
MakeLevel[{},_,_,rank_] := rank
2714+
2715+
MakeLevel[l_List,lvl_,adjm_List,r_List] :=
2716+
Module[ {rank=r, v, lst=l },
2717+
rank = SetLevel[lst,lvl,rank]; (* make this level ready *)
2718+
While[ lst != {},
2719+
v = First[lst];
2720+
rank = MakeLevel[adjm[[v]], lvl+1,adjm,rank];
2721+
lst = Rest[lst];
2722+
];
2723+
rank
2724+
]
2725+
2726+
(*
2727+
* HasseDiagram[g] renders a graph corresponding to the HasseDiagram of
2728+
* the partial order induced by the directed graph g.
2729+
* HasseDiagram[g,fac] renders the HasseDiagram in which each vertex'
2730+
* position is stretched by factor fac. In each stage that factor
2731+
* is taken to the power of the distance to the 1 element.
2732+
*)
2733+
27152734

27162735
TopologicalSort[g_Graph] :=
27172736
Module[{g1 = RemoveSelfLoops[g],e,indeg,zeros,v},
@@ -3180,38 +3199,6 @@
31803199
(aj < Max[b])
31813200
]
31823201

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-
32153202
End[]
32163203

32173204
Protect[

0 commit comments

Comments
 (0)