1 | initial version |
If i correctly figure out what is needed, then the following code should solve the problem (to some percentage):
def f(n):
"""https://ask.sagemath.org/question/38865/
obtaining-all-posets-in-a-certain-form-with-sage/
"""
R = range(n)
posets = [ p for p in Posets(n) if p.is_connected() ]
variables = [ "x%s" % (k+1) for k in R ]
result = []
for p in posets:
A = p.hasse_diagram().adjacency_matrix()
result.append( [ variables
, [ [ variables[j], variables[k] ]
for j in R for k in R
if A[j,k]
] ] )
return result
Example of usage in the sage interpreter:
sage: f(4)
[[['x1', 'x2', 'x3', 'x4'], [['x1', 'x2'], ['x1', 'x3'], ['x1', 'x4']]],
[['x1', 'x2', 'x3', 'x4'], [['x1', 'x2'], ['x1', 'x4'], ['x2', 'x3']]],
[['x1', 'x2', 'x3', 'x4'],
[['x1', 'x2'], ['x1', 'x3'], ['x2', 'x4'], ['x3', 'x4']]],
[['x1', 'x2', 'x3', 'x4'], [['x1', 'x2'], ['x2', 'x3'], ['x2', 'x4']]],
[['x1', 'x2', 'x3', 'x4'], [['x1', 'x3'], ['x2', 'x3'], ['x3', 'x4']]],
[['x1', 'x2', 'x3', 'x4'], [['x1', 'x4'], ['x2', 'x4'], ['x3', 'x4']]],
[['x1', 'x2', 'x3', 'x4'], [['x1', 'x4'], ['x2', 'x3'], ['x2', 'x4']]],
[['x1', 'x2', 'x3', 'x4'],
[['x1', 'x3'], ['x1', 'x4'], ['x2', 'x3'], ['x2', 'x4']]],
[['x1', 'x2', 'x3', 'x4'], [['x1', 'x2'], ['x2', 'x3'], ['x3', 'x4']]],
[['x1', 'x2', 'x3', 'x4'], [['x1', 'x4'], ['x2', 'x3'], ['x3', 'x4']]]]
sage:
2 | No.2 Revision |
If i correctly figure out what is needed, then the following code should solve the problem (to some percentage):
def f(n):
"""https://ask.sagemath.org/question/38865/
obtaining-all-posets-in-a-certain-form-with-sage/
"""
R = range(n)
posets = [ p for p in Posets(n) if p.is_connected() ]
variables = [ "x%s" % (k+1) for k in R ]
result = []
for p in posets:
A = p.hasse_diagram().adjacency_matrix()
result.append( [ variables
, [ [ variables[j], variables[k] ]
for j in R for k in R
if A[j,k]
] ] )
return result
Example of usage in the sage interpreter:
sage: f(4)
[[['x1', 'x2', 'x3', 'x4'], [['x1', 'x2'], ['x1', 'x3'], ['x1', 'x4']]],
[['x1', 'x2', 'x3', 'x4'], [['x1', 'x2'], ['x1', 'x4'], ['x2', 'x3']]],
[['x1', 'x2', 'x3', 'x4'],
[['x1', 'x2'], ['x1', 'x3'], ['x2', 'x4'], ['x3', 'x4']]],
[['x1', 'x2', 'x3', 'x4'], [['x1', 'x2'], ['x2', 'x3'], ['x2', 'x4']]],
[['x1', 'x2', 'x3', 'x4'], [['x1', 'x3'], ['x2', 'x3'], ['x3', 'x4']]],
[['x1', 'x2', 'x3', 'x4'], [['x1', 'x4'], ['x2', 'x4'], ['x3', 'x4']]],
[['x1', 'x2', 'x3', 'x4'], [['x1', 'x4'], ['x2', 'x3'], ['x2', 'x4']]],
[['x1', 'x2', 'x3', 'x4'],
[['x1', 'x3'], ['x1', 'x4'], ['x2', 'x3'], ['x2', 'x4']]],
[['x1', 'x2', 'x3', 'x4'], [['x1', 'x2'], ['x2', 'x3'], ['x3', 'x4']]],
[['x1', 'x2', 'x3', 'x4'], [['x1', 'x4'], ['x2', 'x3'], ['x3', 'x4']]]]
sage:
LATER EDIT:
I will try to explain the way the above code works still here in the answer, since it would not fit in the comment. My favorite way is always by using a special situation.
So let us get a big connected poset, code:
X = ZZ( 2^2 * 3 ).divisors()
R = [ [j,k] for j in X for k in X if j != k and j.divides(k) ]
p = Poset( (X, R) )
print ( "Is p connected? %s"
% p.is_connected() )
print ( "The Hasse diagram of p is given by the matrix:\n%s"
% p.hasse_diagram().adjacency_matrix() )
print ( "The comparability graph of p as a matrix is:\n%s"
% p.comparability_graph().adjacency_matrix() )
print ( "An oriented version of this matrix is:\n%s"
% matrix( ZZ, len(X), len(X)
, [ [ p.compare_elements(j,k) for k in X ]
for j in X ] ) )
It gives an explanation of all objects:
Is p connected? True
The Hasse diagram of p is given by the matrix:
[0 1 1 0 0 0]
[0 0 0 1 1 0]
[0 0 0 0 1 0]
[0 0 0 0 0 1]
[0 0 0 0 0 1]
[0 0 0 0 0 0]
The comparability graph of p as a matrix is:
[0 1 1 1 1 1]
[1 0 0 1 1 1]
[1 0 0 0 1 1]
[1 1 0 0 0 1]
[1 1 1 0 0 1]
[1 1 1 1 1 0]
An oriented version of this matrix is:
[ 0 -1 -1 -1 -1 -1]
[ 1 0 0 -1 -1 -1]
[ 1 0 0 0 -1 -1]
[ 1 1 0 0 0 -1]
[ 1 1 1 0 0 -1]
[ 1 1 1 1 1 0]
sage:
The -1
in the first row means that $1$ (strictly) divides all other elements.
The second row [ 1 0 0 -1 -1 -1]
reads
2 is strictly divisible by 1, not strictly by 2, it does not (strictly) divide 3, but it does for
4, 6, 12 .
Now back to the original problem. Suppose we need variables for $x_k$ using exactly the divisors, as strings, the list of Hasse relations, the cover relations, and all relations for the strict divisibility. Here they are:
sage: dic = dict( [ (k, 'x%s' % k) for k in X ] )
sage: vars = dic.values()
sage: vars
['x1', 'x2', 'x3', 'x4', 'x6', 'x12']
sage: hasse_pairs = [ [ dic[j], dic[k] ] for j in X for k in X if [j,k] in p.cover_relations() ]
sage: hasse_pairs
[['x1', 'x2'],
['x1', 'x3'],
['x2', 'x4'],
['x2', 'x6'],
['x3', 'x6'],
['x4', 'x12'],
['x6', 'x12']]
sage: all_pairs = [ [ dic[j], dic[k] ] for j in X for k in X if p.compare_elements(j,k) == -1 ]
sage: all_pairs
[['x1', 'x2'],
['x1', 'x3'],
['x1', 'x4'],
['x1', 'x6'],
['x1', 'x12'],
['x2', 'x4'],
['x2', 'x6'],
['x2', 'x12'],
['x3', 'x6'],
['x3', 'x12'],
['x4', 'x12'],
['x6', 'x12']]
sage:
(Sorry for the space used for such a simple step, but now all problems are solved. People generally underestimate the bad didactic impact of small steps omissions in maths and info. This still propagates from the last century, as paper and publication space were expensive.)
The one problem with the double quote... I would solve it in the very last step in the film "code writes code", and in this step we can replace all simple quotes with double ones in the resulted code string. For instance, you may need - as in the last comment:
def f(n):
"""https://ask.sagemath.org/question/38865/
obtaining-all-posets-in-a-certain-form-with-sage/
"""
R = range(n)
dic = dict( [ (k, 'x%s' % (k+1)) for k in R ] ) # dic 0->'x1', 1->'x2', ...
vars = dic.values()
result = [] # and we append in the next loop
for p in Posets(n):
if not p.is_connected():
continue
entry = [ vars
, [ [ dic[j], dic[k] ]
for j in R for k in R
if p.hasse_diagram().adjacency_matrix() [j,k] ]
, [ [ dic[j], dic[k] ]
for j in R for k in R
if p.compare_elements(j,k) == -1 ]
]
# entry = re.sub( "'", '"', str(entry) ) # here or later
result.append( entry )
return result
import re
# print [ '\n'.join( [ re.sub( "'", '"', str(row) ) for row in f(5) ] ) ]
for row in f(5):
print re.sub( "'", '"', str(row) )
This gives a long list...