枚举所有可能的有约束的矩阵
Enumeration all possible matrices with constraints
我试图枚举大小为r
× r
的所有可能的矩阵,并具有一些约束。
- 行和和必须按非升序排列。
- 从主对角线上的左上角元素开始,该条目的每个行和列子集必须由从0到左上角条目中的值(包括)的替换组合组成。
- 行和列之和必须小于或等于预定的n值。
- 主对角线必须为非升序。
重要的注意是,我需要将每个组合存储在某个地方,或者如果用c++编写,则在找到它们后再运行其他几个函数
r
和n
的取值范围从2到100。
我已经尝试了一种递归的方式来做到这一点,伴随着迭代,但是一直在跟踪列和行和,以及在可管理的意义上的所有数据。
我附上了我最近的一次尝试(远未完成),但可能会给你一个关于发生了什么的想法。
函数first_section():
正确构建第0行和第0列,但除此之外,我没有任何成功。
我需要更多的推动来推动这件事,逻辑是一个痛苦的屁股,并吞噬了我整个。我需要有这写在python或c++。
import numpy as np
from itertools import combinations_with_replacement
global r
global n
r = 4
n = 8
global myarray
myarray = np.zeros((r,r))
global arraysums
arraysums = np.zeros((r,2))
def first_section():
bigData = []
myarray = np.zeros((r,r))
arraysums = np.zeros((r,2))
for i in reversed(range(1,n+1)):
myarray[0,0] = i
stuff = []
stuff = list(combinations_with_replacement(range(i),r-1))
for j in range(len(stuff)):
myarray[0,1:] = list(reversed(stuff[j]))
arraysums[0,0] = sum(myarray[0,:])
for k in range(len(stuff)):
myarray[1:,0] = list(reversed(stuff[k]))
arraysums[0,1] = sum(myarray[:,0])
if arraysums.max() > n:
break
bigData.append(np.hstack((myarray[0,:],myarray[1:,0])))
if printing: print 'myarray n%s' %(myarray)
return bigData
def one_more_section(bigData,index):
newData = []
for item in bigData:
if printing: print 'item = %s' %(item)
upperbound = int(item[index-1]) # will need to have logic worked out
if printing: print 'upperbound = %s' % (upperbound)
for i in reversed(range(1,upperbound+1)):
myarray[index,index] = i
stuff = []
stuff = list(combinations_with_replacement(range(i),r-1))
for j in range(len(stuff)):
myarray[index,index+1:] = list(reversed(stuff[j]))
arraysums[index,0] = sum(myarray[index,:])
for k in range(len(stuff)):
myarray[index+1:,index] = list(reversed(stuff[k]))
arraysums[index,1] = sum(myarray[:,index])
if arraysums.max() > n:
break
if printing: print 'index = %s' %(index)
newData.append(np.hstack((myarray[index,index:],myarray[index+1:,index])))
if printing: print 'myarray n%s' %(myarray)
return newData
bigData = first_section()
bigData = one_more_section(bigData,1)
一个可能的矩阵是这样的:R = 4, n>= 6
|3 2 0 0| = 5
|3 2 0 0| = 5
|0 0 2 1| = 3
|0 0 0 1| = 1
6 4 2 2
这是numpy和python 2.7中的解决方案。注意,所有的行和列都是非递增顺序的,因为您只指定了它们应该是具有替换的组合,而不是它们的排序(使用排序列表生成组合是最简单的)。
代码可以通过保留行和列的和作为参数而不是重新计算它们来进行优化。
import numpy as np
r = 2 #matrix dimension
maxs = 5 #maximum sum of row/column
def generate(r, maxs):
# We create an extra row and column for the starting "dummy" values.
# Filling in the matrix becomes much simpler when we do not have to treat cells with
# one or two zero indices in special way. Thus, we start iteration from the
# (1, 1) index.
m = np.zeros((r + 1, r + 1), dtype = np.int32)
m[0] = m[:,0] = maxs + 1
def go(n, i, j):
# If we completely filled the matrix, yield a copy of the non-dummy parts.
if (i, j) == (r, r):
yield m[1:, 1:].copy()
return
# We compute the next indices in row major order (the choice is arbitrary).
(i2, j2) = (i + 1, 1) if j == r else (i, j + 1)
# Computing the maximum possible value for the current cell.
max_val = min(
maxs - m[i, 1:].sum(),
maxs - m[1:, j].sum(),
m[i, j-1],
m[i-1, j])
for n2 in xrange(max_val, -1, -1):
m[i, j] = n2
for matrix in go(n2, i2, j2):
yield matrix
return go(maxs, 1, 1) #note that this is a generator object
# testing
for matrix in generate(r, maxs):
print
print matrix
如果您希望在行和列中拥有所有有效的排列,下面的代码应该可以工作。
def generate(r, maxs):
m = np.zeros((r + 1, r + 1), dtype = np.int32)
rows = [0]*(r+1) # We avoid recomputing row/col sums on each cell.
cols = [0]*(r+1)
rows[0] = cols[0] = m[0, 0] = maxs
def go(i, j):
if (i, j) == (r, r):
yield m[1:, 1:].copy()
return
(i2, j2) = (i + 1, 1) if j == r else (i, j + 1)
max_val = min(rows[i-1] - rows[i], cols[j-1] - cols[j])
if i == j:
max_val = min(max_val, m[i-1, j-1])
if (i, j) != (1, 1):
max_val = min(max_val, m[1, 1])
for n in xrange(max_val, -1, -1):
m[i, j] = n
rows[i] += n
cols[j] += n
for matrix in go(i2, j2):
yield matrix
rows[i] -= n
cols[j] -= n
return go(1, 1)
相关文章:
- 有可能在Armadillo中复制MATLAB circshift方法吗
- 在他自己的方法中,有可能将一个对象取消引用到另一个对象吗
- 有可能使shared_ptr协变吗
- 有可能在信号处理程序中设置promise吗
- 是否有可能实现O(N)时间和O(1)空间解决方案,以实现C++中的字符串循环移位
- 是否有可能构建面向Linux和Windows的.Net Core C++ / CLI应用程序?
- 是否有可能使用debug_info获取ELF文件的源代码?
- C++,是否有可能/如何定义在.h和.cpp源文件中调用函数的类构造函数
- 有可能在C++中有类的查找表吗
- 是否有可能让 c++ dll 在后台运行 python 程序并让它填充向量图?如果是这样,如何?
- 向量的大小是否有可能为 1 但其中的元素数量为零?
- 是否有可能编写新的叮当声现代化规则?
- 是否有可能通过指向另一个未关联的子对象的指针来获取指向一个子对象的指针?
- 是否有可能通过演绎指南实现整个 std::make_tuple 功能?
- 是否有可能在没有复制的情况下传递 std::vector<int> 作为参数来获得 std::vector<std::array<int, 3>>?
- 是否有可能具有放入容器的移动操作的类型?
- 是否有可能通过溢出 C 中的第一个元素来写入数组第二个元素
- 声明是否有可能逃脱其封闭的名称空间
- git-是否有互联网上某处所有可能错误的列表
- 是否有可能有一个派生类继承最终函数但创建相同的函数(而不是重写)