我有一个问题,我不愿意相信在Sage之前还没有解决。
给定一对整数(d,n)作为输入,我希望收到所有非减少的列表(或集合,或其他)长度为 d 的序列,其条目不大于 n 。
同样,我想要另一个函数返回所有严格增加长度为 d 的序列,其条目不大于 n
例如,对于 d = 2 n = 3 ,我会收到输出:
[[1,2],[1,3],[2,3]]
或
[[1,1],[1,2],[1,3],[2,2],[2,3],[3,3]]
取决于我是使用增加还是非减少。
有谁知道这样的功能?
编辑当然,如果有非增加或减少序列的方法,我可以修改它以符合我的目的。只需迭代序列
答案 0 :(得分:1)
我也需要这个算法,今天终于设法写了一个。我将在这里分享代码,但我上周才开始学习编码,所以它并不漂亮。
想法输入=(r,d)。步骤1)创建一个类“ListAndPosition”,其具有数组列表L的整数[r + 1],以及0和r之间的整数q。步骤2)创建一个方法,接收ListAndPosition(L,q)并按顺序屏蔽L中的数组,检查位置q处的整数是否小于位置q + 1处的整数,如果是,则在该位置添加一个新数组列表底部的那个条目++。完成后,Method再次使用新列表和q-1作为输入调用自身。
步骤1)的代码
import java.util.ArrayList;
公共类ListAndPosition { public static Integer r = 5;
public final ArrayList<Integer[]> L;
public int q;
public ListAndPosition(ArrayList<Integer[]> L, int q) {
this.L = L;
this.q = q;
}
public ArrayList<Integer[]> getList(){
return L;
}
public int getPosition() {
return q;
}
public void decreasePosition() {
q--;
}
public void showList() {
for(int i=0;i<L.size();i++){
for(int j=0; j<r+1 ; j++){
System.out.print(""+L.get(i)[j]);
}
System.out.println("");
}
}
}
步骤2)的代码
import java.util.ArrayList;
public class NonDecreasingSeqs {
public static Integer r=5;
public static Integer d=3;
public static void main(String[] args) {
//Creating the first array
Integer[] firstArray;
firstArray = new Integer[r+1];
for(int i=0;i<r;i++){
firstArray[i] = 0;
}
firstArray[r] = d;
//Creating the starting listAndDim
ArrayList<Integer[]> L = new ArrayList<Integer[]>();
L.add(firstArray);
ListAndPosition Lq = new ListAndPosition(L,r-1);
System.out.println(""+nonDecSeqs(Lq).size());
}
public static ArrayList<Integer[]> nonDecSeqs(ListAndPosition Lq){
int iterations = r-1-Lq.getPosition();
System.out.println("How many arrays in the list after "+iterations+" iterations? "+Lq.getList().size());
System.out.print("Should we stop the iteration?");
if(0<Lq.getPosition()){
System.out.println(" No, position = "+Lq.getPosition());
for(int i=0;i<Lq.getList().size();i++){
//Showing particular array
System.out.println("Array of L #"+i+":");
for(int j=0;j<r+1;j++){
System.out.print(""+Lq.getList().get(i)[j]);
}
System.out.print("\nCan it be modified at position "+Lq.getPosition()+"?");
if(Lq.getList().get(i)[Lq.getPosition()]<Lq.getList().get(i)[Lq.getPosition()+1]){
System.out.println(" Yes, "+Lq.getList().get(i)[Lq.getPosition()]+"<"+Lq.getList().get(i)[Lq.getPosition()+1]);
{
Integer[] tempArray = new Integer[r+1];
for(int j=0;j<r+1;j++){
if(j==Lq.getPosition()){
tempArray[j] = new Integer(Lq.getList().get(i)[j])+1;
}
else{
tempArray[j] = new Integer(Lq.getList().get(i)[j]);
}
}
Lq.getList().add(tempArray);
}
System.out.println("New list");Lq.showList();
}
else{
System.out.println(" No, "+Lq.getList().get(i)[Lq.getPosition()]+"="+Lq.getList().get(i)[Lq.getPosition()+1]);
}
}
System.out.print("Old position = "+Lq.getPosition());
Lq.decreasePosition();
System.out.println(", new position = "+Lq.getPosition());
nonDecSeqs(Lq);
}
else{
System.out.println(" Yes, position = "+Lq.getPosition());
}
return Lq.getList();
}
}
备注:我需要我的序列从0开始到d结束。
答案 1 :(得分:0)
这可能不是你问题的一个很好的答案。但原则上你可以使用Partitions
和max_slope=-1
参数。使用IntegerVectors
的过滤列表徘徊听起来同样效率低下并且由于其他原因而令人沮丧。
如果这有一个规范名称,它可能在sage-combinat功能列表中,甚至还有一个基类可以用于integer lists,这基本上就是你所要求的。也许你可以使用IntegerListsLex
实际得到你想要的东西?希望这证明是有帮助的。
答案 2 :(得分:0)
这个问题可以通过使用class&#34; UnorderedTuples&#34;来解决。这里描述:
http://doc.sagemath.org/html/en/reference/combinat/sage/combinat/tuple.html
要返回长度为d的0到n-1之间的所有非递减序列,您可以输入:
UnorderedTuples(range(n),d)
这将非递减序列作为列表返回。我需要一个不可变对象(因为序列将成为字典的键)。所以我使用了#34; tuple&#34;将列表转换为元组的方法:
immutables = []
for s in UnorderedTuples(range(n),d):
immutables.append(tuple(s))
return immutables
我还写了一个方法,只选出不断增加的序列:
def isIncreasing(list):
for i in range(len(list) - 1):
if list[i] >= list[i+1]:
return false
return true
仅返回严格增加的序列的方法看起来像
immutables = []
for s in UnorderedTuples(range(n),d):
if isIncreasing(s):
immutables.append(tuple(s))
return immutables