blob: 434f7a4360f5003a934b8001974ee35eaca3ef41 [file] [log] [blame]
Austin Schuh405fa6c2015-09-06 18:13:55 -07001(* Combinatorica5.m package, Modified version of Combinatorica.m
2 Modified by Komei Fukuda November 1998.
3 Please look for the string "Fukuda" for modified places.
4*)
5
6(* :Title: Combinatorica
7*)
8(* :Author:
9 Steven S. Skiena
10*)
11(* :Summary:
12
13 Implementing Discrete Mathematics: Combinatorics and Graph Theory
14 with Mathematica
15
16This package contains all the programs from the book, "Implementing
17Discrete Mathematics: Combinatorics and Graph Theory with Mathematica"
18by Steven S. Skiena, Addison-Wesley Publishing Co., Advanced Book Program,
19350 Bridge Parkway, Redwood City CA 94065. ISBN 0-201-50943-1.
20For ordering information, call 1-800-447-2226.
21
22These programs can be obtained on Macintosh and MS-DOS disks by sending
23$15.00 to Discrete Mathematics Disk, Wolfram Research Inc.,
24PO Box 6059, Champaign, IL 61826-9905. (217)-398-0700.
25
26Any comments, bug reports, or requests to get on the Combinatorica
27mailing list should be forwarded to:
28
29 Steven Skiena
30 Department of Computer Science
31 State University of New York
32 Stony Brook, NY 11794
33
34 skiena@sbcs.sunysb.edu
35
36 (516)-632-9026 / 8470
37*)
38(* :Context: DiscreteMath`Combinatorica`
39*)
40(* :Package Version: .9 (2/29/92 Beta Release)
41*)
42(* :Copyright: Copyright 1990, 1991, 1992 by Steven S. Skiena
43
44This package may be copied in its entirety for nonprofit purposes only.
45Sale, other than for the direct cost of the media, is prohibited. This
46copyright notice must accompany all copies.
47
48The author, Wolfram Research, and Addison-Wesley Publishing Company,
49Inc. make no representations, express or implied, with respond to this
50documentation, of the software it describes and contains, including
51without limitations, any implied warranties of mechantability or fitness
52for a particular purpose, all of which are expressly disclaimed. The
53author, Wolfram Research, or Addison-Wesley, their licensees,
54distributors and dealers shall in no event be liable for any indirect,
55incidental, or consequential damages.
56*)
57(* :History:
58 Version .8 by Steven S. Skiena, July 1991.
59 Version .7 by Steven S. Skiena, January 1991.
60 Version .6 by Steven S. Skiena, June 1990.
61*)
62(* :Keywords:
63 adjacency, automorphism, chromatic, clique, coloring,
64 combination, composition, connected components, connectivity, cycle,
65 de Bruijn, degree, derangement, Dijkstra, Durfee,
66 embedding, equivalence, Eulerian, Ferrers,
67 geodesic, graph, Gray code, group, Hamiltonian cycle, Harary, Hasse,
68 heap, hypercube, interval, inversion, involution, isomorphism,
69 Josephus, network,
70 partition, perfect, permutation, planar graph, Polya, pseudograph,
71 self-loop, sequence, signature, simple, spanning tree,
72 stable marriage, star, Stirling,
73 transitive closure, traveling salesman tour, tree, Turan,
74 vertex cover, wheel, Young tableau
75*)
76(* :Source:
77 Steven Skiena: "Implementing Discrete Mathematics: Combinatorics
78 and Graph Theory with Mathematica",
79 Addison-Wesley Publishing Co.
80*)
81(* :Mathematica Version: 2.0
82*)
83
84BeginPackage["DiscreteMath`Combinatorica`"]
85
86(* Change: unprotect all Combinatorica functions
87 by K. Fukuda 930501 *)
88Unprotect[
89AcyclicQ,
90AddEdge,
91AddVertex,
92AllPairsShortestPath,
93ArticulationVertices,
94Automorphisms,
95Backtrack,
96BiconnectedComponents,
97BiconnectedComponents,
98BiconnectedQ,
99BinarySearch,
100BinarySubsets,
101BipartiteMatching,
102BipartiteQ,
103BreadthFirstTraversal,
104Bridges,
105CartesianProduct,
106CatalanNumber,
107ChangeEdges,
108ChangeVertices,
109ChromaticNumber,
110ChromaticPolynomial,
111CirculantGraph,
112CircularVertices,
113CliqueQ,
114CodeToLabeledTree,
115Cofactor,
116CompleteQ,
117Compositions,
118ConnectedComponents,
119ConnectedQ,
120ConstructTableau,
121Contract,
122CostOfPath,
123Cycle,
124DeBruijnSequence,
125DegreeSequence,
126DeleteCycle,
127DeleteEdge,
128DeleteFromTableau,
129DeleteVertex,
130DepthFirstTraversal,
131DerangementQ,
132Derangements,
133Diameter,
134Dijkstra,
135DilateVertices,
136DistinctPermutations,
137Distribution,
138DurfeeSquare,
139Eccentricity,
140EdgeChromaticNumber,
141EdgeColoring,
142EdgeConnectivity,
143Edges,
144Element,
145EmptyGraph,
146EmptyQ,
147EncroachingListSet,
148EquivalenceClasses,
149EquivalenceRelationQ,
150Equivalences,
151EulerianCycle,
152EulerianQ,
153Eulerian,
154ExactRandomGraph,
155ExpandGraph,
156ExtractCycles,
157FerrersDiagram,
158FindCycle,
159FindSet,
160FirstLexicographicTableau,
161FromAdjacencyLists,
162FromCycles,
163FromInversionVector,
164FromOrderedPairs,
165FromUnorderedPairs,
166FromOrderedTriples,
167FromUnorderedTriples,
168FunctionalGraph,
169Girth,
170GraphCenter,
171GraphComplement,
172GraphDifference,
173GraphIntersection,
174GraphJoin,
175GraphPower,
176GraphProduct,
177GraphSum,
178GraphUnion,
179GraphicQ,
180GrayCode,
181GridGraph,
182HamiltonianCycle,
183HamiltonianQ,
184Harary,
185HasseDiagram,
186HeapSort,
187Heapify,
188HideCycles,
189Hypercube,
190IdenticalQ,
191IncidenceMatrix,
192IndependentSetQ,
193Index,
194InduceSubgraph,
195InitializeUnionFind,
196InsertIntoTableau,
197IntervalGraph,
198InversePermutation,
199Inversions,
200InvolutionQ,
201IsomorphicQ,
202IsomorphismQ,
203Isomorphism,
204Josephus,
205KSubsets,
206K,
207LabeledTreeToCode,
208LastLexicographicTableau,
209LexicographicPermutations,
210LexicographicSubsets,
211LineGraph,
212LongestIncreasingSubsequence,
213M,
214MakeGraph,
215MakeSimple,
216MakeUndirected,
217MaximalMatching,
218MaximumAntichain,
219MaximumClique,
220MaximumIndependentSet,
221MaximumSpanningTree,
222MinimumChainPartition,
223MinimumChangePermutations,
224MinimumSpanningTree,
225MinimumVertexCover,
226MultiplicationTable,
227NetworkFlowEdges,
228NetworkFlow,
229NextComposition,
230NextKSubset,
231NextPartition,
232NextPermutation,
233NextSubset,
234NextTableau,
235NormalizeVertices,
236NthPair,
237NthPermutation,
238NthSubset,
239NumberOfCompositions,
240NumberOfDerangements,
241NumberOfInvolutions,
242NumberOfPartitions,
243NumberOfPermutationsByCycles,
244NumberOfSpanningTrees,
245NumberOfTableaux,
246OrientGraph,
247PartialOrderQ,
248PartitionQ,
249Partitions,
250PathConditionGraph,
251Path,
252PerfectQ,
253PermutationGroupQ,
254PermutationQ,
255Permute,
256PlanarQ,
257PointsAndLines,
258Polya,
259PseudographQ,
260RadialEmbedding,
261Radius,
262RandomComposition,
263RandomGraph,
264RandomHeap,
265RandomKSubset,
266RandomPartition,
267RandomPermutation1,
268RandomPermutation2,
269RandomPermutation,
270RandomSubset,
271RandomTableau,
272RandomTree,
273RandomVertices,
274RankGraph,
275RankPermutation,
276RankSubset,
277RankedEmbedding,
278ReadGraph,
279RealizeDegreeSequence,
280RegularGraph,
281RegularQ,
282RemoveSelfLoops,
283RevealCycles,
284RootedEmbedding,
285RotateVertices,
286Runs,
287SamenessRelation,
288SelectionSort,
289SelfComplementaryQ,
290ShakeGraph,
291ShortestPathSpanningTree,
292ShortestPath,
293ShowGraph,
294ShowLabeledGraph,
295ShowWeightedGraph,
296ShowWeightedLabeledGraph,
297SignaturePermutation,
298SimpleQ,
299Spectrum,
300SpringEmbedding,
301SpringEmbeddingDirected,
302StableMarriage,
303Star,
304StirlingFirst,
305StirlingSecond,
306Strings,
307StronglyConnectedComponents,
308Subsets,
309TableauClasses,
310TableauQ,
311TableauxToPermutation,
312Tableaux,
313ToAdjacencyLists,
314ToCycles,
315ToInversionVector,
316ToOrderedPairs,
317ToUnorderedPairs,
318ToOrderedTriples,
319TopologicalSort,
320TransitiveClosure,
321TransitiveQ,
322TransitiveReduction,
323TranslateVertices,
324TransposePartition,
325TransposeTableau,
326TravelingSalesmanBounds,
327TravelingSalesman,
328TreeQ,
329TriangleInequalityQ,
330Turan,
331TwoColoring,
332UndirectedQ,
333UnionSet,
334UnweightedQ,
335V,
336VertexColoring,
337VertexConnectivity,
338VertexCoverQ,
339Vertices,
340WeaklyConnectedComponents,
341Wheel,
342WriteGraph,
343DilworthGraph ]
344(* end Change *)
345
346Graph::usage = "Graph[g,v] is the header for a graph object where g is an adjacency matrix and v is a list of vertices."
347
348Directed::usage = "Directed is an option to inform certain functions that the graph is directed."
349
350Undirected::usage = "Undirected is an option to inform certain functions that the graph is undirected."
351
352Edge::usage = "Edge is an option to inform certain functions to work with edges instead of vertices."
353
354All::usage = "All is an option to inform certain functions to return all solutions, instead of just the first one."
355
356AcyclicQ::usage = "AcyclicQ[g] returns True if graph g is acyclic. AcyclicQ[g,Directed] returns True if g is a directed acyclic graph."
357
358AddEdge::usage = "AddEdge[g,{x,y}] returns graph g with a new undirected edge {x,y}, while AddEdge[g,{x,y},Directed] returns graph g with a new directed edge {x,y}."
359
360AddVertex::usage = "AddVertex[g] adds a disconnected vertex to graph g."
361
362AllPairsShortestPath::usage = "AllPairsShortestPath[g] returns a matrix, where the (i,j)th entry is the length of the shortest path in g between vertices i and j."
363
364ArticulationVertices::usage = "ArticulationVertices[g] returns a list of all articulation vertices in graph g, vertices whose removal will disconnect the graph."
365
366Automorphisms::usage = "Automorphisms[g] finds the automorphism group of a graph g, the set of isomorphisms of g with itself."
367
368Backtrack::usage = "Backtrack[s,partialQ,solutionQ] performs a backtrack search of the state space s, expanding a partial solution so long as partialQ is True and returning the first complete solution, as identified by solutionQ."
369
370BiconnectedComponents::usage = "BiconnectedComponents[g] returns a list of all the biconnected components of graph g."
371
372BiconnectedComponents::usage = "BiconnectedComponents[g] returns a list of the biconnected components of graph g."
373
374BiconnectedQ::usage = "BiconnectedQ[g] returns True if graph g is biconnected."
375
376BinarySearch::usage = "BinarySearch[l,k,f] searches sorted list l for key k and returns the the position of l containing k, with f a function which extracts the key from an element of l."
377
378BinarySubsets::usage = "BinarySubsets[l] returns all subsets of l ordered according to the binary string defining each subset."
379
380BipartiteMatching::usage = "BipartiteMatching[g] returns the list of edges associated with a maximum matching in bipartite graph g."
381
382BipartiteQ::usage = "BipartiteQ[g] returns True if graph g is bipartite."
383
384BreadthFirstTraversal::usage = "BreadthFirstTraversal[g,v] performs a breadth-first traversal of graph g starting from vertex v, and returns a list of vertices in the order in which they were encountered."
385
386Bridges::usage = "Bridges[g] returns a list of the bridges of graph g, the edges whose removal disconnects the graph."
387
388CartesianProduct::usage = "CartesianProduct[l1,l2] returns the Cartesian product of lists l1 and l2."
389
390CatalanNumber::usage = "CatalanNumber[n] computes the nth Catalan number, for a positive integer n."
391
392ChangeEdges::usage = "ChangeEdges[g,e] constructs a graph with the adjacency matrix e and the embedding of graph g."
393
394ChangeVertices::usage = "ChangeVertices[g,v] constructs a graph with the adjacency matrix of graph g and the list v as its embedding."
395
396ChromaticNumber::usage = "ChromaticNumber[g] computes the chromatic number of the graph, the fewest number of colors necessary to color the graph."
397
398ChromaticPolynomial::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."
399
400CirculantGraph::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."
401
402CircularVertices::usage = "CircularVertices[n] constructs a list of n points equally spaced on a circle."
403
404CliqueQ::usage = "CliqueQ[g,c] returns True if the list of vertices c defines a clique in graph g."
405
406CodeToLabeledTree::usage = "CodeToLabeledTree[l] constructs the unique labeled tree on n vertices from the Prufer code l, which consists of a list of n-2 integers from 1 to n."
407
408Cofactor::usage = "Cofactor[m,{i,j}] calculates the (i,j)th cofactor of matrix m."
409
410CompleteQ::usage = "CompleteQ[g] returns True if graph g is complete."
411
412Compositions::usage = "Compositions[n,k] returns a list of all compositions of integer n into k parts."
413
414ConnectedComponents::usage = "ConnectedComponents[g] returns the vertices of graph g partitioned into connected components."
415
416ConnectedQ::usage = "ConnectedQ[g] returns True if undirected graph g is connected. ConnectedQ[g,Directed] and ConnectedQ[g,Undirected] returns True if g is strongly or weakly connected, respectively."
417
418ConstructTableau::usage = "ConstructTableau[p] performs the bumping algorithm repeatedly on each element of permutation p, resulting in a distinct Young tableau."
419
420Contract::usage = "Contract[g,{x,y}] gives the graph resulting from contracting edge {x,y} of graph g."
421
422CostOfPath::usage = "CostOfPath[g,p] sums up the weights of the edges in graph g defined by the path p."
423
424Cycle::usage = "Cycle[n] constructs the cycle on n vertices, a 2-regular connected graph."
425
426DeBruijnSequence::usage = "DeBruijnSequence[a,n] constructs a de Bruijn sequence on the alphabet described by list a, the shortest sequence such that every string of length n on a occurs as a contiguous subrange of the sequence."
427
428DegreeSequence::usage = "DegreeSequence[g] returns the sorted degree sequence of graph g."
429
430DeleteCycle::usage = "DeleteCycle[g,c] deletes undirected cycle c from graph g. DeleteCycle[g,c,Directed] deletes directed cycle c from graph g."
431
432DeleteEdge::usage = "DeleteEdge[g,{x,y}] returns graph g minus undirected edge {x,y}, while DeleteEdge[g,{x,y},Directed] returns graph g minus directed edge {x,y}."
433
434DeleteFromTableau::usage = "DeleteFromTableau[t,r] deletes the last element of row r from Young tableaux t."
435
436DeleteVertex::usage = "DeleteVertex[g,v] deletes vertex v from graph g."
437
438DepthFirstTraversal::usage = "DepthFirstTraversal[g,v] performs a depth-first traversal of graph g starting from vertex v, and returns a list of vertices in the order in which they were encountered."
439
440DerangementQ::usage = "DerangementQ[p] tests whether permutation p is a derangement, a permutation without a fixed point."
441
442Derangements::usage = "Derangements[p] constructs all derangements of permutation p."
443
444Diameter::usage = "Diameter[g] computes the diameter of graph g, the length of the longest shortest path between two vertices of g."
445
446Dijkstra::usage = "Dijkstra[g,v] returns the shortest path spanning tree and associated distances from vertex v of graph g."
447
448DilateVertices::usage = "DilateVertices[v,d] multiplies each coordinate of each vertex position in list l by d, thus dilating the embedding."
449
450DistinctPermutations::usage = "DistinctPermutations[l] returns all permutations of the multiset described by list l."
451
452Distribution::usage = "Distribution[l,set] lists the frequency of occurrence of each element of set in list l."
453
454DurfeeSquare::usage = "DurfeeSquare[p] computes the number of rows involved in the Durfee square of partition p, the side of the largest sized square contained within the Ferrers diagram of p."
455
456Eccentricity::usage = "Eccentricity[g] computes the eccentricity of each vertex v of graph g, the length of the longest shortest path from v."
457
458EdgeChromaticNumber::usage = "EdgeChromaticNumber[g] computes the fewest number of colors necessary to color each edge of graph g, so that no two edges incident on the same vertex have the same color."
459
460EdgeColoring::usage = "EdgeColoring[g] uses Brelaz's heuristic to find a good, but not necessarily minimal, edge coloring of graph g."
461
462EdgeConnectivity::usage = "EdgeConnectivity[g] computes the minimum number of edges whose deletion from graph g disconnects it."
463
464Edges::usage = "Edges[g] returns the adjacency matrix of graph g."
465
466Element::usage = "Element[a,l] returns the lth element of nested list a, where l is a list of indices"
467
468EmptyGraph::usage = "EmptyGraph[n] generates an empty graph on n vertices."
469
470EmptyQ::usage = "EmptyQ[g] returns True if graph g contains no edges."
471
472EncroachingListSet::usage = "EncroachingListSet[p] constructs the encroaching list set associated with permutation p."
473
474EquivalenceClasses::usage = "EquivalenceClasses[r] identifies the equivalence classes among the elements of matrix r."
475
476EquivalenceRelationQ::usage = "EquivalenceRelationQ[r] returns True if the matrix r defines an equivalence relation. EquivalenceRelationQ[g] tests whether the adjacency matrix of graph g defines an equivalence relation."
477
478Equivalences::usage = "Equivalences[g,h] lists the vertex equivalence classes between graphs g and h defined by the all-pairs shortest path heuristic."
479
480EulerianCycle::usage = "EulerianCycle[g] finds an Eulerian circuit of undirected graph g if one exists. EulerianCycle[g,Directed] finds an Eulerian circuit of directed graph g if one exists."
481
482EulerianQ::usage = "EulerianQ[g] returns True if graph g is Eulerian, meaning there exists a tour which includes each edge exactly once. EulerianQ[g,Directed] returns True if directed graph g is Eulerian."
483
484Eulerian::usage = "Eulerian[n,k] computes the number of permutations of length n with k runs."
485
486ExactRandomGraph::usage = "ExactRandomGraph[n,e] constructs a random labeled graph of exactly e edges and n vertices."
487
488ExpandGraph::usage = "ExpandGraph[g,n] expands graph g to n vertices by adding disconnected vertices."
489
490ExtractCycles::usage = "ExtractCycles[g] returns a list of edge disjoint cycles in graph g."
491
492FerrersDiagram::usage = "FerrersDiagram[p] draws a Ferrers diagram of integer partition p."
493
494FindCycle::usage = "FindCycle[g] finds a list of vertices which define an undirected cycle in graph g. FindCycle[g,Directed] finds a directed cycle in graph g."
495
496FindSet::usage = "FindSet[n,s] returns the root of the set containing n in union-find data structure s."
497
498FirstLexicographicTableau::usage = "FirstLexicographicTableau[p] constructs the first Young tableau with shape described by partition p."
499
500FromAdjacencyLists::usage = "FromAdjacencyLists[l] constructs an adjacency matrix representation for a graph with adjacency lists l, using a circular embedding. FromAdjacencyLists[l,v] uses v as the embedding for the resulting graph."
501
502FromCycles::usage = "FromCycles[c] restores a cycle structure c to the original permutation."
503
504FromInversionVector::usage = "FromInversionVector[v] reconstructs the unique permutation with inversion vector v."
505
506FromOrderedPairs::usage = "FromOrderedPairs[l] constructs an adjacency matrix representation from a list of ordered pairs l, using a circular embedding. FromOrderedPairs[l,v] uses v as the embedding for the resulting graph."
507
508FromUnorderedPairs::usage = "FromUnorderedPairs[l] constructs an adjacency matrix representation from a list of unordered pairs l, using a circular embedding. FromUnorderedPairs[l,v] uses v as the embedding for the resulting graph."
509
510FromOrderedTriples::usage = "FromOrderedTriples[l] constructs an adjacency matrix representation from a list of ordered triples l, using a circular embedding."
511
512FromUnorderedTriples::usage = "FromUnorderedTriples[l] constructs an adjacency matrix representation from a list of ordered triples l, using a circular embedding."
513
514FunctionalGraph::usage = "FunctionalGraph[f,n] constructs the functional digraph on n vertices defined by integer function f."
515
516Girth::usage = "Girth[g] computes the length of the shortest cycle in unweighted graph g."
517
518GraphCenter::usage = "GraphCenter[g] returns a list of the vertices of graph g with minimum eccentricity."
519
520GraphComplement::usage = "GraphComplement[g] returns the complement of graph g."
521
522GraphDifference::usage = "GraphDifference[g,h] constructs the graph resulting from subtracting the adjacency matrix of graph g from that of graph h."
523
524GraphIntersection::usage = "GraphIntersection[g,h] constructs the graph defined by the edges which are in both graph g and graph h."
525
526GraphJoin::usage = "GraphJoin[g,h] constructs the join of graphs g and h."
527
528GraphPower::usage = "GraphPower[g,k] computes the kth power of graph g, meaning there is an edge between any pair of vertices of g with a path between them of length at most k."
529
530GraphProduct::usage = "GraphProduct[g,h] constructs the product of graphs g and h."
531
532GraphSum::usage = "GraphSum[g,h] constructs the graph resulting from adding the adjacency matrices of graphs g and h."
533
534GraphUnion::usage = "GraphUnion[g,h] constructs the union of graphs g and h. GraphUnion[n,g] constructs n copies of graph g, where n is an integer."
535
536GraphicQ::usage = "GraphicQ[s] returns True if the list of integers s is graphic, and thus represents a degree sequence of some graph."
537
538GrayCode::usage = "GrayCode[l] constructs a binary reflected Gray code on set l."
539
540GridGraph::usage = "GridGraph[n,m] constructs an n*m grid graph, the product of paths on n and m vertices."
541
542HamiltonianCycle::usage = "HamiltonianCycle[g] finds a Hamiltonian cycle in graph g if one exists. HamiltonianCycle[g,All] returns all Hamiltonian cycles of graph g."
543
544HamiltonianQ::usage = "HamiltonianQ[g] returns True if there exists a Hamiltonian cycle in graph g, in other words, if there exists a cycle which visits each vertex exactly once."
545
546Harary::usage = "Harary[k,n] constructs the minimal k-connected graph on n vertices."
547
548HasseDiagram::usage = "HasseDiagram[g] constructs a Hasse diagram of the relation defined by directed acyclic graph g."
549
550HeapSort::usage = "HeapSort[l] performs a heap sort on the items of list l."
551
552Heapify::usage = "Heapify[p] builds a heap from permutation p."
553
554HideCycles::usage = "HideCycles[c] canonically encodes the cycle structure c into a unique permutation."
555
556Hypercube::usage = "Hypercube[n] constructs an n-dimensional hypercube."
557
558IdenticalQ::usage = "IdenticalQ[g,h] returns True if graphs g and h have identical adjacency matrices."
559
560IncidenceMatrix::usage = "IncidenceMatrix[g] returns the (0,1) incidence matrix of graph g, which has a row for each vertex and column for each edge and (v,e)=1 if and only if vertex v is incident upon edge e."
561
562IndependentSetQ::usage = "IndependentSetQ[g,i] returns True if the vertices in list i define an independent set in graph g."
563
564Index::usage = "Index[p] returns the index of permutation p, the sum of all subscripts j such that p[j] is greater than p[j+1]."
565
566InduceSubgraph::usage = "InduceSubgraph[g,s] constructs the subgraph of graph g induced by the list of vertices s."
567
568InitializeUnionFind::usage = "InitializeUnionFind[n] initializes a union-find data structure for n elements."
569
570InsertIntoTableau::usage = "InsertIntoTableau[e,t] inserts integer e into Young tableau t using the bumping algorithm."
571
572IntervalGraph::usage = "IntervalGraph[l] constructs the interval graph defined by the list of intervals l."
573
574InversePermutation::usage = "InversePermutation[p] yields the multiplicative inverse of permutation p."
575
576Inversions::usage = "Inversions[p] counts the number of inversions in permutation p."
577
578InvolutionQ::usage = "InvolutionQ[p] returns True if permutation p is its own inverse."
579
580IsomorphicQ::usage = "IsomorphicQ[g,h] returns True if graphs g and h are isomorphic."
581
582IsomorphismQ::usage = "IsomorphismQ[g,h,p] tests if permutation p defines an isomorphism between graphs g and h."
583
584Isomorphism::usage = "Isomorphism[g,h] returns an isomorphism between graphs g and h if one exists."
585
586Josephus::usage = "Josephus[n,m] generates the inverse of the permutation defined by executing every mth member in a circle of n men."
587
588KSubsets::usage = "KSubsets[l,k] returns all subsets of set l containing exactly k elements, ordered lexicographically."
589
590K::usage = "K[n] creates a complete graph on n vertices. K[a,b,c,...,k] creates a complete k-partite graph of the prescribed shape."
591
592LabeledTreeToCode::usage = "LabeledTreeToCode[g] reduces the tree g to its Prufer code."
593
594LastLexicographicTableau::usage = "LastLexicographicTableau[p] constructs the last Young tableau with shape described by partition p."
595
596LexicographicPermutations::usage = "LexicographicPermutations[l] constructs all permutations of list l in lexicographic order."
597
598LexicographicSubsets::usage = "LexicographicSubsets[l] returns all subsets of set l in lexicographic order."
599
600LineGraph::usage = "LineGraph[g] constructs the line graph of graph g."
601
602LongestIncreasingSubsequence::usage = "LongestIncreasingSubsequence[p] find the longest increasing scattered subsequence of permutation p."
603
604M::usage = "M[g] gives the number of edges in undirected graph g."
605
606MakeGraph::usage = "MakeGraph[v,f] constructs the binary relation defined by function f on all pairs of elements of list v."
607
608MakeSimple::usage = "MakeSimple[g] returns an undirected, unweighted graph derived from directed graph g."
609
610MakeUndirected::usage = "MakeUndirected[g] returns a graph with an undirected edge for each directed edge of graph g."
611
612MaximalMatching::usage = "MaximalMatching[g] returns the list of edges associated with a maximal matching of graph g."
613
614MaximumAntichain::usage = "MaximumAntichain[g] returns a largest set of unrelated vertices in partial order g."
615
616MaximumClique::usage = "MaximumClique[g] finds the largest clique in graph g."
617
618MaximumIndependentSet::usage = "MaximumIndependentSet[g] finds the largest independent set of graph g."
619
620MaximumSpanningTree::usage = "MaximumSpanningTree[g] uses Kruskal's algorithm to find a maximum spanning tree of graph g."
621
622MinimumChainPartition::usage = "MinimumChainPartition[g] partitions partial order g into a minimum number of chains."
623
624MinimumChangePermutations::usage = "MinimumChangePermutations[l] constructs all permutations of list l such that adjacent permutations differ by only one transposition."
625
626MinimumSpanningTree::usage = "MinimumSpanningTree[g] uses Kruskal's algorithm to find a minimum spanning tree of graph g."
627
628MinimumVertexCover::usage = "MinimumVertexCover[g] finds the minimum vertex cover of graph g."
629
630MultiplicationTable::usage = "MultiplicationTable[l,f] constructs the complete transition table defined by the binary relation function f on the elements of list l."
631
632NetworkFlowEdges::usage = "NetworkFlowEdges[g,source,sink] returns the adjacency matrix showing the distribution of the maximum flow from source to sink in graph g."
633
634NetworkFlow::usage = "NetworkFlow[g,source,sink] finds the maximum flow through directed graph g from source to sink."
635
636NextComposition::usage = "NextComposition[l] constructs the integer composition which follows l in a canonical order."
637
638NextKSubset::usage = "NextKSubset[l,s] computes the k-subset of list l which appears after k-subsets s in lexicographic order."
639
640NextPartition::usage = "NextPartition[p] returns the integer partition following p in reverse lexicographic order."
641
642NextPermutation::usage = "NextPermutation[p] returns the permutation following p in lexicographic order"
643
644NextSubset::usage = "NextSubset[l,s] constructs the subset of l following subset s in canonical order."
645
646NextTableau::usage = "NextTableau[t] returns the tableau of shape t which follows t in lexicographic order."
647
648NormalizeVertices::usage = "NormalizeVertices[v] returns a list of vertices with the same structure as v but with all coordinates of all points between 0 and 1."
649
650NthPair::usage = "NthPair[n] returns the nth unordered pair of positive integers, when sequenced to minimize the size of the larger integer."
651
652NthPermutation::usage = "NthPermutation[n,l] returns the nth lexicographic permutation of list l."
653
654NthSubset::usage = "NthSubset[n,l] returns the nth subset of list l in canonical order."
655
656NumberOfCompositions::usage = "NumberOfCompositions[n,k] counts the number of distinct compositions of integer n into k parts."
657
658NumberOfDerangements::usage = "NumberOfDerangements[n] counts the derangements on n elements, the permutations without any fixed points."
659
660NumberOfInvolutions::usage = "NumberOfInvolutions[n] counts the number of involutions on n elements."
661
662NumberOfPartitions::usage = "NumberOfPartitions[n] counts the number of distinct integer partitions of n."
663
664NumberOfPermutationsByCycles::usage = "NumberOfPermutationsByCycles[n,m] returns the number of permutations of length n with exactly m cycles."
665
666NumberOfSpanningTrees::usage = "NumberOfSpanningTrees[g] computes the number of distinct labeled spanning trees of graph g."
667
668NumberOfTableaux::usage = "NumberOfTableaux[p] uses the hook length formula to count the number of Young tableaux with shape defined by partition p."
669
670OrientGraph::usage = "OrientGraph[g] assigns a direction to each edge of a bridgeless, undirected graph g, so that the graph is strongly connected."
671
672PartialOrderQ::usage = "PartialOrderQ[g] returns True if the binary relation defined by the adjacency matrix of graph g is a partial order, meaning it is transitive, reflexive, and anti-symmetric."
673
674PartitionQ::usage = "PartitionQ[p] returns True if p is an integer partition."
675
676Partitions::usage = "Partitions[n] constructs all partitions of integer n in reverse lexicographic order."
677
678PathConditionGraph::usage = "PathConditionGraph[g] replaces each non-edge of a graph by an infinite cost, so shortest path algorithms work correctly"
679
680Path::usage = "Path[n] constructs a tree consisting only of a path on n vertices."
681
682PerfectQ::usage = "PerfectQ[g] returns true is g is a perfect graph, meaning that for every induced subgraph of g the size of the largest clique equals the chromatic number."
683
684PermutationGroupQ::usage = "PermutationGroupQ[l] returns True if the list of permutations l forms a permutation group."
685
686PermutationQ::usage = "PermutationQ[p] returns True if p represents a permutation and False otherwise."
687
688Permute::usage = "Permute[l,p] permutes list l according to permutation p."
689
690PlanarQ::usage = "PlanarQ[g] returns True if graph g is planar, meaning it can be drawn in the plane so no two edges cross."
691
692PointsAndLines::usage = "PointsAndLines[g] constructs a partial graphics representation of a graph g."
693
694Polya::usage = "Polya[g,m] returns the polynomial giving the number of colorings, with m colors, of a structure defined by the permutation group g."
695
696PseudographQ::usage = "PseudographQ[g] returns True if graph g is a pseudograph, meaning it contains self-loops."
697
698RadialEmbedding::usage = "RadialEmbedding[g] constructs a radial embedding of graph g, radiating from the center of the graph."
699
700Radius::usage = "Radius[g] computes the radius of graph g, the minimum eccentricity of any vertex of g."
701
702RandomComposition::usage = "RandomComposition[n,k] constructs a random composition of integer n into k parts."
703
704RandomGraph::usage = "RandomGraph[n,p,{l,h}] constructs a random labeled graph on n vertices with an edge probability of p and edge weights of integers drawn uniformly at random from the range (l,h). RandomGraph[n,p,{l,h},Directed] similarly constructs a random directed graph."
705
706RandomHeap::usage = "RandomHeap[n] constructs a random heap on n elements."
707
708RandomKSubset::usage = "RandomKSubset[l,k] returns a random subset of set l with exactly k elements."
709
710RandomPartition::usage = "RandomPartition[n] constructs a random partition of integer n."
711
712RandomPermutation1::usage = "RandomPermutation1[n] sorts random numbers to generate a random permutation."
713
714RandomPermutation2::usage = "RandomPermutation2[n] uses random transpositions to generate random permutations."
715
716RandomPermutation::usage = "RandomPermutation[n] returns a random permutation of length n."
717
718RandomSubset::usage = "RandomSubset[l] creates a random subset of set l."
719
720RandomTableau::usage = "RandomTableau[p] constructs a random Young tableau of shape p."
721
722RandomTree::usage = "RandomTree[n] constructs a random labeled tree on n vertices."
723
724RandomVertices::usage = "RandomVertices[g] assigns a random embedding to graph g."
725
726RankGraph::usage = "RankGraph[g,l] partitions the vertices into classes based on the shortest geodesic distance to a member of list l."
727
728RankPermutation::usage = "RankPermutation[p] computes the rank of permutation p in lexicographic order."
729
730RankSubset::usage = "RankSubset[l,s] computes the rank, in canonical order, of subset s of set l."
731
732RankedEmbedding::usage = "RankedEmbedding[g,l] performs a ranked embedding of graph g, with the vertices ranked in terms of geodesic distance from a member of list l."
733
734ReadGraph::usage = "ReadGraph[f] reads a graph represented as edge lists from file f, and returns the graph as a graph object."
735
736RealizeDegreeSequence::usage = "RealizeDegreeSequence[s] constructs a semirandom graph with degree sequence s."
737
738RegularGraph::usage = "RegularGraph[k,n] constructs a semirandom k-regular graph on n vertices, if such a graph exists."
739
740RegularQ::usage = "RegularQ[g] returns True if g is a regular graph."
741
742RemoveSelfLoops::usage = "RemoveSelfLoops[g] constructs a graph g with the same edges except for any self-loops."
743
744RevealCycles::usage = "RevealCycles[p] unveils the canonical hidden cycle structure of permutation p."
745
746RootedEmbedding::usage = "RootedEmbedding[g,v] constructs a rooted embedding of graph g with vertex v as the root."
747
748RotateVertices::usage = "RotateVertices[v,theta] rotates each vertex position in list v by theta radians around the origin (0,0)."
749
750Runs::usage = "Runs[p] partitions p into contiguous increasing subsequences."
751
752SamenessRelation::usage = "SamenessRelation[l] constructs a binary relation from a list of permutations l which is an equivalence relation if l is a permutation group."
753
754SelectionSort::usage = "SelectionSort[l,f] sorts list l using ordering function f."
755
756SelfComplementaryQ::usage = "SelfComplementaryQ[g] returns True if graph g is self-complementary, meaning it is isomorphic to its complement."
757
758ShakeGraph::usage = "ShakeGraph[g,d] performs a random perturbation of the vertices of graph g, with each vertex moving at most a distance d from its original position."
759
760ShortestPathSpanningTree::usage = "ShortestPathSpanningTree[g,v] constructs the shortest-path spanning tree originating from v, so that the shortest path in graph g from v to any other vertex is the path in the tree."
761
762ShortestPath::usage = "ShortestPath[g,start,end] finds the shortest path between vertices start and end in graph g."
763
764ShowGraph::usage = "ShowGraph[g] displays graph g according to its embedding. ShowGraph[g,Directed] displays directed graph g according to its embedding, with arrows illustrating the orientation of each edge."
765
766ShowLabeledGraph::usage = "ShowLabeledGraph[g] displays graph g according to its embedding, with each vertex labeled with its vertex number. ShowLabeledGraph[g,l] uses the ith element of list l as the label for vertex i. ShowLabeledGraph[g,l,Directed] displays directed graph g according to its embedding, with arrows illustrating the orientation of each edge."
767
768ShowWeightedGraph::usage = "ShowWeightedGraph[g] displays graph g according to its embedding. ShowWeitedGraph[g,Directed] displays directed graph g according to its embedding, with arrows illustrating the orientation of each edge."
769
770ShowWeightedLabeledGraph::usage = "ShowWeightedLabeledGraph[g] displays graph g according to its embedding, with each vertex labeled with its vertex number. ShowWeightedLabeledGraph[g,l] uses the ith element of list l as the label for vertex i. ShowWeightedLabeledGraph[g,l,Directed] displays directed graph g according to its embedding, with arrows illustrating the orientation of each edge."
771
772SignaturePermutation::usage = "SignaturePermutation[p] gives the signature of permutation p."
773
774SimpleQ::usage = "SimpleQ[g] returns True if g is a simple graph, meaning it is unweighted and contains no self-loops."
775
776Spectrum::usage = "Spectrum[g] gives the eigenvalues of graph g."
777
778SpringEmbedding::usage = "SpringEmbedding[g] beautifies the embedding of graph g by modeling the embedding as a system of springs."
779
780SpringEmbeddingDirected::usage = "SpringEmbeddingDirected[g] beautifies the embedding of digraph g by modeling the embedding as a system of springs."
781
782StableMarriage::usage = "StableMarriage[mpref,fpref] finds the male optimal stable marriage defined by lists of permutations describing male and female preferences."
783
784Star::usage = "Star[n] constructs a star on n vertices, which is a tree with one vertex of degree n-1."
785
786StirlingFirst::usage = "StirlingFirst[n,k] computes the Stirling numbers of the first kind."
787
788StirlingSecond::usage = "StirlingSecond[n,k] computes the Stirling numbers of the second kind."
789
790Strings::usage = "Strings[l,n] constructs all possible strings of length n from the elements of list l."
791
792StronglyConnectedComponents::usage = "StronglyConnectedComponents[g] returns the strongly connected components of directed graph g."
793
794Subsets::usage = "Subsets[l] returns all subsets of set l."
795
796TableauClasses::usage = "TableauClasses[p] partitions the elements of permutation p into classes according to their initial columns during Young tableaux construction."
797
798TableauQ::usage = "TableauQ[t] returns True if and only if t represents a Young tableau."
799
800TableauxToPermutation::usage = "TableauxToPermutation[t1,t2] constructs the unique permutation associated with Young tableaux t1 and t2, where both tableaux have the same shape. "
801
802Tableaux::usage = "Tableaux[p] constructs all tableaux whose shape is given by integer partition p."
803
804ToAdjacencyLists::usage = "ToAdjacencyLists[g] constructs an adjacency list representation for graph g."
805
806ToCycles::usage = "ToCycles[p] returns the cycle structure of permutation p."
807
808ToInversionVector::usage = "ToInversionVector[p] computes the inversion vector associated with permutation p."
809
810ToOrderedPairs::usage = "ToOrderedPairs[g] constructs a list of ordered pairs representing the edges of undirected graph g."
811
812ToUnorderedPairs::usage = "ToUnorderedPairs[g] constructs a list of vertex pairs representing graph g, with one pair per undirected edge."
813
814ToOrderedTriples::usage = "ToOrderedTriples[g] constructs a list of ordered triples representing the edges of weighted directed graph g."
815
816TopologicalSort::usage = "TopologicalSort[g] returns a permutation of the vertices of directed acyclic graph g such that an edge (i,j) implies vertex i appears before vertex j."
817
818TransitiveClosure::usage = "TransitiveClosure[g] finds the transitive closure of graph g, the superset of g which contains edge {x,y} iff there is a path from x to y."
819
820TransitiveQ::usage = "TransitiveQ[g] returns True if graph g defines a transitive relation."
821
822TransitiveReduction::usage = "TransitiveReduction[g] finds the smallest graph which has the same transitive closure as g."
823
824TranslateVertices::usage = "TranslateVertices[v,{x,y}] adds the vector {x,y} to each vertex in list v."
825
826TransposePartition::usage = "TransposePartition[p] reflects a partition p of k parts along the main diagonal, creating a partition with maximum part k."
827
828TransposeTableau::usage = "TransposeTableau[t] reflects a Young tableau t along the main diagonal, creating a different tableau."
829
830TravelingSalesmanBounds::usage = "TravelingSalesmanBounds[g] computes upper and lower bounds on the minimum cost traveling salesman tour of graph g."
831
832TravelingSalesman::usage = "TravelingSalesman[g] finds the optimal traveling salesman tour in graph g."
833
834TreeQ::usage = "TreeQ[g] returns True if graph g is a tree."
835
836TriangleInequalityQ::usage = "TriangleInequalityQ[g] returns True if the weight function defined by the adjacency matrix of graph g satisfies the triangle inequality."
837
838Turan::usage = "Turan[n,p] constructs the Turan graph, the extremal graph on n vertices which does not contain K[p]."
839
840TwoColoring::usage = "TwoColoring[g] finds a two-coloring of graph g if g is bipartite."
841
842UndirectedQ::usage = "UndirectedQ[g] returns True if graph g is undirected."
843
844UnionSet::usage = "UnionSet[a,b,s] merges the sets containing a and b in union-find data structure s."
845
846UnweightedQ::usage = "UnweightedQ[g] returns True if all entries in the adjacency matrix of graph g are zero or one."
847
848V::usage = "V[g] gives the order or number of vertices of graph g."
849
850VertexColoring::usage = "VertexColoring[g] uses Brelaz's heuristic to find a good, but not necessarily minimal, vertex coloring of graph g."
851
852VertexConnectivity::usage = "VertexConnectivity[g] computes the minimum number of vertices whose deletion from graph g disconnects it."
853
854VertexCoverQ::usage = "VertexCoverQ[g,c] returns True if the vertices in list c define a vertex cover of graph g."
855
856Vertices::usage = "Vertices[g] returns the embedding of graph g."
857
858WeaklyConnectedComponents::usage = "WeaklyConnectedComponents[g] returns the weakly connected components of directed graph g."
859
860Wheel::usage = "Wheel[n] constructs a wheel on n vertices, which is the join of K[1] and Cycle[n-1]."
861
862WriteGraph::usage = "WriteGraph[g,f] writes graph g to file f using an edge list representation."
863
864Begin["`private`"]
865PermutationQ[p_List] := (Sort[p] == Range[Length[p]])
866
867Permute[l_List,p_?PermutationQ] := l [[ p ]]
868
869LexicographicPermutations[{l_}] := {{l}}
870
871LexicographicPermutations[{a_,b_}] := {{a,b},{b,a}}
872
873LexicographicPermutations[l_List] :=
874 Module[{i,n=Length[l]},
875 Apply[
876 Join,
877 Table[
878 Map[
879 (Prepend[#,l[[i]]])&,
880 LexicographicPermutations[
881 Complement[l,{l[[i]]}]
882 ]
883 ],
884 {i,n}
885 ]
886 ]
887 ]
888
889RankPermutation[{1}] = 0
890
891RankPermutation[p_?PermutationQ] := (p[[1]]-1) (Length[Rest[p]]!) +
892 RankPermutation[ Map[(If[#>p[[1]], #-1, #])&, Rest[p]] ]
893
894NthPermutation[n1_Integer,l_List] :=
895 Module[{k, n=n1, s=l, i},
896 Table[
897 n = Mod[n,(i+1)!];
898 k = s [[Quotient[n,i!]+1]];
899 s = Complement[s,{k}];
900 k,
901 {i,Length[l]-1,0,-1}
902 ]
903 ]
904
905NextPermutation[p_?PermutationQ] :=
906 NthPermutation[ RankPermutation[p]+1, Sort[p] ]
907
908RandomPermutation1[n_Integer?Positive] :=
909 Map[ Last, Sort[ Map[({Random[],#})&,Range[n]] ] ]
910
911RandomPermutation2[n_Integer?Positive] :=
912 Module[{p = Range[n],i,x},
913 Do [
914 x = Random[Integer,{1,i}];
915 {p[[i]],p[[x]]} = {p[[x]],p[[i]]},
916 {i,n,2,-1}
917 ];
918 p
919 ]
920
921RandomPermutation[n_Integer?Positive] := RandomPermutation1[n]
922
923MinimumChangePermutations[l_List] :=
924 Module[{i=1,c,p=l,n=Length[l],k},
925 c = Table[1,{n}];
926 Join[
927 {l},
928 Table[
929 While [ c[[i]] >= i, c[[i]] = 1; i++];
930 If[OddQ[i], k=1, k=c[[i]] ];
931 {p[[i]],p[[k]]} = {p[[k]],p[[i]]};
932 c[[i]]++;
933 i = 2;
934 p,
935 {n!-1}
936 ]
937 ]
938 ]
939
940Backtrack[space_List,partialQ_,solutionQ_,flag_:One] :=
941 Module[{n=Length[space],all={},done,index,v=2,solution},
942 index=Prepend[ Table[0,{n-1}],1];
943 While[v > 0,
944 done = False;
945 While[!done && (index[[v]] < Length[space[[v]]]),
946 index[[v]]++;
947 done = Apply[partialQ,{Solution[space,index,v]}];
948 ];
949 If [done, v++, index[[v--]]=0 ];
950 If [v > n,
951 solution = Solution[space,index,n];
952 If [Apply[solutionQ,{solution}],
953 If [SameQ[flag,All],
954 AppendTo[all,solution],
955 all = solution; v=0
956 ]
957 ];
958 v--
959 ]
960 ];
961 all
962 ]
963
964Solution[space_List,index_List,count_Integer] :=
965 Module[{i}, Table[space[[ i,index[[i]] ]], {i,count}] ]
966
967DistinctPermutations[s_List] :=
968 Module[{freq,alph=Union[s],n=Length[s]},
969 freq = Map[ (Count[s,#])&, alph];
970 Map[
971 (alph[[#]])&,
972 Backtrack[
973 Table[Range[Length[alph]],{n}],
974 (Count[#,Last[#]] <= freq[[Last[#]]])&,
975 (Count[#,Last[#]] <= freq[[Last[#]]])&,
976 All
977 ]
978 ]
979 ]
980
981MinOp[l_List,f_] :=
982 Module[{min=First[l]},
983 Scan[ (If[ Apply[f,{#,min}], min = #])&, l];
984 Return[min];
985 ]
986
987SelectionSort[l_List,f_] :=
988 Module[{where,item,unsorted=l},
989 Table[
990 item = MinOp[unsorted, f];
991 {where} = First[ Position[unsorted,item] ];
992 unsorted = Drop[unsorted,{where,where}];
993 item,
994 {Length[l]}
995 ]
996 ]
997
998BinarySearch[l_List,k_Integer] := BinarySearch[l,k,1,Length[l],Identity]
999BinarySearch[l_List,k_Integer,f_] := BinarySearch[l,k,1,Length[l],f]
1000
1001BinarySearch[l_List,k_Integer,low_Integer,high_Integer,f_] :=
1002 Module[{mid = Floor[ (low + high)/2 ]},
1003 If [low > high, Return[low - 1/2]];
1004 If [f[ l[[mid]] ] == k, Return[mid]];
1005 If [f[ l[[mid]] ] > k,
1006 BinarySearch[l,k,1,mid-1,f],
1007 BinarySearch[l,k,mid+1,high,f]
1008 ]
1009 ]
1010
1011MultiplicationTable[elems_List,op_] :=
1012 Module[{i,j,n=Length[elems],p},
1013 Table[
1014 p = Position[elems, Apply[op,{elems[[i]],elems[[j]]}]];
1015 If [p === {}, 0, p[[1,1]]],
1016 {i,n},{j,n}
1017 ]
1018 ]
1019
1020InversePermutation[p_?PermutationQ] :=
1021 Module[{inverse=p, i},
1022 Do[ inverse[[ p[[i]] ]] = i, {i,Length[p]} ];
1023 inverse
1024 ]
1025
1026EquivalenceRelationQ[r_?SquareMatrixQ] :=
1027 ReflexiveQ[r] && SymmetricQ[r] && TransitiveQ[r]
1028EquivalenceRelationQ[g_Graph] := EquivalenceRelationQ[ Edges[g] ]
1029
1030SquareMatrixQ[{}] = True
1031SquareMatrixQ[r_] := MatrixQ[r] && (Length[r] == Length[r[[1]]])
1032
1033ReflexiveQ[r_?SquareMatrixQ] :=
1034 Module[{i}, Apply[And, Table[(r[[i,i]]!=0),{i,Length[r]}] ] ]
1035
1036TransitiveQ[r_?SquareMatrixQ] := TransitiveQ[ Graph[r,RandomVertices[Length[r]]] ]
1037TransitiveQ[r_Graph] := IdenticalQ[r,TransitiveClosure[r]]
1038
1039SymmetricQ[r_?SquareMatrixQ] := (r === Transpose[r])
1040
1041EquivalenceClasses[r_List?EquivalenceRelationQ] :=
1042 ConnectedComponents[ Graph[r,RandomVertices[Length[r]]] ]
1043EquivalenceClasses[g_Graph?EquivalenceRelationQ] := ConnectedComponents[g]
1044
1045PermutationGroupQ[perms_List] :=
1046 FreeQ[ MultiplicationTable[perms,Permute], 0] &&
1047 EquivalenceRelationQ[SamenessRelation[perms]]
1048
1049SamenessRelation[perms_List] :=
1050 Module[{positions = Transpose[perms], i, j, n=Length[First[perms]]},
1051 Table[
1052 If[ MemberQ[positions[[i]],j], 1, 0],
1053 {i,n}, {j,n}
1054 ]
1055 ] /; perms != {}
1056
1057ToCycles[p1_?PermutationQ] :=
1058 Module[{p=p1,m,n,cycle,i},
1059 Select[
1060 Table[
1061 m = n = p[[i]];
1062 cycle = {};
1063 While[ p[[n]] != 0,
1064 AppendTo[cycle,m=n];
1065 n = p[[n]];
1066 p[[m]] = 0
1067 ];
1068 cycle,
1069 {i,Length[p]}
1070 ],
1071 (# =!= {})&
1072 ]
1073 ]
1074
1075FromCycles[cyc_List] :=
1076 Module[{p=Table[0,{Length[Flatten[cyc]]}], pos},
1077 Scan[
1078 (pos = Last[#];
1079 Scan[ Function[c, pos = p[[pos]] = c], #])&,
1080 cyc
1081 ];
1082 p
1083 ]
1084
1085HideCycles[c_List] :=
1086 Flatten[
1087 Sort[
1088 Map[(RotateLeft[#,Position[#,Min[#]] [[1,1]] - 1])&, c],
1089 (#1[[1]] > #2[[1]])&
1090 ]
1091 ]
1092
1093RevealCycles[p_?PermutationQ] :=
1094 Module[{start=end=1, cycles={}},
1095 While [end <= Length[p],
1096 If [p[[start]] > p[[end]],
1097 AppendTo[ cycles, Take[p,{start,end-1}] ];
1098 start = end,
1099 end++
1100 ]
1101 ];
1102 Append[cycles,Take[p,{start,end-1}]]
1103 ]
1104
1105NumberOfPermutationsByCycles[n_Integer,m_Integer] := (-1)^(n-m) StirlingS1[n,m]
1106
1107StirlingFirst[n_Integer,m_Integer] := StirlingFirst1[n,m]
1108
1109StirlingFirst1[n_Integer,0] := If [n == 0, 1, 0]
1110StirlingFirst1[0,m_Integer] := If [m == 0, 1, 0]
1111
1112StirlingFirst1[n_Integer,m_Integer] := StirlingFirst1[n,m] =
1113 (n-1) StirlingFirst1[n-1,m] + StirlingFirst1[n-1, m-1]
1114
1115StirlingSecond[n_Integer,m_Integer] := StirlingSecond1[n,m]
1116
1117StirlingSecond1[n_Integer,0] := If [n == 0, 1, 0]
1118StirlingSecond1[0,m_Integer] := If [m == 0, 1, 0]
1119
1120StirlingSecond1[n_Integer,m_Integer] := StirlingSecond1[n,m] =
1121 m StirlingSecond1[n-1,m] + StirlingSecond1[n-1,m-1]
1122
1123SignaturePermutation[p_?PermutationQ] := (-1) ^ (Length[p]-Length[ToCycles[p]])
1124
1125Polya[g_List,m_] := Apply[ Plus, Map[(m^Length[ToCycles[#]])&,g] ] / Length[g]
1126
1127ToInversionVector[p_?PermutationQ] :=
1128 Module[{i,inverse=InversePermutation[p]},
1129 Table[
1130 Length[ Select[Take[p,inverse[[i]]], (# > i)&] ],
1131 {i,Length[p]-1}
1132 ]
1133 ]
1134
1135FromInversionVector[vec_List] :=
1136 Module[{n=Length[vec]+1,i,p},
1137 p={n};
1138 Do [
1139 p = Insert[p, i, vec[[i]]+1],
1140 {i,n-1,1,-1}
1141 ];
1142 p
1143 ]
1144
1145Inversions[p_?PermutationQ] := Apply[Plus,ToInversionVector[p]]
1146
1147Index[p_?PermutationQ]:=
1148 Module[{i},
1149 Sum[ If [p[[i]] > p[[i+1]], i, 0], {i,Length[p]-1} ]
1150 ]
1151
1152Runs[p_?PermutationQ] :=
1153 Map[
1154 (Apply[Take,{p,{#[[1]]+1,#[[2]]}}])&,
1155 Partition[
1156 Join[
1157 {0},
1158 Select[Range[Length[p]-1], (p[[#]]>p[[#+1]])&],
1159 {Length[p]}
1160 ],
1161 2,
1162 1
1163 ]
1164 ]
1165
1166Eulerian[n_Integer,k_Integer] := Eulerian1[n,k]
1167
1168Eulerian1[0,k_Integer] := If [k==1, 1, 0]
1169Eulerian1[n_Integer,k_Integer] := Eulerian1[n,k] =
1170 k Eulerian1[n-1,k] + (n-k+1) Eulerian1[n-1,k-1]
1171
1172InvolutionQ[p_?PermutationQ] := p[[p]] == Range[Length[p]]
1173
1174NumberOfInvolutions[n_Integer] :=
1175 Module[{k},
1176 n! Sum[1/((n - 2k)! 2^k k!), {k, 0, Quotient[n, 2]}]
1177 ]
1178
1179DerangementQ[p_?PermutationQ] :=
1180 !(Apply[ Or, Map[( # == p[[#]] )&, Range[Length[p]]] ])
1181
1182NumberOfDerangements[0] = 1;
1183NumberOfDerangements[n_] := n * NumberOfDerangements[n-1] + (-1)^n
1184
1185Derangements[n_Integer] := Derangements[Range[n]]
1186Derangements[p_?PermutationQ] := Select[ Permutations[p], DerangementQ ]
1187
1188Josephus[n_Integer,m_Integer] :=
1189 Module[{live=Range[n],next},
1190 InversePermutation[
1191 Table[
1192 next = RotateLeft[live,m-1];
1193 live = Rest[next];
1194 First[next],
1195 {n}
1196 ]
1197 ]
1198 ]
1199
1200Heapify[p_List] :=
1201 Module[{j,heap=p},
1202 Do [
1203 heap = Heapify[heap,j],
1204 {j,Quotient[Length[p],2],1,-1}
1205 ];
1206 heap
1207 ]
1208
1209Heapify[p_List, k_Integer] :=
1210 Module[{hp=p, i=k, l, n=Length[p]},
1211 While[ (l = 2 i) <= n,
1212 If[ (l < n) && (hp[[l]] > hp[[l+1]]), l++ ];
1213 If[ hp[[i]] > hp[[l]],
1214 {hp[[i]],hp[[l]]}={hp[[l]],hp[[i]]};
1215 i = l,
1216 i = n+1
1217 ];
1218 ];
1219 hp
1220 ]
1221
1222RandomHeap[n_Integer] := Heapify[RandomPermutation[n]]
1223
1224HeapSort[p_List] :=
1225 Module[{heap=Heapify[p],min},
1226 Append[
1227 Table[
1228 min = First[heap];
1229 heap[[1]] = heap[[n]];
1230 heap = Heapify[Drop[heap,-1],1];
1231 min,
1232 {n,Length[p],2,-1}
1233 ],
1234 Max[heap]
1235 ]
1236 ]
1237
1238Strings[l_List,0] := { {} }
1239
1240Strings[l_List,k_Integer?Positive] :=
1241 Module[{oneless = Strings[l,k-1],i,n=Length[l]},
1242 Apply[Join, Table[ Map[(Prepend[#,l[[i]]])&, oneless], {i,n}] ]
1243 ]
1244
1245NthSubset[n_Integer,m_Integer] := NthSubset[n,Range[m]]
1246NthSubset[n_Integer,l_List] :=
1247 l[[ Flatten[ Position[Reverse[IntegerDigits[ Mod[n,2^Length[l]],2]],1] ] ]]
1248
1249BinarySubsets[l_List] :=
1250 Module[{pos=Reverse[Range[Length[l]]], n=Length[l]},
1251 Map[(l[[ Reverse[Select[pos*#, Positive]] ]])&, Strings[{0,1},n] ]
1252 ]
1253
1254NextSubset[set_List,subset_List] := NthSubset[ RankSubset[set,subset], set ]
1255
1256RankSubset[set_List,subset_List] :=
1257 Module[{i,n=Length[set]},
1258 Sum[ 2^(i-1) * If[ MemberQ[subset,set[[i]]], 1, 0], {i,n}]
1259 ]
1260
1261RandomSubset[set_List] := NthSubset[Random[Integer,2^(Length[set])-1],set]
1262
1263GrayCode[l_List] := GrayCode[l,{{}}]
1264
1265GrayCode[{},prev_List] := prev
1266
1267GrayCode[l_List,prev_List] :=
1268 GrayCode[
1269 Rest[l],
1270 Join[ prev, Map[(Append[#,First[l]])&,Reverse[prev]] ]
1271 ]
1272
1273Subsets[l_List] := GrayCode[l]
1274Subsets[n_Integer] := GrayCode[Range[n]]
1275
1276LexicographicSubsets[l_List] := LexicographicSubsets[l,{{}}]
1277
1278LexicographicSubsets[{},s_List] := s
1279
1280LexicographicSubsets[l_List,subsets_List] :=
1281 LexicographicSubsets[
1282 Rest[l],
1283 Join[
1284 subsets,
1285 Map[(Prepend[#,First[l]])&,LexicographicSubsets[Rest[l],{{}}] ]
1286 ]
1287 ]
1288
1289KSubsets[l_List,0] := { {} }
1290KSubsets[l_List,1] := Partition[l,1]
1291KSubsets[l_List,k_Integer?Positive] := {l} /; (k == Length[l])
1292KSubsets[l_List,k_Integer?Positive] := {} /; (k > Length[l])
1293
1294KSubsets[l_List,k_Integer?Positive] :=
1295 Join[
1296 Map[(Prepend[#,First[l]])&, KSubsets[Rest[l],k-1]],
1297 KSubsets[Rest[l],k]
1298 ]
1299
1300NextKSubset[set_List,subset_List] :=
1301 Take[set,Length[subset]] /; (Take[set,-Length[subset]] === subset)
1302
1303NextKSubset[set_List,subset_List] :=
1304 Module[{h=1, x=1},
1305 While [set[[-h]] == subset[[-h]], h++];
1306 While [set[[x]] =!= subset[[-h]], x++];
1307 Join[ Drop[subset,-h], Take[set, {x+1,x+h}] ]
1308 ]
1309
1310RandomKSubset[n_Integer,k_Integer] := RandomKSubset[Range[n],k]
1311
1312RandomKSubset[set_List,k_Integer] :=
1313 Module[{s=Range[Length[set]],i,n=Length[set],x},
1314 set [[
1315 Sort[
1316 Table[
1317 x=Random[Integer,{1,i}];
1318 {s[[i]],s[[x]]} = {s[[x]],s[[i]]};
1319 s[[i]],
1320 {i,n,n-k+1,-1}
1321 ]
1322 ]
1323 ]]
1324 ]
1325
1326PartitionQ[p_List] := (Min[p]>0) && Apply[And, Map[IntegerQ,p]]
1327
1328Partitions[n_Integer] := Partitions[n,n]
1329
1330Partitions[n_Integer,_] := {} /; (n<0)
1331Partitions[0,_] := { {} }
1332Partitions[n_Integer,1] := { Table[1,{n}] }
1333Partitions[_,0] := {}
1334
1335Partitions[n_Integer,maxpart_Integer] :=
1336 Join[
1337 Map[(Prepend[#,maxpart])&, Partitions[n-maxpart,maxpart]],
1338 Partitions[n,maxpart-1]
1339 ]
1340
1341NextPartition[p_List] := Join[Drop[p,-1],{Last[p]-1,1}] /; (Last[p] > 1)
1342
1343NextPartition[p_List] := {Apply[Plus,p]} /; (Max[p] == 1)
1344
1345NextPartition[p_List] :=
1346 Module[{index,k,m},
1347 {index} = First[ Position[p,1] ];
1348 k = p[[index-1]] - 1;
1349 m = Apply[Plus,Drop[p,index-1]] + k + 1;
1350 Join[
1351 Take[p,index-2],
1352 Table[k,{Quotient[m,k]}],
1353 If [Mod[m,k] == 0, {}, {Mod[m,k]}]
1354 ]
1355 ]
1356
1357FerrersDiagram[p1_List] :=
1358 Module[{i,j,n=Length[p1],p=Sort[p1]},
1359 Show[
1360 Graphics[
1361 Join[
1362 {PointSize[ Min[0.05,1/(2 Max[p])] ]},
1363 Table[Point[{i,j}], {j,n}, {i,p[[j]]}]
1364 ],
1365 {AspectRatio -> 1, PlotRange -> All}
1366 ]
1367 ]
1368 ]
1369
1370TransposePartition[p_List] :=
1371 Module[{s=Select[p,(#>0)&], i, row, r},
1372 row = Length[s];
1373 Table [
1374 r = row;
1375 While [s[[row]]<=i, row--];
1376 r,
1377 {i,First[s]}
1378 ]
1379 ]
1380
1381DurfeeSquare[s_List] :=
1382 Module[{i,max=1},
1383 Do [
1384 If [s[[i]] >= i, max=i],
1385 {i,2,Min[Length[s],First[s]]}
1386 ];
1387 max
1388 ]
1389
1390DurfeeSquare[{}] := 0
1391
1392NumberOfPartitions[n_Integer] := NumberOfPartitions1[n]
1393
1394NumberOfPartitions1[n_Integer] := 0 /; (n < 0)
1395NumberOfPartitions1[n_Integer] := 1 /; (n == 0)
1396
1397NumberOfPartitions1[n_Integer] := NumberOfPartitions1[n] =
1398 Module[{m},
1399 Sum[ (-1)^(m+1) NumberOfPartitions1[n - m (3m-1)/2] +
1400 (-1)^(m+1) NumberOfPartitions1[n - m (3m+1)/2],
1401 {m, Ceiling[ (1+Sqrt[1.0 + 24n])/6 ], 1, -1}
1402 ]
1403 ]
1404
1405RandomPartition[n_Integer?Positive] :=
1406 Module[{mult = Table[0,{n}],j,d,m = n},
1407 While[ m != 0,
1408 {j,d} = NextPartitionElement[m];
1409 m -= j d;
1410 mult[[d]] += j;
1411 ];
1412 Flatten[Map[(Table[#,{mult[[#]]}])&,Reverse[Range[n]]]]
1413 ]
1414
1415NextPartitionElement[n_Integer] :=
1416 Module[{d=0,j,m,z=Random[] n PartitionsP[n],done=False,flag},
1417 While[!done,
1418 d++; m = n; j = 0; flag = False;
1419 While[ !flag,
1420 j++; m -=d;
1421 If[ m > 0,
1422 z -= d PartitionsP[m];
1423 If[ z <= 0, flag=done=True],
1424 flag = True;
1425 If[m==0, z -=d; If[z <= 0, done = True]]
1426 ];
1427 ];
1428 ];
1429 {j,d}
1430 ]
1431
1432NumberOfCompositions[n_,k_] := Binomial[ n+k-1, n ]
1433
1434RandomComposition[n_Integer,k_Integer] :=
1435 Map[
1436 (#[[2]] - #[[1]] - 1)&,
1437 Partition[Join[{0},RandomKSubset[Range[n+k-1],k-1],{n+k}], 2, 1]
1438 ]
1439
1440Compositions[n_Integer,k_Integer] :=
1441 Map[
1442 (Map[(#[[2]]-#[[1]]-1)&, Partition[Join[{0},#,{n+k}],2,1] ])&,
1443 KSubsets[Range[n+k-1],k-1]
1444 ]
1445
1446NextComposition[l_List] :=
1447 Module[{c=l, h=1, t},
1448 While[c[[h]] == 0, h++];
1449 {t,c[[h]]} = {c[[h]],0};
1450 c[[1]] = t - 1;
1451 c[[h+1]]++;
1452 c
1453 ]
1454
1455NextComposition[l_List] :=
1456 Join[{Apply[Plus,l]},Table[0,{Length[l]-1}]] /; Last[l]==Apply[Plus,l]
1457
1458TableauQ[{}] = True
1459TableauQ[t_List] :=
1460 And [
1461 Apply[ And, Map[(Apply[LessEqual,#])&,t] ],
1462 Apply[ And, Map[(Apply[LessEqual,#])&,TransposeTableau[t]] ],
1463 Apply[ GreaterEqual, Map[Length,t] ],
1464 Apply[ GreaterEqual, Map[Length,TransposeTableau[t]] ]
1465 ]
1466
1467TransposeTableau[tb_List] :=
1468 Module[{t=Select[tb,(Length[#]>=1)&],row},
1469 Table[
1470 row = Map[First,t];
1471 t = Map[ Rest, Select[t,(Length[#]>1)&] ];
1472 row,
1473 {Length[First[tb]]}
1474 ]
1475 ]
1476
1477ShapeOfTableau[t_List] := Map[Length,t]
1478
1479InsertIntoTableau[e_Integer,{}] := { {e} }
1480
1481InsertIntoTableau[e_Integer, t1_?TableauQ] :=
1482 Module[{item=e,row=0,col,t=t1},
1483 While [row < Length[t],
1484 row++;
1485 If [Last[t[[row]]] <= item,
1486 AppendTo[t[[row]],item];
1487 Return[t]
1488 ];
1489 col = Ceiling[ BinarySearch[t[[row]],item] ];
1490 {item, t[[row,col]]} = {t[[row,col]], item};
1491 ];
1492 Append[t, {item}]
1493 ]
1494
1495ConstructTableau[p_List] := ConstructTableau[p,{}]
1496
1497ConstructTableau[{},t_List] := t
1498
1499ConstructTableau[p_List,t_List] :=
1500 ConstructTableau[Rest[p], InsertIntoTableau[First[p],t]]
1501
1502DeleteFromTableau[t1_?TableauQ,r_Integer]:=
1503 Module [{t=t1, col, row, item=Last[t1[[r]]]},
1504 col = Length[t[[r]]];
1505 If[col == 1, t = Drop[t,-1], t[[r]] = Drop[t[[r]],-1]];
1506 Do [
1507 While [t[[row,col]]<=item && Length[t[[row]]]>col, col++];
1508 If [item < t[[row,col]], col--];
1509 {item,t[[row,col]]} = {t[[row,col]],item},
1510 {row,r-1,1,-1}
1511 ];
1512 t
1513 ]
1514
1515TableauxToPermutation[p1_?TableauQ,q1_?TableauQ] :=
1516 Module[{p=p1, q=q1, row, firstrow},
1517 Reverse[
1518 Table[
1519 firstrow = First[p];
1520 row = Position[q, Max[q]] [[1,1]];
1521 p = DeleteFromTableau[p,row];
1522 q[[row]] = Drop[ q[[row]], -1];
1523 If[ p == {},
1524 First[firstrow],
1525 First[Complement[firstrow,First[p]]]
1526 ],
1527 {Apply[Plus,ShapeOfTableau[p1]]}
1528 ]
1529 ]
1530 ] /; ShapeOfTableau[p1] === ShapeOfTableau[q1]
1531
1532LastLexicographicTableau[s_List] :=
1533 Module[{c=0},
1534 Map[(c+=#; Range[c-#+1,c])&, s]
1535 ]
1536
1537FirstLexicographicTableau[s_List] :=
1538 TransposeTableau[ LastLexicographicTableau[ TransposePartition[s] ] ]
1539
1540NextTableau[t_?TableauQ] :=
1541 Module[{s,y,row,j,count=0,tj,i,n=Max[t]},
1542 y = TableauToYVector[t];
1543 For [j=2, (j<n) && (y[[j]]>=y[[j-1]]), j++];
1544 If [y[[j]] >= y[[j-1]],
1545 Return[ FirstLexicographicTableau[ ShapeOfTableau[t] ] ]
1546 ];
1547 s = ShapeOfTableau[ Table[Select[t[[i]],(#<=j)&], {i,Length[t]}] ];
1548 {row} = Last[ Position[ s, s[[ Position[t,j] [[1,1]] + 1 ]] ] ];
1549 s[[row]] --;
1550 tj = FirstLexicographicTableau[s];
1551 If[ Length[tj] < row,
1552 tj = Append[tj,{j}],
1553 tj[[row]] = Append[tj[[row]],j]
1554 ];
1555 Join[
1556 Table[
1557 Join[tj[[i]],Select[t[[i]],(#>j)&]],
1558 {i,Length[tj]}
1559 ],
1560 Table[t[[i]],{i,Length[tj]+1,Length[t]}]
1561 ]
1562 ]
1563
1564Tableaux[s_List] :=
1565 Module[{t = LastLexicographicTableau[s]},
1566 Table[ t = NextTableau[t], {NumberOfTableaux[s]} ]
1567 ]
1568
1569Tableaux[n_Integer?Positive] := Apply[ Join, Map[ Tableaux, Partitions[n] ] ]
1570
1571YVectorToTableau[y_List] :=
1572 Module[{k},
1573 Table[ Flatten[Position[y,k]], {k,Length[Union[y]]}]
1574 ]
1575
1576TableauToYVector[t_?TableauQ] :=
1577 Module[{i,y=Table[1,{Length[Flatten[t]]}]},
1578 Do [ Scan[ (y[[#]]=i)&, t[[i]] ], {i,2,Length[t]} ];
1579 y
1580 ]
1581
1582NumberOfTableaux[{}] := 1
1583NumberOfTableaux[s_List] :=
1584 Module[{row,col,transpose=TransposePartition[s]},
1585 (Apply[Plus,s])! /
1586 Product [
1587 (transpose[[col]]-row+s[[row]]-col+1),
1588 {row,Length[s]}, {col,s[[row]]}
1589 ]
1590 ]
1591
1592NumberOfTableaux[n_Integer] := Apply[Plus, Map[NumberOfTableaux, Partitions[n]]]
1593
1594CatalanNumber[n_] := Binomial[2n,n]/(n+1) /; (n>=0)
1595
1596RandomTableau[shape_List] :=
1597 Module[{i=j=n=Apply[Plus,shape],done,l,m,h=1,k,y,p=shape},
1598 y= Join[TransposePartition[shape],Table[0,{n - Max[shape]}]];
1599 Do[
1600 {i,j} = RandomSquare[y,p]; done = False;
1601 While [!done,
1602 h = y[[j]] + p[[i]] - i - j;
1603 If[ h != 0,
1604 If[ Random[] < 0.5,
1605 j = Random[Integer,{j,p[[i]]}],
1606 i = Random[Integer,{i,y[[j]]}]
1607 ],
1608 done = True
1609 ];
1610 ];
1611 p[[i]]--; y[[j]]--;
1612 y[[m]] = i,
1613 {m,n,1,-1}
1614 ];
1615 YVectorToTableau[y]
1616 ]
1617
1618RandomSquare[y_List,p_List] :=
1619 Module[{i=Random[Integer,{1,First[y]}], j=Random[Integer,{1,First[p]}]},
1620 While[(i > y[[j]]) || (j > p[[i]]),
1621 i = Random[Integer,{1,First[y]}];
1622 j = Random[Integer,{1,First[p]}]
1623 ];
1624 {i,j}
1625 ]
1626
1627TableauClasses[p_?PermutationQ] :=
1628 Module[{classes=Table[{},{Length[p]}],t={}},
1629 Scan [
1630 (t = InsertIntoTableau[#,t];
1631 PrependTo[classes[[Position[First[t],#] [[1,1]] ]], #])&,
1632 p
1633 ];
1634 Select[classes, (# != {})&]
1635 ]
1636
1637LongestIncreasingSubsequence[p_?PermutationQ] :=
1638 Module[{c,x,xlast},
1639 c = TableauClasses[p];
1640 xlast = x = First[ Last[c] ];
1641 Append[
1642 Reverse[
1643 Map[
1644 (x = First[ Intersection[#,
1645 Take[p, Position[p,x][[1,1]] ] ] ])&,
1646 Reverse[ Drop[c,-1] ]
1647 ]
1648 ],
1649 xlast
1650 ]
1651 ]
1652
1653LongestIncreasingSubsequence[{}] := {}
1654
1655AddToEncroachingLists[k_Integer,{}] := {{k}}
1656
1657AddToEncroachingLists[k_Integer,l_List] :=
1658 Append[l,{k}] /; (k > First[Last[l]]) && (k < Last[Last[l]])
1659
1660AddToEncroachingLists[k_Integer,l1_List] :=
1661 Module[{i,l=l1},
1662 If [k <= First[Last[l]],
1663 i = Ceiling[ BinarySearch[l,k,First] ];
1664 PrependTo[l[[i]],k],
1665 i = Ceiling[ BinarySearch[l,-k,(-Last[#])&] ];
1666 AppendTo[l[[i]],k]
1667 ];
1668 l
1669 ]
1670
1671EncroachingListSet[l_List] := EncroachingListSet[l,{}]
1672EncroachingListSet[{},e_List] := e
1673
1674EncroachingListSet[l_List,e_List] :=
1675 EncroachingListSet[Rest[l], AddToEncroachingLists[First[l],e] ]
1676
1677Edges[Graph[e_,_]] := e
1678
1679Vertices[Graph[_,v_]] := v
1680
1681V[Graph[e_,_]] := Length[e]
1682
1683M[Graph[g_,_],___] := Apply[Plus, Map[(Apply[Plus,#])&,g] ] / 2
1684M[Graph[g_,_],Directed] := Apply[Plus, Map[(Apply[Plus,#])&,g] ]
1685
1686ChangeVertices[g_Graph,v_List] := Graph[ Edges[g], v ]
1687
1688ChangeEdges[g_Graph,e_List] := Graph[ e, Vertices[g] ]
1689
1690AddEdge[Graph[g_,v_],{x_,y_},Directed] :=
1691 Module[ {gnew=g},
1692 gnew[[x,y]] ++;
1693 Graph[gnew,v]
1694 ]
1695
1696AddEdge[g_Graph,{x_,y_},flag_:Undirected] :=
1697 AddEdge[ AddEdge[g, {x,y}, Directed], {y,x}, Directed]
1698
1699DeleteEdge[Graph[g_,v_],{x_,y_},Directed] :=
1700 Module[ {gnew=g},
1701 If [ g[[x,y]] > 1, gnew[[x,y]]--, gnew[[x,y]] = 0];
1702 Graph[gnew,v]
1703 ]
1704
1705DeleteEdge[g_Graph,{x_,y_},flag_:Undirected] :=
1706 DeleteEdge[ DeleteEdge[g, {x,y}, Directed], {y,x}, Directed]
1707
1708AddVertex[g_Graph] := GraphUnion[g, K[1]]
1709
1710DeleteVertex[g_Graph,v_Integer] := InduceSubgraph[g,Complement[Range[V[g]],{v}]]
1711
1712Spectrum[Graph[g_,_]] := Eigenvalues[g]
1713
1714ToAdjacencyLists[Graph[g_,_]] :=
1715 Map[ (Flatten[ Position[ #, _?(Function[n, n!=0])] ])&, g ]
1716
1717FromAdjacencyLists[e_List] :=
1718 Module[{blanks = Table[0,{Length[e]}] },
1719 Graph[
1720 Map [ (MapAt[ 1&,blanks,Partition[#,1]])&, e ],
1721 CircularVertices[Length[e]]
1722 ]
1723 ]
1724
1725FromAdjacencyLists[e_List,v_List] := ChangeVertices[FromAdjacencyLists[e], v]
1726
1727ToOrderedPairs[g_Graph] := Position[ Edges[g], _?(Function[n,n != 0]) ]
1728
1729ToUnorderedPairs[g_Graph] := Select[ ToOrderedPairs[g], (#[[1]] < #[[2]])& ]
1730
1731FromOrderedPairs[l_List] :=
1732 Module[{n=Max[l]},
1733 Graph[
1734 MapAt[1&, Table[0,{n},{n}],l],
1735 CircularVertices[n]
1736 ]
1737 ]
1738FromOrderedPairs[{}] := Graph[{},{}]
1739FromOrderedPairs[l_List,v_List] :=
1740 Graph[ MapAt[1&, Table[0,{Length[v]},{Length[v]}], l], v]
1741
1742FromUnorderedPairs[l_List] := MakeUndirected[ FromOrderedPairs[l] ]
1743FromUnorderedPairs[l_List,v_List] := MakeUndirected[ FromOrderedPairs[l,v] ]
1744
1745(* Addition: Extension of From* and ToOrderedPairs
1746by Fukuda 941006 *)
1747FromOrderedTriples[tr_List]:=
1748 Block[{graph,pairs,wedges},
1749 pairs=Transpose[Drop[Transpose[tr],-1]];
1750 graph=FromOrderedPairs[pairs];
1751 wedges=Edges[graph];
1752 Scan[(wedges[[#[[1]],#[[2]]]]=#[[3]])&,tr];
1753 graph=Graph[wedges,Vertices[graph]]
1754 ]
1755
1756FromUnorderedTriples[tr_List]:=
1757 Block[{graph,pairs,wedges},
1758 pairs=Transpose[Drop[Transpose[tr],-1]];
1759 graph=FromOrderedPairs[pairs];
1760 wedges=Edges[graph];
1761 Scan[(wedges[[#[[1]],#[[2]]]]=#[[3]];wedges[[#[[2]],#[[1]]]]=#[[3]])&,tr];
1762 graph=Graph[wedges,Vertices[graph]]
1763 ]
1764
1765ToOrderedTriples[g_Graph] :=
1766 Map[Append[#,Edges[g][[#[[1]],#[[2]]]]]&, Position[ Edges[g], _?(Function[n,n != 0]) ]]
1767(* end of Addition *)
1768
1769PseudographQ[Graph[g_,_]] :=
1770 Module[{i},
1771 Apply[Or, Table[ g[[i,i]]!=0, {i,Length[g]} ]]
1772 ]
1773
1774UnweightedQ[Graph[g_,_]] := Apply[ And, Map[(#==0 || #==1)&, Flatten[g] ] ]
1775
1776SimpleQ[g_Graph] := (!PseudographQ[g]) && (UnweightedQ[g])
1777
1778RemoveSelfLoops[g_Graph] :=
1779 Module[{i,e=Edges[g]},
1780 Do [ e[[i,i]]=0, {i,V[g]} ];
1781 Graph[e, Vertices[g]]
1782 ]
1783
1784EmptyQ[g_Graph] := Edges[g] == Table[0, {V[g]}, {V[g]}]
1785
1786CompleteQ[g_Graph] := Edges[RemoveSelfLoops[g]] == Edges[ K[V[g]] ]
1787
1788InduceSubgraph[g_Graph,{}] := Graph[{},{}]
1789
1790InduceSubgraph[Graph[g_,v_],s_List] :=
1791 Graph[Transpose[Transpose[g[[s]]] [[s]] ],v[[s]]] /; (Length[s]<=Length[g])
1792
1793Contract[g_Graph,{u_Integer,v_Integer}] :=
1794 Module[{o,e,i,n=V[g],newg,range=Complement[Range[V[g]],{u,v}]},
1795 newg = InduceSubgraph[g,range];
1796 e = Edges[newg]; o = Edges[g];
1797 Graph[
1798 Append[
1799 Table[
1800 Append[e[[i]],
1801 If[o[[range[[i]],u]]>0 ||
1802 o[[range[[i]],v]]>0,1,0] ],
1803 {i,n-2}
1804 ],
1805 Append[
1806 Map[(If[o[[u,#]]>0||o[[v,#]]>0,1,0])&,range],
1807 0
1808 ]
1809 ],
1810 Join[Vertices[newg], {(Vertices[g][[u]]+Vertices[g][[v]])/2}]
1811 ]
1812 ] /; V[g] > 2
1813
1814Contract[g_Graph,_] := K[1] /; V[g] == 2
1815
1816GraphComplement[Graph[g_,v_]] :=
1817 RemoveSelfLoops[ Graph[ Map[ (Map[ (If [#==0,1,0])&, #])&, g], v ] ]
1818
1819MakeUndirected[Graph[g_,v_]] :=
1820 Module[{i,j,n=Length[g]},
1821 Graph[ Table[If [g[[i,j]]!=0 || g[[j,i]]!=0,1,0],{i,n},{j,n}], v ]
1822 ]
1823
1824UndirectedQ[Graph[g_,_]] := (Apply[Plus,Apply[Plus,Abs[g-Transpose[g]]]] == 0)
1825
1826MakeSimple[g_Graph] := MakeUndirected[RemoveSelfLoops[g]]
1827
1828BFS[g_Graph,start_Integer] :=
1829 Module[{e,bfi=Table[0,{V[g]}],cnt=1,edges={},queue={start}},
1830 e = ToAdjacencyLists[g];
1831 bfi[[start]] = cnt++;
1832 While[ queue != {},
1833 {v,queue} = {First[queue],Rest[queue]};
1834 Scan[
1835 (If[ bfi[[#]] == 0,
1836 bfi[[#]] = cnt++;
1837 AppendTo[edges,{v,#}];
1838 AppendTo[queue,#]
1839 ])&,
1840 e[[v]]
1841 ];
1842 ];
1843 {edges,bfi}
1844 ]
1845
1846BreadthFirstTraversal[g_Graph,s_Integer,Edge] := First[BFS[g,s]]
1847
1848BreadthFirstTraversal[g_Graph,s_Integer,___] := InversePermutation[Last[BFS[g,s]]]
1849
1850DFS[v_Integer] :=
1851 ( dfi[[v]] = cnt++;
1852 AppendTo[visit,v];
1853 Scan[ (If[dfi[[#]]==0,AppendTo[edges,{v,#}];DFS[#] ])&, e[[v]] ] )
1854
1855DepthFirstTraversal[g_Graph,start_Integer,flag_:Vertex] :=
1856 Block[{visit={},e=ToAdjacencyLists[g],edges={},dfi=Table[0,{V[g]}],cnt=1},
1857 DFS[start];
1858 If[ flag===Edge, edges, visit]
1859 ]
1860
1861ShowGraph[g1_Graph,type_:Undirected] :=
1862 Module[{g=NormalizeVertices[g1]},
1863 Show[
1864 Graphics[
1865 Join[
1866 PointsAndLines[g],
1867 If[SameQ[type,Directed],Arrows[g],{}]
1868 ]
1869 ],
1870 {AspectRatio->1, PlotRange->FindPlotRange[Vertices[g]]}
1871 ]
1872 ]
1873
1874(* Addtion: Weighted Graph drawing by
1875 Fukuda 941006 *)
1876ShowWeightedGraph[g1_Graph,type_:Undirected] :=
1877 Module[{g=NormalizeVertices[g1]},
1878 Show[
1879 Graphics[
1880 Join[
1881 If[SameQ[type,Directed],PointsAndLines[g],PointsAndProportionalLines[g]],
1882 If[SameQ[type,Directed],ProportionalArrows[g],{}]
1883 ]
1884 ],
1885 {AspectRatio->1, PlotRange->FindPlotRange[Vertices[g]]}
1886 ]
1887 ]
1888
1889
1890MinimumEdgeLength[v_List,pairs_List] :=
1891 Max[ Select[
1892 Chop[ Map[(Sqrt[ N[(v[[#[[1]]]]-v[[#[[2]]]]) .
1893 (v[[#[[1]]]]-v[[#[[2]]]])] ])&,pairs] ],
1894 (# > 0)&
1895 ], 0.001 ]
1896
1897(* Change: for larger off-set by K. Fukuda 930530 *)
1898FindPlotRange[v_List] :=
1899 Module[{xmin=Min[Map[First,v]], xmax=Max[Map[First,v]],
1900 ymin=Min[Map[Last,v]], ymax=Max[Map[Last,v]]},
1901 { {xmin - 0.18 Max[1,xmax-xmin], xmax + 0.18 Max[1,xmax-xmin]},
1902 {ymin - 0.18 Max[1,ymax-ymin], ymax + 0.18 Max[1,ymax-ymin]} }
1903 ]
1904(* end Change *)
1905
1906(* Change: for thiner line and smaller points by
1907 K. Fukuda 960516 *)
1908PointsAndLines[Graph[e_List,v_List]] :=
1909 Module[{pairs=ToOrderedPairs[Graph[e,v]]},
1910 Join[
1911 {PointSize[ 0.02 ]},
1912 Map[Point,Chop[v]],
1913 {Thickness[ 0.0025 ]},
1914 Map[(Line[Chop[ v[[#]] ]])&,pairs]
1915 ]
1916 ]
1917PointsAndProportionalLines[Graph[e_List,v_List]] :=
1918 Module[{triples=ToOrderedTriples[Graph[e,v]]},
1919 Join[
1920 {PointSize[ 0.02 ]},
1921 Map[Point,Chop[v]],
1922 Map[{Thickness[ 0.0025 * #[[3]]],(Line[Chop[ v[[Drop[#,-1]]] ]])}&,triples]
1923 ]
1924 ]
1925
1926
1927(* End Change *)
1928
1929(* Change: Narrower arrow, and different arrow positioning by
1930 K. Fukuda 930604 *)
1931Arrows[Graph[e_,v_]] :=
1932 Module[{pairs=ToOrderedPairs[Graph[e,v]], size, triangle},
1933 size = Min[0.04, MinimumEdgeLength[v,pairs]/4];
1934 triangle={ {0,0}, {-size,size/4}, {-size,-size/4} };
1935 Map[
1936 (Polygon[
1937 TranslateVertices[
1938 RotateVertices[
1939 triangle,
1940 Arctan[Apply[Subtract,v[[#]]]]+Pi
1941 ],
1942 v[[ #[[2]] ]]*(7/8)+v[[ #[[1]] ]]*(1/8)
1943 ]
1944 ])&,
1945 pairs
1946 ]
1947 ]
1948(* end of Change *)
1949
1950(* Addition: Proportional arrows for weighted graphs by
1951 K. Fukuda 930604 *)
1952ProportionalArrows[Graph[e_,v_]] :=
1953 Module[{triples=ToOrderedTriples[Graph[e,v]],
1954 pairs=ToOrderedPairs[Graph[e,v]],size, triangle},
1955 size = Min[0.05, MinimumEdgeLength[v,pairs]/3];
1956 triangle={ {0,0}, {-size,size/4}, {-size,-size/4} };
1957 Map[
1958 (Polygon[
1959 TranslateVertices[
1960 RotateVertices[
1961 triangle * #[[3]],
1962 Arctan[Apply[Subtract,v[[Drop[#,-1]]]]]+Pi
1963 ],
1964 v[[ #[[2]] ]]*(7/8)+v[[ #[[1]] ]]*(1/8)
1965 ]
1966 ])&,
1967 triples
1968 ]
1969 ]
1970(* end of Change *)
1971
1972ShowLabeledGraph[g_Graph] := ShowLabeledGraph[g,Range[V[g]]]
1973ShowLabeledGraph[g1_Graph,labels_List] :=
1974 Module[{pairs=ToOrderedPairs[g1], g=NormalizeVertices[g1], v},
1975 v = Vertices[g];
1976 Show[
1977 Graphics[
1978 Join[
1979 PointsAndLines[g],
1980 Map[(Line[Chop[ v[[#]] ]])&, pairs],
1981 GraphLabels[v,labels]
1982 ]
1983 ],
1984 {AspectRatio->1, PlotRange->FindPlotRange[v]}
1985 ]
1986 ]
1987
1988(* Addition: Directed option for ShowLabeledGraph
1989 by K. Fukuda 930604 *)
1990ShowLabeledGraph[g1_Graph,labels_List,type_:Undirected] :=
1991 Module[{pairs=ToOrderedPairs[g1], g=NormalizeVertices[g1], v},
1992 v = Vertices[g];
1993 Show[
1994 Graphics[
1995 Join[
1996 PointsAndLines[g],
1997 If[SameQ[type,Directed],Arrows[g],{}],
1998 Map[(Line[Chop[ v[[#]] ]])&, pairs],
1999 GraphLabels[v,labels]
2000 ]
2001 ],
2002 {AspectRatio->1, PlotRange->FindPlotRange[v]}
2003 ]
2004 ]
2005
2006ShowWeightedLabeledGraph[g1_Graph,labels_List,type_:Undirected] :=
2007 Module[{pairs=ToOrderedPairs[g1], g=NormalizeVertices[g1], v},
2008 v = Vertices[g];
2009 Show[
2010 Graphics[
2011 Join[
2012 If[SameQ[type,Directed],PointsAndLines[g],PointsAndProportionalLines[g]],
2013 If[SameQ[type,Directed],ProportionalArrows[g],{}],
2014 Map[(Line[Chop[ v[[#]] ]])&, pairs],
2015 GraphLabels[v,labels]
2016 ]
2017 ],
2018 {AspectRatio->1, PlotRange->FindPlotRange[v]}
2019 ]
2020 ]
2021
2022
2023(* end Addition *)
2024
2025GraphLabels[v_List,l_List] :=
2026 Module[{i},
2027 Table[ Text[ l[[i]],v[[i]]-{0.025,0.025},{0,1} ],{i,Length[v]}]
2028 ]
2029
2030CircularVertices[0] := {}
2031
2032CircularVertices[n_Integer] :=
2033 Module[{i,x = N[2 Pi / n]},
2034 Chop[ Table[ N[{ (Cos[x i]), (Sin[x i]) }], {i,n} ] ]
2035 ]
2036
2037CircularVertices[Graph[g_,_]] := Graph[ g, CircularVertices[ Length[g] ] ]
2038
2039RankGraph[g_Graph, start_List] :=
2040 Module[ {rank = Table[0,{V[g]}],edges = ToAdjacencyLists[g],v,queue,new},
2041 Scan[ (rank[[#]] = 1)&, start];
2042 queue = start;
2043 While [queue != {},
2044 v = First[queue];
2045 new = Select[ edges[[v]], (rank[[#]] == 0)&];
2046 Scan[ (rank[[#]] = rank[[v]]+1)&, new];
2047 queue = Join[ Rest[queue], new];
2048 ];
2049 rank
2050 ]
2051
2052RankedEmbedding[g_Graph,start_List] := Graph[ Edges[g],RankedVertices[g,start] ]
2053
2054RankedVertices[g_Graph,start_List] :=
2055 Module[{i,m,stages,rank,freq = Table[0,{V[g]}]},
2056 rank = RankGraph[g,start];
2057 stages = Distribution[ rank ];
2058 Table[
2059 m = ++ freq[[ rank[[i]] ]];
2060 {rank[[i]], (m-1) + (1 - stages[[ rank[[i]] ]])/2 },
2061 {i,V[g]}
2062 ]
2063 ]
2064
2065Distribution[l_List] := Distribution[l, Union[l]]
2066Distribution[l_List, set_List] := Map[(Count[l,#])&, set]
2067
2068Eccentricity[g_Graph] := Map[ Max, AllPairsShortestPath[g] ]
2069Eccentricity[g_Graph,start_Integer] := Map[ Max, Last[Dijkstra[g,start]] ]
2070
2071Diameter[g_Graph] := Max[ Eccentricity[g] ]
2072
2073Radius[g_Graph] := Min[ Eccentricity[g] ]
2074
2075GraphCenter[g_Graph] :=
2076 Module[{eccentricity = Eccentricity[g]},
2077 Flatten[ Position[eccentricity, Min[eccentricity]] ]
2078 ]
2079
2080RadialEmbedding[g_Graph,ct_Integer] :=
2081 Module[{center=ct,ang,i,da,theta,n,v,positioned,done,next,e=ToAdjacencyLists[g]},
2082 ang = Table[{0,2 Pi},{n=V[g]}];
2083 v = Table[{0,0},{n}];
2084 positioned = next = done = {center};
2085 While [next != {},
2086 center = First[next];
2087 new = Complement[e[[center]], positioned];
2088 Do [
2089 da = (ang[[center,2]]-ang[[center,1]])/Length[new];
2090 ang[[ new[[i]] ]] = {ang[[center,1]] + (i-1)*da,
2091 ang[[center,1]] + i*da};
2092 theta = Apply[Plus,ang[[ new[[i]] ]] ]/2;
2093 v[[ new[[i]] ]] = v[[center]] +
2094 N[{Cos[theta],Sin[theta]}],
2095 {i,Length[new]}
2096 ];
2097 next = Join[Rest[next],new];
2098 positioned = Union[positioned,new];
2099 AppendTo[done,center]
2100 ];
2101 Graph[Edges[g],v]
2102 ]
2103
2104RadialEmbedding[g_Graph] := RadialEmbedding[g,First[GraphCenter[g]]];
2105
2106RootedEmbedding[g_Graph,rt_Integer] :=
2107 Module[{root=rt,pos,i,x,dx,new,n=V[g],v,done,next,e=ToAdjacencyLists[g]},
2108 pos = Table[{-Ceiling[Sqrt[n]],Ceiling[Sqrt[n]]},{n}];
2109 v = Table[{0,0},{n}];
2110 next = done = {root};
2111 While [next != {},
2112 root = First[next];
2113 new = Complement[e[[root]], done];
2114 Do [
2115 dx = (pos[[root,2]]-pos[[root,1]])/Length[new];
2116 pos[[ new[[i]] ]] = {pos[[root,1]] + (i-1)*dx,
2117 pos[[root,1]] + i*dx};
2118 x = Apply[Plus,pos[[ new[[i]] ]] ]/2;
2119 v[[ new[[i]] ]] = {x,v[[root,2]]-1},
2120 {i,Length[new]}
2121 ];
2122 next = Join[Rest[next],new];
2123 done = Join[done,new]
2124 ];
2125 Graph[Edges[g],N[v]]
2126 ]
2127
2128TranslateVertices[v_List,{x_,y_}] := Map[ (# + {x,y})&, v ]
2129TranslateVertices[Graph[g_,v_],{x_,y_}] := Graph[g, TranslateVertices[v,{x,y}] ]
2130
2131DilateVertices[v_List,d_] := (d * v)
2132DilateVertices[Graph[e_,v_],d_] := Graph[e, DilateVertices[v,d]]
2133
2134RotateVertices[v_List,t_] :=
2135 Module[{d,theta},
2136 Map[
2137 (If[# == {0,0}, {0,0},
2138 d=Sqrt[#[[1]]^2 + #[[2]]^2];
2139 theta = t + Arctan[#];
2140 N[{d Cos[theta], d Sin[theta]}]
2141 ])&,
2142 v
2143 ]
2144 ]
2145RotateVertices[Graph[g_,v_],t_] := Graph[g, RotateVertices[v,t]]
2146
2147Arctan[{x_,y_}] := Arctan1[Chop[{x,y}]]
2148Arctan1[{0,0}] := 0
2149Arctan1[{x_,y_}] := ArcTan[x,y]
2150
2151(* Change: to normalize in x and y directions independently]
2152 by K. Fukuda 930601 *)
2153NormalizeVertices[v_List] :=
2154 Module[{vx=Transpose[v][[1]],vy=Transpose[v][[2]],
2155 xmin,xmax,ymin,ymax,dx,dy},
2156 xmin=Min[vx]; xmax=Max[vx];
2157 ymin=Min[vy]; ymax=Max[vy];
2158 dx=Max[(xmax-xmin),0.01];
2159 dy=Max[(ymax-ymin),0.01];
2160 Map[{(#[[1]]-xmin)/dx,(#[[2]]-ymin)/dy}&,v]
2161 ]
2162(* end Change *)
2163
2164NormalizeVertices[Graph[g_,v_]] := Graph[g, NormalizeVertices[v]]
2165
2166ShakeGraph[Graph[e_List,v_List], fract_:0.1] :=
2167 Module[{i,d,a},
2168 Graph[
2169 e,
2170 Table[
2171 d = Random[Real,{0,fract}];
2172 a = Random[Real,{0, 2 N[Pi]}];
2173 {N[v[[i,1]] + d Cos[a]], N[v[[i,2]] + d Sin[a]]},
2174 {i,Length[e]}
2175 ]
2176 ]
2177 ]
2178
2179CalculateForce[u_Integer,g_Graph,em_List] :=
2180 Module[{n=V[g],stc=0.25,gr=10.0,e=Edges[g],f={0.0,0.0},spl=1.0,v,dsquared},
2181 Do [
2182 dsquared = Max[0.001, Apply[Plus,(em[[u]]-em[[v]])^2] ];
2183 f += (1-e[[u,v]]) (gr/dsquared) (em[[u]]-em[[v]])
2184 - e[[u,v]] stc Log[dsquared/spl] (em[[u]]-em[[v]]),
2185 {v,n}
2186 ];
2187 f
2188 ]
2189
2190SpringEmbedding[g_Graph,step_:10,inc_:0.15] :=
2191 Module[{new=old=Vertices[g],n=V[g],i,u,g1=MakeUndirected[g]},
2192 Do [
2193 Do [
2194 new[[u]] = old[[u]]+inc*CalculateForce[u,g1,old],
2195 {u,n}
2196 ];
2197 old = new,
2198 {i,step}
2199 ];
2200 Graph[Edges[g],new]
2201 ]
2202
2203(* Rewritten for Version 2.0 *)
2204
2205
2206(* Change: A directed spring embedding made by
2207Fukuda 94-10-05 *)
2208
2209SpringEmbeddingDirected[g_Graph,step_:10,inc_:0.15] :=
2210 Module[{new=old=Vertices[g],n=V[g],i,u,g1=g},
2211 Do [
2212 Do [
2213 new[[u]] = old[[u]]+inc*CalculateForce[u,g1,old],
2214 {u,n}
2215 ];
2216 old = new,
2217 {i,step}
2218 ];
2219 Graph[Edges[g],new]
2220 ]
2221
2222(* end of Change *)
2223
2224ReadGraph[file_] :=
2225 Module[{edgelist={}, v={},x},
2226 OpenRead[file];
2227 While[!SameQ[(x = Read[file,Number]), EndOfFile],
2228 AppendTo[v,Read[file,{Number,Number}]];
2229 AppendTo[edgelist,
2230 Convert[Characters[Read[file,String]]]
2231 ];
2232 ];
2233 Close[file];
2234 FromAdjacencyLists[edgelist,v]
2235 ]
2236
2237Toascii[s_String] := First[ ToCharacterCode[s] ]
2238
2239Convert[l_List] :=
2240 Module[{ch,num,edge={},i=1},
2241 While[i <= Length[l],
2242 If[ DigitQ[ l[[i]] ],
2243 num = 0;
2244 While[ ((i <= Length[l]) && (DigitQ[l[[i]]])),
2245 num = 10 num + Toascii[l[[i++]]] - Toascii["0"]
2246 ];
2247 AppendTo[edge,num],
2248 i++
2249 ];
2250 ];
2251 edge
2252 ]
2253
2254WriteGraph[g_Graph,file_] :=
2255 Module[{edges=ToAdjacencyLists[g],v=N[NormalizeVertices[Vertices[g]]],i,x,y},
2256 OpenWrite[file];
2257 Do[
2258 WriteString[file," ",ToString[i]];
2259 {x,y} = Chop[ v [[i]] ];
2260 WriteString[file," ",ToString[x]," ",ToString[y]];
2261 Scan[
2262 (WriteString[file," ",ToString[ # ]])&,
2263 edges[[i]]
2264 ];
2265 Write[file],
2266 {i,V[g]}
2267 ];
2268 Close[file];
2269 ]
2270
2271GraphUnion[g_Graph,h_Graph] :=
2272 Module[{maxg=Max[ Map[First,Vertices[g]] ], minh=Min[ Map[First,Vertices[h]] ]},
2273 FromOrderedPairs[
2274 Join[ ToOrderedPairs[g], (ToOrderedPairs[h] + V[g])],
2275 Join[ Vertices[g], Map[({maxg-minh+1,0}+#)&, Vertices[h] ] ]
2276 ]
2277 ]
2278
2279GraphUnion[1,g_Graph] := g
2280GraphUnion[0,g_Graph] := EmptyGraph[0];
2281GraphUnion[k_Integer,g_Graph] := GraphUnion[ GraphUnion[k-1,g], g]
2282
2283ExpandGraph[g_Graph,n_] := GraphUnion[ g, EmptyGraph[n - V[g]] ] /; V[g] <= n
2284
2285GraphIntersection[g_Graph,h_Graph] :=
2286 FromOrderedPairs[
2287 Intersection[ToOrderedPairs[g],ToOrderedPairs[h]],
2288 Vertices[g]
2289 ] /; (V[g] == V[h])
2290
2291GraphDifference[g1_Graph,g2_Graph] :=
2292 Graph[Edges[g1] - Edges[g2], Vertices[g1]] /; V[g1]==V[g2]
2293
2294GraphSum[g1_Graph,g2_Graph] :=
2295 Graph[Edges[g1] + Edges[g2], Vertices[g1]] /; V[g1]==V[g2]
2296
2297GraphJoin[g_Graph,h_Graph] :=
2298 Module[{maxg=Max[ Abs[ Map[First,Vertices[g]] ] ]},
2299 FromUnorderedPairs[
2300 Join[
2301 ToUnorderedPairs[g],
2302 ToUnorderedPairs[h] + V[g],
2303 CartesianProduct[Range[V[g]],Range[V[h]]+V[g]]
2304 ],
2305 Join[ Vertices[g], Map[({maxg+1,0}+#)&, Vertices[h]]]
2306 ]
2307 ]
2308
2309CartesianProduct[a_List,b_List] :=
2310 Module[{i,j},
2311 Flatten[ Table[{a[[i]],b[[j]]},{i,Length[a]},{j,Length[b]}], 1]
2312 ]
2313
2314GraphProduct[g_Graph,h_Graph] :=
2315 Module[{k,eg=ToOrderedPairs[g],eh=ToOrderedPairs[h],leng=V[g],lenh=V[h]},
2316 FromOrderedPairs[
2317 Flatten[
2318 Join[
2319 Table[eg+(i-1)*leng, {i,lenh}],
2320 Map[ (Table[
2321 {leng*(#[[1]]-1)+k, leng*(#[[2]]-1)+k},
2322 {k,1,leng}
2323 ])&,
2324 eh
2325 ]
2326 ],
2327 1
2328 ],
2329 ProductVertices[Vertices[g],Vertices[h]]
2330 ]
2331 ]
2332
2333ProductVertices[vg_,vh_] :=
2334 Flatten[
2335 Map[
2336 (TranslateVertices[
2337 DilateVertices[vg, 1/(Max[Length[vg],Length[vh]])],
2338 #])&,
2339 RotateVertices[vh,Pi/2]
2340 ],
2341 1
2342 ]
2343
2344IncidenceMatrix[g_Graph] :=
2345 Map[
2346 ( Join[
2347 Table[0,{First[#]-1}], {1},
2348 Table[0,{Last[#]-First[#]-1}], {1},
2349 Table[0,{V[g]-Last[#]}]
2350 ] )&,
2351 ToUnorderedPairs[g]
2352 ]
2353
2354LineGraph[g_Graph] :=
2355 Module[{b=IncidenceMatrix[g], edges=ToUnorderedPairs[g], v=Vertices[g]},
2356 Graph[
2357 b . Transpose[b] - 2 IdentityMatrix[Length[edges]],
2358 Map[ ( (v[[ #[[1]] ]] + v[[ #[[2]] ]]) / 2 )&, edges]
2359 ]
2360 ]
2361
2362K[0] := Graph[{},{}]
2363K[1] := Graph[{{0}},{{0,0}}]
2364
2365K[n_Integer?Positive] := CirculantGraph[n,Range[1,Floor[(n+1)/2]]]
2366
2367CirculantGraph[n_Integer?Positive,l_List] :=
2368 Module[{i,r},
2369 r = Prepend[MapAt[1&,Table[0,{n-1}], Map[List,Join[l,n-l]]], 0];
2370 Graph[ Table[RotateRight[r,i], {i,0,n-1}], CircularVertices[n] ]
2371 ]
2372
2373EmptyGraph[n_Integer?Positive] :=
2374 Module[{i},
2375 Graph[ Table[0,{n},{n}], Table[{0,i},{i,(1-n)/2,(n-1)/2}] ]
2376 ]
2377
2378K[l__] :=
2379 Module[{ll=List[l],t,i,x,row,stages=Length[List[l]]},
2380 t = FoldList[Plus,0,ll];
2381 Graph[
2382 Apply[
2383 Join,
2384 Table [
2385 row = Join[
2386 Table[1, {t[[i-1]]}],
2387 Table[0, {t[[i]]-t[[i-1]]}],
2388 Table[1, {t[[stages+1]]-t[[i]]}]
2389 ];
2390 Table[row, {ll[[i-1]]}],
2391 {i,2,stages+1}
2392 ]
2393
2394 ],
2395 Apply [
2396 Join,
2397 Table[
2398 Table[{x,i-1+(1-ll[[x]])/2},{i,ll[[x]]}],
2399 {x,stages}
2400 ]
2401 ]
2402 ]
2403 ] /; TrueQ[Apply[And, Map[Positive,List[l]]]] && (Length[List[l]]>1)
2404
2405Turan[n_Integer,p_Integer] :=
2406 Module[{k = Floor[ n / (p-1) ], r},
2407 r = n - k (p-1);
2408 Apply[K, Join[ Table[k,{p-1-r}], Table[k+1,{r}] ] ]
2409 ] /; (n > 0 && p > 1)
2410
2411Cycle[n_Integer] := CirculantGraph[n,{1}] /; n>=3
2412
2413Star[n_Integer?Positive] :=
2414 Module[{g},
2415 g = Append [ Table[0,{n-1},{n}], Append[ Table[1,{n-1}], 0] ];
2416 Graph[
2417 g + Transpose[g],
2418 Append[ CircularVertices[n-1], {0,0}]
2419 ]
2420 ]
2421
2422Wheel[n_Integer] :=
2423 Module[{i,row = Join[{0,1}, Table[0,{n-4}], {1}]},
2424 Graph[
2425 Append[
2426 Table[ Append[RotateRight[row,i-1],1], {i,n-1}],
2427 Append[ Table[1,{n-1}], 0]
2428 ],
2429 Append[ CircularVertices[n-1], {0,0} ]
2430 ]
2431 ] /; n >= 3
2432
2433Path[1] := K[1]
2434Path[n_Integer?Positive] :=
2435 FromUnorderedPairs[ Partition[Range[n],2,1], Map[({#,0})&,Range[n]] ]
2436
2437GridGraph[n_Integer?Positive,m_Integer?Positive] :=
2438 GraphProduct[
2439 ChangeVertices[Path[n], Map[({Max[n,m]*#,0})&,Range[n]]],
2440 Path[m]
2441 ]
2442
2443Hypercube[n_Integer] := Hypercube1[n]
2444
2445Hypercube1[0] := K[1]
2446Hypercube1[1] := Path[2]
2447Hypercube1[2] := Cycle[4]
2448
2449Hypercube1[n_Integer] := Hypercube1[n] =
2450 GraphProduct[
2451 RotateVertices[ Hypercube1[Floor[n/2]], 2Pi/5],
2452 Hypercube1[Ceiling[n/2]]
2453 ]
2454
2455LabeledTreeToCode[g_Graph] :=
2456 Module[{e=ToAdjacencyLists[g],i,code},
2457 Table [
2458 {i} = First[ Position[ Map[Length,e], 1 ] ];
2459 code = e[[i,1]];
2460 e[[code]] = Complement[ e[[code]], {i} ];
2461 e[[i]] = {};
2462 code,
2463 {V[g]-2}
2464 ]
2465 ]
2466
2467CodeToLabeledTree[l_List] :=
2468 Module[{m=Range[Length[l]+2],x,i},
2469 FromUnorderedPairs[
2470 Append[
2471 Table[
2472 x = Min[Complement[m,Drop[l,i-1]]];
2473 m = Complement[m,{x}];
2474 {x,l[[i]]},
2475 {i,Length[l]}
2476 ],
2477 m
2478 ]
2479 ]
2480 ]
2481
2482RandomTree[n_Integer?Positive] :=
2483 RadialEmbedding[CodeToLabeledTree[ Table[Random[Integer,{1,n}],{n-2}] ], 1]
2484
2485RandomGraph[n_Integer,p_] := RandomGraph[n,p,{1,1}]
2486
2487RandomGraph[n_Integer,p_,range_List] :=
2488 Module[{i,g},
2489 g = Table[
2490 Join[
2491 Table[0,{i}],
2492 Table[
2493 If[Random[Real]<p, Random[Integer,range], 0],
2494 {n-i}
2495 ]
2496 ],
2497 {i,n}
2498 ];
2499 Graph[ g + Transpose[g], CircularVertices[n] ]
2500 ]
2501
2502ExactRandomGraph[n_Integer,e_Integer] :=
2503 FromUnorderedPairs[
2504 Map[ NthPair, Take[ RandomPermutation[n(n-1)/2], e] ],
2505 CircularVertices[n]
2506 ]
2507
2508NthPair[0] := {}
2509NthPair[n_Integer] :=
2510 Module[{i=2},
2511 While[ Binomial[i,2] < n, i++];
2512 {n - Binomial[i-1,2], i}
2513 ]
2514
2515RandomVertices[n_Integer] := Table[{Random[], Random[]}, {n}]
2516RandomVertices[g_Graph] := Graph[ Edges[g], RandomVertices[V[g]] ]
2517
2518RandomGraph[n_Integer,p_,range_List,Directed] :=
2519 RemoveSelfLoops[
2520 Graph[
2521 Table[If[Random[Real]<p,Random[Integer,range],0],{n},{n}],
2522 CircularVertices[n]
2523 ]
2524 ]
2525
2526RandomGraph[n_Integer,p_,Directed] := RandomGraph[n,p,{1,1},Directed]
2527
2528DegreeSequence[g_Graph] := Reverse[ Sort[ Degrees[g] ] ]
2529
2530Degrees[Graph[g_,_]] := Map[(Apply[Plus,#])&, g]
2531
2532GraphicQ[s_List] := False /; (Min[s] < 0) || (Max[s] >= Length[s])
2533GraphicQ[s_List] := (First[s] == 0) /; (Length[s] == 1)
2534GraphicQ[s_List] :=
2535 Module[{m,sorted = Reverse[Sort[s]]},
2536 m = First[sorted];
2537 GraphicQ[ Join[ Take[sorted,{2,m+1}]-1, Drop[sorted,m+1] ] ]
2538 ]
2539
2540RealizeDegreeSequence[d_List] :=
2541 Module[{i,j,v,set,seq,n=Length[d],e},
2542 seq = Reverse[ Sort[ Table[{d[[i]],i},{i,n}]] ];
2543 FromUnorderedPairs[
2544 Flatten[ Table[
2545 {{k,v},seq} = {First[seq],Rest[seq]};
2546 While[ !GraphicQ[
2547 MapAt[
2548 (# - 1)&,
2549 Map[First,seq],
2550 set = RandomKSubset[Table[{i},{i,n-j}],k]
2551 ] ]
2552 ];
2553 e = Map[(Prepend[seq[[#,2]],v])&,set];
2554 seq = Reverse[ Sort[
2555 MapAt[({#[[1]]-1,#[[2]]})&,seq,set]
2556 ] ];
2557 e,
2558 {j,Length[d]-1}
2559 ], 1],
2560 CircularVertices[n]
2561 ]
2562 ] /; GraphicQ[d]
2563
2564RealizeDegreeSequence[d_List,seed_Integer] :=
2565 (SeedRandom[seed]; RealizeDegreeSequence[d])
2566
2567RegularQ[Graph[g_,_]] := Apply[ Equal, Map[(Apply[Plus,#])& , g] ]
2568
2569RegularGraph[k_Integer,n_Integer] := RealizeDegreeSequence[Table[k,{n}]]
2570
2571MakeGraph[v_List,f_] :=
2572 Module[{n=Length[v],i,j},
2573 Graph [
2574 Table[If [Apply[f,{v[[i]],v[[j]]}], 1, 0],{i,n},{j,n}],
2575 CircularVertices[n]
2576 ]
2577 ]
2578
2579IntervalGraph[l_List] :=
2580 MakeGraph[
2581 l,
2582 ( ((First[#1] <= First[#2]) && (Last[#1] >= First[#2])) ||
2583 ((First[#2] <= First[#1]) && (Last[#2] >= First[#1])) )&
2584 ]
2585
2586FunctionalGraph[f_,n_] :=
2587 Module[{i,x},
2588 FromOrderedPairs[
2589 Table[{i, x=Mod[Apply[f,{i}],n]; If[x!=0,x,n]}, {i,n} ],
2590 CircularVertices[n]
2591 ]
2592 ]
2593
2594ConnectedComponents[g_Graph] :=
2595 Module[{untraversed=Range[V[g]],traversed,comps={}},
2596 While[untraversed != {},
2597 traversed = DepthFirstTraversal[g,First[untraversed]];
2598 AppendTo[comps,traversed];
2599 untraversed = Complement[untraversed,traversed]
2600 ];
2601 comps
2602 ]
2603
2604ConnectedQ[g_Graph] := Length[ DepthFirstTraversal[g,1] ] == V[g]
2605
2606WeaklyConnectedComponents[g_Graph] := ConnectedComponents[ MakeUndirected[g] ]
2607
2608ConnectedQ[g_Graph,Undirected] := Length[ WeaklyConnectedComponents[g] ] == 1
2609
2610StronglyConnectedComponents[g_Graph] :=
2611 Block[{e=ToAdjacencyLists[g],s,c=1,i,cur={},low=dfs=Table[0,{V[g]}],scc={}},
2612 While[(s=Select[Range[V[g]],(dfs[[#]]==0)&]) != {},
2613 SearchStrongComp[First[s]];
2614 ];
2615 scc
2616 ]
2617
2618SearchStrongComp[v_Integer] :=
2619 Block[{r},
2620 low[[v]]=dfs[[v]]=c++;
2621 PrependTo[cur,v];
2622 Scan[
2623 (If[dfs[[#]] == 0,
2624 SearchStrongComp[#];
2625 low[[v]]=Min[low[[v]],low[[#]]],
2626 If[(dfs[[#]] < dfs[[v]]) && MemberQ[cur,#],
2627 low[[v]]=Min[low[[v]],dfs[[#]] ]
2628 ];
2629 ])&,
2630 e[[v]]
2631 ];
2632 If[low[[v]] == dfs[[v]],
2633 {r} = Flatten[Position[cur,v]];
2634 AppendTo[scc,Take[cur,r]];
2635 cur = Drop[cur,r];
2636 ];
2637 ]
2638
2639ConnectedQ[g_Graph,Directed] := Length[ StronglyConnectedComponents[g] ] == 1
2640
2641OrientGraph[g_Graph] :=
2642 Module[{pairs,newg,rest,cc,c,i,e},
2643 pairs = Flatten[Map[(Partition[#,2,1])&,ExtractCycles[g]],1];
2644 newg = FromUnorderedPairs[pairs,Vertices[g]];
2645 rest = ToOrderedPairs[ GraphDifference[ g, newg ] ];
2646 cc = Sort[ConnectedComponents[newg], (Length[#1]>=Length[#2])&];
2647 c = First[cc];
2648 Do[
2649 e = Select[rest,(MemberQ[c,#[[1]]] &&
2650 MemberQ[cc[[i]],#[[2]]])&];
2651 rest = Complement[rest,e,Map[Reverse,e]];
2652 c = Union[c,cc[[i]]];
2653 pairs = Join[pairs, Prepend[ Rest[e],Reverse[e[[1]]] ] ],
2654 {i,2,Length[cc]}
2655 ];
2656 FromOrderedPairs[
2657 Join[pairs, Select[rest,(#[[1]] > #[[2]])&] ],
2658 Vertices[g]
2659 ]
2660 ] /; SameQ[Bridges[g],{}]
2661
2662FindBiconnectedComponents[g_Graph] :=
2663 Block[{e=ToAdjacencyLists[g],n=V[g],par,c=0,act={},back,dfs,ap=bcc={}},
2664 back=dfs=Table[0,{n}];
2665 par = Table[n+1,{n}];
2666 Map[(SearchBiConComp[First[#]])&, ConnectedComponents[g]];
2667 {bcc,Drop[ap, -1]}
2668 ]
2669
2670SearchBiConComp[v_Integer] :=
2671 Block[{r},
2672 back[[v]]=dfs[[v]]=++c;
2673 Scan[
2674 (If[ dfs[[#]] == 0,
2675 If[!MemberQ[act,{v,#}], PrependTo[act,{v,#}]];
2676 par[[#]] = v;
2677 SearchBiConComp[#];
2678 If[ back[[#]] >= dfs[[v]],
2679 {r} = Flatten[Position[act,{v,#}]];
2680 AppendTo[bcc,Union[Flatten[Take[act,r]]]];
2681 AppendTo[ap,v];
2682 act = Drop[act,r]
2683 ];
2684 back[[v]] = Min[ back[[v]],back[[#]] ],
2685 If[# != par[[v]],back[[v]]=Min[dfs[[#]],back[[v]]]]
2686 ])&,
2687 e[[v]]
2688 ];
2689 ]
2690
2691ArticulationVertices[g_Graph] := Union[Last[FindBiconnectedComponents[g]]];
2692
2693Bridges[g_Graph] := Select[BiconnectedComponents[g],(Length[#] == 2)&]
2694
2695BiconnectedComponents[g_Graph] := First[FindBiconnectedComponents[g]];
2696
2697BiconnectedQ[g_Graph] := Length[ BiconnectedComponents[g] ] == 1
2698
2699EdgeConnectivity[g_Graph] :=
2700 Module[{i},
2701 Apply[Min, Table[NetworkFlow[g,1,i], {i,2,V[g]}]]
2702 ]
2703
2704VertexConnectivityGraph[g_Graph] :=
2705 Module[{n=V[g],e},
2706 e=Table[0,{2 n},{2 n}];
2707 Scan[ (e[[#-1,#]] = 1)&, 2 Range[n] ];
2708 Scan[
2709 (e[[#[[1]], #[[2]]-1]] = e[[#[[2]],#[[1]]-1]] = Infinity)&,
2710 2 ToUnorderedPairs[g]
2711 ];
2712 Graph[e,Apply[Join,Map[({#,#})&,Vertices[g]]]]
2713 ]
2714
2715VertexConnectivity[g_Graph] :=
2716 Module[{p=VertexConnectivityGraph[g],k=V[g],i=0,notedges},
2717 notedges = ToUnorderedPairs[ GraphComplement[g] ];
2718 While[ i++ <= k,
2719 k = Min[
2720 Map[
2721 (NetworkFlow[p,2 #[[1]],2 #[[2]]-1])&,
2722 Select[notedges,(First[#]==i)&]
2723 ],
2724 k
2725 ]
2726 ];
2727 k
2728 ]
2729
2730Harary[k_?EvenQ, n_Integer] := CirculantGraph[n,Range[k/2]]
2731
2732Harary[k_?OddQ, n_?EvenQ] := CirculantGraph[n,Append[Range[k/2],n/2]]
2733
2734Harary[k_?OddQ, n_?OddQ] :=
2735 Module[{g=Harary[k-1,n],i},
2736 FromUnorderedPairs[
2737 Join[
2738 ToUnorderedPairs[g],
2739 { {1,(n+1)/2}, {1,(n+3)/2} },
2740 Table [ {i,i+(n+1)/2}, {i,2,(n-1)/2} ]
2741 ],
2742 Vertices[g]
2743 ]
2744 ]
2745
2746IdenticalQ[g_Graph,h_Graph] := Edges[g] === Edges[h]
2747
2748IsomorphismQ[g_Graph,h_Graph,p_List] := False /;
2749 (V[g]!=V[h]) || !PermutationQ[p] || (Length[p] != V[g])
2750
2751IsomorphismQ[g_Graph,h_Graph,p_List] := IdenticalQ[g, InduceSubgraph[h,p] ]
2752
2753Isomorphism[g_Graph,h_Graph,flag_:One] := {} /; (V[g] != V[h])
2754
2755Isomorphism[g_Graph,h_Graph,flag_:One] :=
2756 Module[{eg=Edges[g],eh=Edges[h],equiv=Equivalences[g,h]},
2757 If [!MemberQ[equiv,{}],
2758 Backtrack[
2759 equiv,
2760 (IdenticalQ[InduceSubgraph[g,Range[Length[#]]],
2761 InduceSubgraph[h,#] ] &&
2762 !MemberQ[Drop[#,-1],Last[#]])&,
2763 (IsomorphismQ[g,h,#])&,
2764 flag
2765 ],
2766 {}
2767 ]
2768 ]
2769
2770IsomorphicQ[g_Graph,h_Graph] := True /; IdenticalQ[g,h]
2771IsomorphicQ[g_Graph,h_Graph] := ! SameQ[ Isomorphism[g,h], {}]
2772
2773Equivalences[g_Graph,h_Graph] :=
2774 Equivalences[ AllPairsShortestPath[g], AllPairsShortestPath[h]]
2775
2776Equivalences[g_List,h_List] :=
2777 Module[{dg=Map[Sort,g],dh=Map[Sort,h],s,i},
2778 Table[
2779 Flatten[Position[dh,_?(Function[s,SameQ[s,dg[[i]] ]])]],
2780 {i,Length[dg]}
2781 ]
2782 ] /; Length[g] == Length[h]
2783
2784Automorphisms[g_Graph,flag_:All] :=
2785 Module[{s=AllPairsShortestPath[g]},
2786 Backtrack[
2787 Equivalences[s,s],
2788 (IdenticalQ[InduceSubgraph[g,Range[Length[#]]],
2789 InduceSubgraph[g,#] ] &&
2790 !MemberQ[Drop[#,-1],Last[#]])&,
2791 (IsomorphismQ[g,g,#])&,
2792 flag
2793 ]
2794 ]
2795
2796SelfComplementaryQ[g_Graph] := IsomorphicQ[g, GraphComplement[g]]
2797
2798FindCycle[g_Graph,flag_:Undirected] :=
2799 Module[{edge,n=V[g],x,queue,v,seen,parent},
2800 edge=ToAdjacencyLists[g];
2801 For[ v = 1, v <= n, v++,
2802 parent=Table[n+1,{n}]; parent[[v]] = 0;
2803 seen = {}; queue = {v};
2804 While[ queue != {},
2805 {x,queue} = {First[queue], Rest[queue]};
2806 AppendTo[seen,x];
2807 If[ SameQ[ flag, Undirected],
2808 Scan[ (If[ parent[[x]] != #, parent[[#]]=x])&, edge[[x]] ],
2809 Scan[ (parent[[#]]=x)&, edge[[x]]]
2810 ];
2811 If[ SameQ[flag,Undirected],
2812 If[ MemberQ[ edge[[x]],v ] && parent[[x]] != v,
2813 Return[ FromParent[parent,x] ]
2814 ],
2815 If[ MemberQ[ edge[[x]],v ],
2816 Return[ FromParent[parent,x] ]
2817 ]
2818 ];
2819 queue = Join[ Complement[ edge[[x]], seen], queue]
2820 ]
2821 ];
2822 {}
2823 ]
2824
2825FromParent[parent_List,s_Integer] :=
2826 Module[{i=s,lst={s}},
2827 While[!MemberQ[lst,(i=parent[[i]])], PrependTo[lst,i] ];
2828 PrependTo[lst,i];
2829 Take[lst, Flatten[Position[lst,i]]]
2830 ]
2831
2832AcyclicQ[g_Graph,flag_:Undirected] := SameQ[FindCycle[g,flag],{}]
2833
2834TreeQ[g_Graph] := ConnectedQ[g] && (M[g] == V[g]-1)
2835
2836ExtractCycles[gi_Graph,flag_:Undirected] :=
2837 Module[{g=gi,cycles={},c},
2838 While[!SameQ[{}, c=FindCycle[g,flag]],
2839 PrependTo[cycles,c];
2840 g = DeleteCycle[g,c,flag];
2841 ];
2842 cycles
2843 ]
2844
2845DeleteCycle[g_Graph,cycle_List,flag_:Undirected] :=
2846 Module[{newg=g},
2847 Scan[(newg=DeleteEdge[newg,#,flag])&, Partition[cycle,2,1] ];
2848 newg
2849 ]
2850
2851Girth[g_Graph] :=
2852 Module[{v,dist,queue,n=V[g],girth=Infinity,parent,e=ToAdjacencyLists[g],x},
2853 Do [
2854 dist = parent = Table[Infinity, {n}];
2855 dist[[v]] = parent[[v]] = 0;
2856 queue = {v};
2857 While [queue != {},
2858 {x,queue} = {First[queue],Rest[queue]};
2859 Scan[
2860 (If [ (dist[[#]]+dist[[x]]<girth) &&
2861 (parent[[x]] != #),
2862 girth=dist[[#]]+dist[[x]] + 1,
2863 If [dist[[#]]==Infinity,
2864 dist[[#]] = dist[[x]] + 1;
2865 parent[[#]] = x;
2866 If [2 dist[[#]] < girth-1,
2867 AppendTo[queue,#] ]
2868 ]])&,
2869 e[[ x ]]
2870 ];
2871 ],
2872 {v,n}
2873 ];
2874 girth
2875 ] /; SimpleQ[g]
2876
2877EulerianQ[g_Graph,Directed] :=
2878 ConnectedQ[g,Undirected] && (InDegree[g] === OutDegree[g])
2879
2880EulerianQ[g_Graph,flag_:Undirected] := ConnectedQ[g,Undirected] &&
2881 UndirectedQ[g] && Apply[And,Map[EvenQ,DegreeSequence[g]]]
2882
2883OutDegree[Graph[e_List,_],n_Integer] := Length[ Select[ e[[n]], (# != 0)& ] ]
2884OutDegree[g_Graph] := Map[ (OutDegree[g,#])&, Range[V[g]] ]
2885
2886InDegree[g_Graph,n_Integer] := OutDegree[ TransposeGraph[g], n ];
2887InDegree[g_Graph] := Map[ (InDegree[g,#])&, Range[V[g]] ]
2888
2889TransposeGraph[Graph[g_List,v_List]] := Graph[ Transpose[g], v ]
2890
2891EulerianCycle[g_Graph,flag_:Undirected] :=
2892 Module[{euler,c,cycles,v},
2893 cycles = Map[(Drop[#,-1])&, ExtractCycles[g,flag]];
2894 {euler, cycles} = {First[cycles], Rest[cycles]};
2895 Do [
2896 c = First[ Select[cycles, (Intersection[euler,#]=!={})&] ];
2897 v = First[Intersection[euler,c]];
2898 euler = Join[
2899 RotateLeft[c, Position[c,v] [[1,1]] ],
2900 RotateLeft[euler, Position[euler,v] [[1,1]] ]
2901 ];
2902 cycles = Complement[cycles,{c}],
2903 {Length[cycles]}
2904 ];
2905 Append[euler, First[euler]]
2906 ] /; EulerianQ[g,flag]
2907
2908DeBruijnSequence[alph_List,n_Integer] :=
2909 Module[{states = Strings[alph,n-1]},
2910 Rest[ Map[
2911 (First[ states[[#]] ])&,
2912 EulerianCycle[
2913 MakeGraph[
2914 states,
2915 (Module[{i},
2916 MemberQ[
2917 Table[
2918 Append[Rest[#1],alph[[i]]],
2919 {i,Length[alph]}
2920 ],
2921 #2
2922 ]
2923 ])&
2924 ],
2925 Directed
2926 ]
2927 ] ]
2928 ] /; n>=2
2929
2930DeBruijnSequence[alph_List,n_Integer] := alph /; n==1
2931
2932HamiltonianQ[g_Graph] := False /; !BiconnectedQ[g]
2933HamiltonianQ[g_Graph] := HamiltonianCycle[g] != {}
2934
2935HamiltonianCycle[g_Graph,flag_:One] :=
2936 Module[{s={1},all={},done,adj=Edges[g],e=ToAdjacencyLists[g],x,v,ind,n=V[g]},
2937 ind=Table[1,{n}];
2938 While[ Length[s] > 0,
2939 v = Last[s];
2940 done = False;
2941 While[ ind[[v]] <= Length[e[[v]]] && !done,
2942 If[!MemberQ[s,(x = e[[v,ind[[v]]++]])], done=True]
2943 ];
2944 If[ done, AppendTo[s,x], s=Drop[s,-1]; ind[[v]] = 1];
2945 If[(Length[s] == n),
2946 If [(adj[[x,1]]>0),
2947 AppendTo[all,Append[s,First[s]]];
2948 If [SameQ[flag,All],
2949 s=Drop[s,-1],
2950 all = Flatten[all]; s={}
2951 ],
2952 s = Drop[s,-1]
2953 ]
2954 ]
2955 ];
2956 all
2957 ]
2958
2959TravelingSalesman[g_Graph] :=
2960 Module[{v,s={1},sol={},done,cost,g1,e=ToAdjacencyLists[g],x,ind,best,n=V[g]},
2961 ind=Table[1,{n}];
2962 g1 = PathConditionGraph[g];
2963 best = Infinity;
2964 While[ Length[s] > 0,
2965 v = Last[s];
2966 done = False;
2967 While[ ind[[v]] <= Length[e[[v]]] && !done,
2968 x = e[[v,ind[[v]]++]];
2969 done = (best > CostOfPath[g1,Append[s,x]]) &&
2970 !MemberQ[s,x]
2971 ];
2972 If[done, AppendTo[s,x], s=Drop[s,-1]; ind[[v]] = 1];
2973 If[(Length[s] == n),
2974 cost = CostOfPath[g1, Append[s,First[s]]];
2975 If [(cost < best), sol = s; best = cost ];
2976 s = Drop[s,-1]
2977 ]
2978 ];
2979 Append[sol,First[sol]]
2980 ]
2981
2982CostOfPath[Graph[g_,_],p_List] := Apply[Plus, Map[(Element[g,#])&,Partition[p,2,1]] ]
2983
2984Element[a_List,{index___}] := a[[ index ]]
2985
2986TriangleInequalityQ[e_?SquareMatrixQ] :=
2987 Module[{i,j,k,n=Length[e],flag=True},
2988 Do [
2989
2990 If[(e[[i,k]]!=0) && (e[[k,j]]!=0) && (e[[i,j]]!=0),
2991 If[e[[i,k]]+e[[k,j]]<e[[i,j]],
2992 flag = False;
2993 ]
2994 ],
2995 {i,n},{j,n},{k,n}
2996 ];
2997 flag
2998 ]
2999
3000TriangleInequalityQ[g_Graph] := TriangleInequalityQ[Edges[g]]
3001
3002TravelingSalesmanBounds[g_Graph] := {LowerBoundTSP[g], UpperBoundTSP[g]}
3003
3004UpperBoundTSP[g_Graph] :=
3005 CostOfPath[g, Append[DepthFirstTraversal[MinimumSpanningTree[g],1],1]]
3006
3007LowerBoundTSP[g_Graph] := Apply[Plus, Map[Min,ReplaceAll[Edges[g],0->Infinity]]]
3008
3009PartialOrderQ[g_Graph] := ReflexiveQ[g] && AntiSymmetricQ[g] && TransitiveQ[g]
3010
3011TransitiveQ[g_Graph] := IdenticalQ[g,TransitiveClosure[g]]
3012
3013ReflexiveQ[Graph[g_List,_]] :=
3014 Module[{i},
3015 Apply[And, Table[(g[[i,i]]!=0),{i,Length[g]}] ]
3016 ]
3017
3018AntiSymmetricQ[g_Graph] :=
3019 Module[{e = Edges[g], g1 = RemoveSelfLoops[g]},
3020 Apply[And, Map[(Element[e,Reverse[#]]==0)&,ToOrderedPairs[g1]] ]
3021 ]
3022
3023TransitiveClosure[g_Graph] :=
3024 Module[{i,j,k,e=Edges[g],n=V[g]},
3025 Do [
3026 If[ e[[j,i]] != 0,
3027 Do [
3028 If[ e[[i,k]] != 0, e[[j,k]]=1],
3029 {k,n}
3030 ]
3031 ],
3032 {i,n},{j,n}
3033 ];
3034 Graph[e,Vertices[g]]
3035 ]
3036
3037TransitiveReduction[g_Graph] :=
3038 Module[{closure=reduction=Edges[g],i,j,k,n=V[g]},
3039 Do[
3040 If[ closure[[i,j]]!=0 && closure[[j,k]]!=0 &&
3041 reduction[[i,k]]!=0 && (i!=j) && (j!=k) && (i!=k),
3042 reduction[[i,k]] = 0
3043 ],
3044 {i,n},{j,n},{k,n}
3045 ];
3046 Graph[reduction,Vertices[g]]
3047 ] /; AcyclicQ[RemoveSelfLoops[g],Directed]
3048
3049TransitiveReduction[g_Graph] :=
3050 Module[{reduction=Edges[g],i,j,k,n=V[g]},
3051 Do[
3052 If[ reduction[[i,j]]!=0 && reduction[[j,k]]!=0 &&
3053 reduction[[i,k]]!=0 && (i!=j) && (j!=k) && (i!=k),
3054 reduction[[i,k]] = 0
3055 ],
3056 {i,n},{j,n},{k,n}
3057 ];
3058 Graph[reduction,Vertices[g]]
3059 ]
3060
3061HasseDiagram[g_Graph] :=
3062 Module[{r,rank,m,stages,freq=Table[0,{V[g]}]},
3063 r = TransitiveReduction[ RemoveSelfLoops[g] ];
3064 rank = RankGraph[
3065 MakeUndirected[r],
3066 Select[Range[V[g]],(InDegree[r,#]==0)&]
3067 ];
3068 m = Max[rank];
3069 rank = MapAt[(m)&,rank,Position[OutDegree[r],0]];
3070 stages = Distribution[ rank ];
3071 Graph[
3072 Edges[r],
3073 Table[
3074 m = ++ freq[[ rank[[i]] ]];
3075 {(m-1) + (1-stages[[rank[[i]] ]])/2, rank[[i]]},
3076 {i,V[g]}
3077 ]
3078 ]
3079 ] /; AcyclicQ[RemoveSelfLoops[g],Directed]
3080
3081TopologicalSort[g_Graph] :=
3082 Module[{g1 = RemoveSelfLoops[g],e,indeg,zeros,v},
3083 e=ToAdjacencyLists[g1];
3084 indeg=InDegree[g1];
3085 zeros = Flatten[ Position[indeg, 0] ];
3086 Table [
3087 {v,zeros}={First[zeros],Rest[zeros]};
3088 Scan[
3089 ( indeg[[#]]--;
3090 If[indeg[[#]]==0, AppendTo[zeros,#]] )&,
3091 e[[ v ]]
3092 ];
3093 v,
3094 {V[g]}
3095 ]
3096 ] /; AcyclicQ[RemoveSelfLoops[g],Directed]
3097
3098ChromaticPolynomial[g_Graph,z_] := 0 /; Identical[g,K[0]]
3099
3100ChromaticPolynomial[g_Graph,z_] :=
3101 Module[{i}, Product[z-i, {i,0,V[g]-1}] ] /; CompleteQ[g]
3102
3103ChromaticPolynomial[g_Graph,z_] := z ( z - 1 ) ^ (V[g]-1) /; TreeQ[g]
3104
3105ChromaticPolynomial[g_Graph,z_] :=
3106 If [M[g]>Binomial[V[g],2]/2, ChromaticDense[g,z], ChromaticSparse[g,z]]
3107
3108ChromaticSparse[g_Graph,z_] := z^V[g] /; EmptyQ[g]
3109ChromaticSparse[g_Graph,z_] :=
3110 Module[{i=1, v, e=Edges[g], none=Table[0,{V[g]}]},
3111 While[e[[i]] === none, i++];
3112 v = Position[e[[i]],1] [[1,1]];
3113 ChromaticSparse[ DeleteEdge[g,{i,v}], z ] -
3114 ChromaticSparse[ Contract[g,{i,v}], z ]
3115 ]
3116
3117ChromaticDense[g_Graph,z_] := ChromaticPolynomial[g,z] /; CompleteQ[g]
3118ChromaticDense[g_Graph,z_] :=
3119 Module[
3120 {i=1, v, e=Edges[g], all=Join[Table[1,{V[g]-1}],{0}] },
3121 While[e[[i]] === RotateRight[all,i], i++];
3122 v = Last[ Position[e[[i]],0] ] [[1]];
3123 ChromaticDense[ AddEdge[g,{i,v}], z ] +
3124 ChromaticDense[ Contract[g,{i,v}], z ]
3125 ]
3126
3127ChromaticNumber[g_Graph] :=
3128 Block[{ways, z},
3129 ways[z_] = ChromaticPolynomial[g,z];
3130 For [z=0, z<=V[g], z++,
3131 If [ways[z] > 0, Return[z]]
3132 ]
3133 ]
3134
3135TwoColoring[g_Graph] :=
3136 Module[{queue,elem,edges,col,flag=True,colored=Table[0,{V[g]}]},
3137 edges = ToAdjacencyLists[g];
3138 While[ MemberQ[colored,0],
3139 queue = First[ Position[colored,0] ];
3140 colored[[ First[queue] ]] = 1;
3141 While[ queue != {},
3142 elem = First[queue];
3143 col = colored[[elem]];
3144 Scan[
3145 (Switch[colored[[ # ]],
3146 col, flag = False,
3147 0, AppendTo[queue, # ];
3148 colored[[#]] = Mod[col,2]+1
3149 ])&,
3150 edges[[elem]]
3151 ];
3152 queue = Rest[queue];
3153 ]
3154 ];
3155 If [!flag, colored[[1]] = 0];
3156 colored
3157 ]
3158
3159BipartiteQ[g_Graph] := ! MemberQ[ TwoColoring[g], 0 ]
3160
3161VertexColoring[g_Graph] :=
3162 Module[{v,l,n=V[g],e=ToAdjacencyLists[g],x,color=Table[0,{V[g]}]},
3163 v = Map[(Apply[Plus,#])&, Edges[g]];
3164 Do[
3165 l = MaximumColorDegreeVertices[e,color];
3166 x = First[l];
3167 Scan[(If[ v[[#]] > v[[x]], x = #])&, l];
3168 color[[x]] = Min[
3169 Complement[ Range[n], color[[ e[[x]] ]] ]
3170 ],
3171 {V[g]}
3172 ];
3173 color
3174 ]
3175
3176MaximumColorDegreeVertices[e_List,color_List] :=
3177 Module[{n=Length[color],l,i,x},
3178 l = Table[ Count[e[[i]], _?(Function[x,color[[x]]!=0])], {i,n}];
3179 Do [
3180 If [color[[i]]!=0, l[[i]] = -1],
3181 {i,n}
3182 ];
3183 Flatten[ Position[ l, Max[l] ] ]
3184 ]
3185
3186EdgeColoring[g_Graph] := VertexColoring[ LineGraph[g] ]
3187
3188EdgeChromaticNumber[g_Graph] := ChromaticNumber[ LineGraph[g] ]
3189
3190CliqueQ[g_Graph,clique_List] :=
3191 IdenticalQ[ K[Length[clique]], InduceSubgraph[g,clique] ] /; SimpleQ[g]
3192
3193MaximumClique[g_Graph] := {} /; g === K[0]
3194
3195MaximumClique[g_Graph] :=
3196 Module[{d = Degrees[g],i,clique=Null,k},
3197 i = Max[d];
3198 While[(SameQ[clique,Null]),
3199 k = K[i+1];
3200 clique = FirstExample[
3201 KSubsets[Flatten[Position[d,_?((#>=i)&)]], i+1],
3202 (IdenticalQ[k,InduceSubgraph[g,#]])&
3203 ];
3204 i--;
3205 ];
3206 clique
3207 ]
3208
3209FirstExample[list_List, predicate_] := Scan[(If [predicate[#],Return[#]])&,list]
3210
3211VertexCoverQ[g_Graph,vc_List] :=
3212 CliqueQ[ GraphComplement[g], Complement[Range[V[g]], vc] ]
3213
3214MinimumVertexCover[g_Graph] :=
3215 Complement[ Range[V[g]], MaximumClique[ GraphComplement[g] ] ]
3216
3217IndependentSetQ[g_Graph,indep_List] :=
3218 VertexCoverQ[ g, Complement[ Range[V[g]], indep] ]
3219
3220MaximumIndependentSet[g_Graph] := Complement[Range[V[g]], MinimumVertexCover[g]]
3221
3222PerfectQ[g_Graph] :=
3223 Apply[
3224 And,
3225 Map[(ChromaticNumber[#] == Length[MaximumClique[#]])&,
3226 Map[(InduceSubgraph[g,#])&, Subsets[Range[V[g]]] ] ]
3227 ]
3228
3229Dijkstra[g_Graph,start_Integer] := First[ Dijkstra[g,{start}] ]
3230
3231Dijkstra[g_Graph, l_List] :=
3232 Module[{x,start,e=ToAdjacencyLists[g],i,p,parent,untraversed},
3233 p=Edges[PathConditionGraph[g]];
3234 Table[
3235 start = l[[i]];
3236 parent=untraversed=Range[V[g]];
3237 dist = p[[start]]; dist[[start]] = 0;
3238 Scan[ (parent[[#]] = start)&, e[[start]] ];
3239 While[ untraversed != {} ,
3240 x = First[untraversed];
3241 Scan[(If [dist[[#]]<dist[[x]],x=#])&, untraversed];
3242 untraversed = Complement[untraversed,{x}];
3243 Scan[
3244 (If[dist[[#]] > dist[[x]]+p[[x,#]],
3245 dist[[#]] = dist[[x]]+p[[x,#]];
3246 parent[[#]] = x ])&,
3247 e[[x]]
3248 ];
3249 ];
3250 {parent, dist},
3251 {i,Length[l]}
3252 ]
3253 ]
3254
3255ShortestPath[g_Graph,s_Integer,e_Integer] :=
3256 Module[{parent=First[Dijkstra[g,s]],i=e,lst={e}},
3257 While[ (i != s) && (i != parent[[i]]),
3258 PrependTo[lst,parent[[i]]];
3259 i = parent[[i]]
3260 ];
3261 If[ i == s, lst, {}]
3262 ]
3263
3264ShortestPathSpanningTree[g_Graph,s_Integer] :=
3265 Module[{parent=First[Dijkstra[g,s]],i},
3266 FromUnorderedPairs[
3267 Map[({#,parent[[#]]})&, Complement[Range[V[g]],{s}]],
3268 Vertices[g]
3269 ]
3270 ]
3271
3272AllPairsShortestPath[g_Graph] :=
3273 Module[{p=Edges[ PathConditionGraph[g] ],i,j,k,n=V[g]},
3274 Do [
3275 p = Table[Min[p[[i,k]]+p[[k,j]],p[[i,j]]],{i,n},{j,n}],
3276 {k,n}
3277 ];
3278 p
3279 ] /; Min[Edges[g]] < 0
3280
3281AllPairsShortestPath[g_Graph] := Map[ Last, Dijkstra[g, Range[V[g]]]]
3282
3283PathConditionGraph[Graph[e_,v_]] := RemoveSelfLoops[Graph[ReplaceAll[e,0->Infinity],v]]
3284
3285GraphPower[g_Graph,1] := g
3286
3287GraphPower[g_Graph,n_Integer] :=
3288 Module[{prod=power=p=Edges[g]},
3289 Do [
3290 prod = prod . p;
3291 power = prod + power,
3292 {n-1}
3293 ];
3294 Graph[power, Vertices[g]]
3295 ]
3296
3297InitializeUnionFind[n_Integer] := Module[{i}, Table[{i,1},{i,n}] ]
3298
3299FindSet[n_Integer,s_List] := If [n == s[[n,1]], n, FindSet[s[[n,1]],s] ]
3300
3301UnionSet[a_Integer,b_Integer,s_List] :=
3302 Module[{sa=FindSet[a,s], sb=FindSet[b,s], set=s},
3303 If[ set[[sa,2]] < set[[sb,2]], {sa,sb} = {sb,sa} ];
3304 set[[sa]] = {sa, Max[ set[[sa,2]], set[[sb,2]]+1 ]};
3305 set[[sb]] = {sa, set[[sb,2]]};
3306 set
3307 ]
3308
3309MinimumSpanningTree[g_Graph] :=
3310 Module[{edges=Edges[g],set=InitializeUnionFind[V[g]]},
3311 FromUnorderedPairs[
3312 Select [
3313 Sort[
3314 ToUnorderedPairs[g],
3315 (Element[edges,#1]<=Element[edges,#2])&
3316 ],
3317 (If [FindSet[#[[1]],set] != FindSet[#[[2]],set],
3318 set=UnionSet[#[[1]],#[[2]],set]; True,
3319 False
3320 ])&
3321 ],
3322 Vertices[g]
3323 ]
3324 ] /; UndirectedQ[g]
3325
3326MaximumSpanningTree[g_Graph] := MinimumSpanningTree[Graph[-Edges[g],Vertices[g]]]
3327
3328Cofactor[m_List,{i_Integer,j_Integer}] :=
3329 (-1)^(i+j) * Det[ Drop[ Transpose[ Drop[Transpose[m],{j,j}] ], {i,i}] ]
3330
3331NumberOfSpanningTrees[Graph[g_List,_]] :=
3332 Cofactor[ DiagonalMatrix[Map[(Apply[Plus,#])&,g]] - g, {1,1}]
3333
3334NetworkFlow[g_Graph,source_Integer,sink_Integer] :=
3335 Block[{flow=NetworkFlowEdges[g,source,sink], i},
3336 Sum[flow[[i,sink]], {i,V[g]}]
3337 ]
3338
3339
3340NetworkFlowEdges[g_Graph,source_Integer,sink_Integer] :=
3341 Block[{e=Edges[g], x, y, flow=Table[0,{V[g]},{V[g]}], p, m},
3342 While[ !SameQ[p=AugmentingPath[g,source,sink], {}],
3343 m = Min[Map[({x,y}=#[[1]];
3344 If[SameQ[#[[2]],f],e[[x,y]]-flow[[x,y]],
3345 flow[[x,y]]])&,p]];
3346 Scan[
3347 ({x,y}=#[[1]];
3348 If[ SameQ[#[[2]],f],
3349 flow[[x,y]]+=m,flow[[x,y]]-=m])&,
3350 p
3351 ]
3352 ];
3353 flow
3354 ]
3355
3356AugmentingPath[g_Graph,src_Integer,sink_Integer] :=
3357 Block[{l={src},lab=Table[0,{V[g]}],v,c=Edges[g],e=ToAdjacencyLists[g]},
3358 lab[[src]] = start;
3359 While[l != {} && (lab[[sink]]==0),
3360 {v,l} = {First[l],Rest[l]};
3361 Scan[ (If[ c[[v,#]] - flow[[v,#]] > 0 && lab[[#]] == 0,
3362 lab[[#]] = {v,f}; AppendTo[l,#]])&,
3363 e[[v]]
3364 ];
3365 Scan[ (If[ flow[[#,v]] > 0 && lab[[#]] == 0,
3366 lab[[#]] = {v,b}; AppendTo[l,#]] )&,
3367 Select[Range[V[g]],(c[[#,v]] > 0)&]
3368 ];
3369 ];
3370 FindPath[lab,src,sink]
3371 ]
3372
3373FindPath[l_List,v1_Integer,v2_Integer] :=
3374 Block[{x=l[[v2]],y,z=v2,lst={}},
3375 If[SameQ[x,0], Return[{}]];
3376 While[!SameQ[x, start],
3377 If[ SameQ[x[[2]],f],
3378 PrependTo[lst,{{ x[[1]], z }, f}],
3379 PrependTo[lst,{{ z, x[[1]] }, b}]
3380 ];
3381 z = x[[1]]; x = l[[z]];
3382 ];
3383 lst
3384 ]
3385
3386BipartiteMatching[g_Graph] :=
3387 Module[{p,v1,v2,coloring=TwoColoring[g],n=V[g]},
3388 v1 = Flatten[Position[coloring,1]];
3389 v2 = Flatten[Position[coloring,2]];
3390 p = BipartiteMatchingFlowGraph[g,v1,v2];
3391 flow = NetworkFlowEdges[p,V[g]+1,V[g]+2];
3392 Select[ToOrderedPairs[Graph[flow,Vertices[p]]], (Max[#]<=n)&]
3393 ] /; BipartiteQ[g]
3394
3395BipartiteMatchingFlowGraph[g_Graph,v1_List,v2_List] :=
3396 Module[{edges = Table[0,{V[g]+2},{V[g]+2}],i,e=ToAdjacencyLists[g]},
3397 Do[
3398 Scan[ (edges[[v1[[i]],#]] = 1)&, e[[ v1[[i]] ]] ],
3399 {i,Length[v1]}
3400 ];
3401 Scan[(edges[[V[g] + 1, #]] = 1)&, v1];
3402 Scan[(edges[[#, V[g] + 2]] = 1)&, v2];
3403 Graph[edges,RandomVertices[V[g] + 2] ]
3404 ]
3405
3406MinimumChainPartition[g_Graph] :=
3407 ConnectedComponents[
3408 FromUnorderedPairs[
3409 Map[(#-{0,V[g]})&, BipartiteMatching[DilworthGraph[g]]],
3410 Vertices[g]
3411 ]
3412 ]
3413
3414MaximumAntichain[g_Graph] := MaximumIndependentSet[TransitiveClosure[g]]
3415
3416DilworthGraph[g_Graph] :=
3417 FromUnorderedPairs[
3418 Map[
3419 (#+{0,V[g]})&,
3420 ToOrderedPairs[RemoveSelfLoops[TransitiveReduction[g]]]
3421 ]
3422 ]
3423
3424MaximalMatching[g_Graph] :=
3425 Module[{match={}},
3426 Scan[
3427 (If [Intersection[#,match]=={}, match=Join[match,#]])&,
3428 ToUnorderedPairs[g]
3429 ];
3430 Partition[match,2]
3431 ]
3432
3433StableMarriage[mpref_List,fpref_List] :=
3434 Module[{n=Length[mpref],freemen,cur,i,w,husband},
3435 freemen = Range[n];
3436 cur = Table[1,{n}];
3437 husband = Table[n+1,{n}];
3438 While[ freemen != {},
3439 {i,freemen}={First[freemen],Rest[freemen]};
3440 w = mpref[[ i,cur[[i]] ]];
3441 If[BeforeQ[ fpref[[w]], i, husband[[w]] ],
3442 If[husband[[w]] != n+1,
3443 AppendTo[freemen,husband[[w]] ]
3444 ];
3445 husband[[w]] = i,
3446 cur[[i]]++;
3447 AppendTo[freemen,i]
3448 ];
3449 ];
3450 InversePermutation[ husband ]
3451 ] /; Length[mpref] == Length[fpref]
3452
3453BeforeQ[l_List,a_,b_] :=
3454 If [First[l]==a, True, If [First[l]==b, False, BeforeQ[Rest[l],a,b] ] ]
3455
3456PlanarQ[g_Graph] :=
3457 Apply[
3458 And,
3459 Map[(PlanarQ[InduceSubgraph[g,#]])&, ConnectedComponents[g]]
3460 ] /; !ConnectedQ[g]
3461
3462PlanarQ[g_Graph] := False /; (M[g] > 3 V[g]-6) && (V[g] > 2)
3463PlanarQ[g_Graph] := True /; (M[g] < V[g] + 3)
3464PlanarQ[g_Graph] := PlanarGivenCycle[ g, Rest[FindCycle[g]] ]
3465
3466PlanarGivenCycle[g_Graph, cycle_List] :=
3467 Module[{b, j, i},
3468 {b, j} = FindBridge[g, cycle];
3469 If[ InterlockQ[j, cycle],
3470 False,
3471 Apply[And, Table[SingleBridgeQ[b[[i]],j[[i]]], {i,Length[b]}]]
3472 ]
3473 ]
3474
3475SingleBridgeQ[b_Graph, {_}] := PlanarQ[b]
3476
3477SingleBridgeQ[b_Graph, j_List] :=
3478 PlanarGivenCycle[ JoinCycle[b,j],
3479 Join[ ShortestPath[b,j[[1]],j[[2]]], Drop[j,2]] ]
3480
3481JoinCycle[g1_Graph, cycle_List] :=
3482 Module[{g=g1},
3483 Scan[(g = AddEdge[g,#])&, Partition[cycle,2,1] ];
3484 AddEdge[g,{First[cycle],Last[cycle]}]
3485 ]
3486
3487FindBridge[g_Graph, cycle_List] :=
3488 Module[{rg = RemoveCycleEdges[g, cycle], b, bridge, j},
3489 b = Map[
3490 (IsolateSubgraph[rg,g,cycle,#])&,
3491 Select[ConnectedComponents[rg], (Intersection[#,cycle]=={})&]
3492 ];
3493 b = Select[b, (!EmptyQ[#])&];
3494 j = Join[
3495 Map[Function[bridge,Select[cycle, MemberQ[Edges[bridge][[#]],1]&] ], b],
3496 Complement[
3497 Select[ToOrderedPairs[g],
3498 (Length[Intersection[#,cycle]] == 2)&],
3499 Partition[Append[cycle,First[cycle]],2,1]
3500 ]
3501 ];
3502 {b, j}
3503 ]
3504
3505RemoveCycleEdges[g_Graph, c_List] :=
3506 FromOrderedPairs[
3507 Select[ ToOrderedPairs[g], (Intersection[c,#] === {})&],
3508 Vertices[g]
3509 ]
3510
3511IsolateSubgraph[g_Graph,orig_Graph,cycle_List,cc_List] :=
3512 Module[{eg=ToOrderedPairs[g], og=ToOrderedPairs[orig]},
3513 FromOrderedPairs[
3514 Join[
3515 Select[eg, (Length[Intersection[cc,#]] == 2)&],
3516 Select[og, (Intersection[#,cycle]!={} &&
3517 Intersection[#,cc]!={})&]
3518 ],
3519 Vertices[g]
3520 ]
3521 ]
3522
3523InterlockQ[ bl_List, c_List ] :=
3524 Module[{in = out = {}, code, jp, bridgelist = bl },
3525 While [ bridgelist != {},
3526 {jp, bridgelist} = {First[bridgelist],Rest[bridgelist]};
3527 code = Sort[ Map[(Position[c, #][[1,1]])&, jp] ];
3528 If[ Apply[ Or, Map[(LockQ[#,code])&, in] ],
3529 If [ Apply[Or, Map[(LockQ[#,code])&, out] ],
3530 Return[True],
3531 AppendTo[out,code]
3532 ],
3533 AppendTo[in,code]
3534 ]
3535 ];
3536 False
3537 ]
3538
3539LockQ[a_List,b_List] := Lock1Q[a,b] || Lock1Q[b,a]
3540
3541Lock1Q[a_List,b_List] :=
3542 Module[{bk, aj},
3543 bk = Min[ Select[Drop[b,-1], (#>First[a])&] ];
3544 aj = Min[ Select[a, (# > bk)&] ];
3545 (aj < Max[b])
3546 ]
3547
3548End[]
3549
3550Protect[
3551AcyclicQ,
3552AddEdge,
3553AddVertex,
3554AllPairsShortestPath,
3555ArticulationVertices,
3556Automorphisms,
3557Backtrack,
3558BiconnectedComponents,
3559BiconnectedComponents,
3560BiconnectedQ,
3561BinarySearch,
3562BinarySubsets,
3563BipartiteMatching,
3564BipartiteQ,
3565BreadthFirstTraversal,
3566Bridges,
3567CartesianProduct,
3568CatalanNumber,
3569ChangeEdges,
3570ChangeVertices,
3571ChromaticNumber,
3572ChromaticPolynomial,
3573CirculantGraph,
3574CircularVertices,
3575CliqueQ,
3576CodeToLabeledTree,
3577Cofactor,
3578CompleteQ,
3579Compositions,
3580ConnectedComponents,
3581ConnectedQ,
3582ConstructTableau,
3583Contract,
3584CostOfPath,
3585Cycle,
3586DeBruijnSequence,
3587DegreeSequence,
3588DeleteCycle,
3589DeleteEdge,
3590DeleteFromTableau,
3591DeleteVertex,
3592DepthFirstTraversal,
3593DerangementQ,
3594Derangements,
3595Diameter,
3596Dijkstra,
3597DilateVertices,
3598DistinctPermutations,
3599Distribution,
3600DurfeeSquare,
3601Eccentricity,
3602EdgeChromaticNumber,
3603EdgeColoring,
3604EdgeConnectivity,
3605Edges,
3606Element,
3607EmptyGraph,
3608EmptyQ,
3609EncroachingListSet,
3610EquivalenceClasses,
3611EquivalenceRelationQ,
3612Equivalences,
3613EulerianCycle,
3614EulerianQ,
3615Eulerian,
3616ExactRandomGraph,
3617ExpandGraph,
3618ExtractCycles,
3619FerrersDiagram,
3620FindCycle,
3621FindSet,
3622FirstLexicographicTableau,
3623FromAdjacencyLists,
3624FromCycles,
3625FromInversionVector,
3626FromOrderedPairs,
3627FromUnorderedPairs,
3628FromOrderedTriples,
3629FromUnorderedTriples,
3630FunctionalGraph,
3631Girth,
3632GraphCenter,
3633GraphComplement,
3634GraphDifference,
3635GraphIntersection,
3636GraphJoin,
3637GraphPower,
3638GraphProduct,
3639GraphSum,
3640GraphUnion,
3641GraphicQ,
3642GrayCode,
3643GridGraph,
3644HamiltonianCycle,
3645HamiltonianQ,
3646Harary,
3647HasseDiagram,
3648HeapSort,
3649Heapify,
3650HideCycles,
3651Hypercube,
3652IdenticalQ,
3653IncidenceMatrix,
3654IndependentSetQ,
3655Index,
3656InduceSubgraph,
3657InitializeUnionFind,
3658InsertIntoTableau,
3659IntervalGraph,
3660InversePermutation,
3661Inversions,
3662InvolutionQ,
3663IsomorphicQ,
3664IsomorphismQ,
3665Isomorphism,
3666Josephus,
3667KSubsets,
3668K,
3669LabeledTreeToCode,
3670LastLexicographicTableau,
3671LexicographicPermutations,
3672LexicographicSubsets,
3673LineGraph,
3674LongestIncreasingSubsequence,
3675M,
3676MakeGraph,
3677MakeSimple,
3678MakeUndirected,
3679MaximalMatching,
3680MaximumAntichain,
3681MaximumClique,
3682MaximumIndependentSet,
3683MaximumSpanningTree,
3684MinimumChainPartition,
3685MinimumChangePermutations,
3686MinimumSpanningTree,
3687MinimumVertexCover,
3688MultiplicationTable,
3689NetworkFlowEdges,
3690NetworkFlow,
3691NextComposition,
3692NextKSubset,
3693NextPartition,
3694NextPermutation,
3695NextSubset,
3696NextTableau,
3697NormalizeVertices,
3698NthPair,
3699NthPermutation,
3700NthSubset,
3701NumberOfCompositions,
3702NumberOfDerangements,
3703NumberOfInvolutions,
3704NumberOfPartitions,
3705NumberOfPermutationsByCycles,
3706NumberOfSpanningTrees,
3707NumberOfTableaux,
3708OrientGraph,
3709PartialOrderQ,
3710PartitionQ,
3711Partitions,
3712PathConditionGraph,
3713Path,
3714PerfectQ,
3715PermutationGroupQ,
3716PermutationQ,
3717Permute,
3718PlanarQ,
3719PointsAndLines,
3720Polya,
3721PseudographQ,
3722RadialEmbedding,
3723Radius,
3724RandomComposition,
3725RandomGraph,
3726RandomHeap,
3727RandomKSubset,
3728RandomPartition,
3729RandomPermutation1,
3730RandomPermutation2,
3731RandomPermutation,
3732RandomSubset,
3733RandomTableau,
3734RandomTree,
3735RandomVertices,
3736RankGraph,
3737RankPermutation,
3738RankSubset,
3739RankedEmbedding,
3740ReadGraph,
3741RealizeDegreeSequence,
3742RegularGraph,
3743RegularQ,
3744RemoveSelfLoops,
3745RevealCycles,
3746RootedEmbedding,
3747RotateVertices,
3748Runs,
3749SamenessRelation,
3750SelectionSort,
3751SelfComplementaryQ,
3752ShakeGraph,
3753ShortestPathSpanningTree,
3754ShortestPath,
3755ShowGraph,
3756ShowLabeledGraph,
3757ShowWeightedGraph,
3758ShowWeightedLabeledGraph,
3759SignaturePermutation,
3760SimpleQ,
3761Spectrum,
3762SpringEmbedding,
3763SpringEmbeddingDirected,
3764StableMarriage,
3765Star,
3766StirlingFirst,
3767StirlingSecond,
3768Strings,
3769StronglyConnectedComponents,
3770Subsets,
3771TableauClasses,
3772TableauQ,
3773TableauxToPermutation,
3774Tableaux,
3775ToAdjacencyLists,
3776ToCycles,
3777ToInversionVector,
3778ToOrderedPairs,
3779ToUnorderedPairs,
3780ToOrderedTriples,
3781TopologicalSort,
3782TransitiveClosure,
3783TransitiveQ,
3784TransitiveReduction,
3785TranslateVertices,
3786TransposePartition,
3787TransposeTableau,
3788TravelingSalesmanBounds,
3789TravelingSalesman,
3790TreeQ,
3791TriangleInequalityQ,
3792Turan,
3793TwoColoring,
3794UndirectedQ,
3795UnionSet,
3796UnweightedQ,
3797V,
3798VertexColoring,
3799VertexConnectivity,
3800VertexCoverQ,
3801Vertices,
3802WeaklyConnectedComponents,
3803Wheel,
3804WriteGraph,
3805DilworthGraph ]
3806
3807EndPackage[ ]