python上的行和列限制

2024-04-26 06:34:05 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个列表列表m,我需要修改它

我需要每行的和大于A,每列的和要小于B

我有这样的东西

x = 5     #or other number, not relevant
rows = len(m)
cols = len(m[0])

for r in range(rows): 
    while sum(m[r]) < A:  
        c = randint(0, cols-1)
        m[r][c] += x 

for c in range(cols): 
    cant = sum([m[r][c] for r in range(rows)])
    while cant > B:
        r = randint(0, rows-1)
        if m[r][c] >= x:  #I don't want negatives
            m[r][c] -= x

我的问题是:我需要同时满足这两个条件,这样,在第二个for之后,我不确定第一个条件是否仍然满足。在

有什么建议可以同时满足这两个条件,当然,最好的执行?我完全可以考虑使用numpy

编辑(示例)

^{pr2}$

我可能需要添加

这是一种用于生成随机初始种群的遗传算法,其限制条件是使它们成为可能的解,而我需要运行这个像80次这样得到不同的可能解


Tags: orinnumber列表forlenrange条件
3条回答
from random import *

m = [[0,0,0],
    [0,0,0]]
A = 20
B = 25

x = 1     #or other number, not relevant
rows = len(m)
cols = len(m[0])

def runner(list1, a1, b1, x1):
    list1_backup = list(list1)
    rows = len(list1)
    cols = len(list1[0])

    for r in range(rows): 
        while sum(list1[r]) <= a1:  
            c = randint(0, cols-1)
            list1[r][c] += x1

    for c in range(cols): 
        cant = sum([list1[r][c] for r in range(rows)])
        while cant >= b1:
            r = randint(0, rows-1)
            if list1[r][c] >= x1:  #I don't want negatives
                list1[r][c] -= x1
    good_a_int = 0
    for r in range(rows):
        test1 = sum(list1[r]) > a1
        good_a_int += 0 if test1 else 1

    if good_a_int == 0:
        return list1
    else:
        return runner(list1=list1_backup, a1=a1, b1=b1, x1=x1)

m2 = runner(m, A, B, x)
for row in m:
    print ','.join(map(lambda x: "{:>3}".format(x), row))

像这样的事情应该很有意思:

import numpy
from scipy.optimize import linprog

A = 10
B = 20
m = 2
n = m * m

# the coefficients of a linear function to minimize.
# setting this to all ones minimizes the sum of all variable
# values in the matrix, which solves the problem, but see below.
c = numpy.ones(n)

# the constraint matrix.
# This is matrix-multiplied with the current solution candidate
# to form the left hand side of a set of normalized 
# linear inequality constraint equations, i.e.
#
# x_0 * A_ub[0][0] + x_1 * A_ub[0][1] <= b_0
# x_1 * A_ub[1][0] + x_1 * A_ub[1][1] <= b_1
# ...
A_ub = numpy.zeros((2 * m, n))

# row sums. Since the <= inequality is a fixed component,
# we just multiply everthing by (-1), i.e. we demand that
# the negative sums are smaller than the negative limit -A.
#
# Assign row ranges all at once, because numpy can do this.
for r in xrange(0, m):
    A_ub[r][r * m:(r + 1) * m] = -1

# We want that the sum of the x  in each (flattened)
# column is smaller than B
#
# The manual stepping for the column sums in row-major encoding
# is a little bit annoying here.
for r in xrange(0, m):
    for j in xrange(0, m):
        A_ub[r + m][r + m * j] = 1

# the actual upper limits for the normalized inequalities.
b_ub = [-A] * m + [B] * m

# hand the linear program to scipy
solution = linprog(c, A_ub=A_ub, b_ub=b_ub)

# bring the solution into the desired matrix form
print numpy.reshape(solution.x, (m, m))

注意事项

  • 我使用<=,而不是你的问题中指出的<,因为这是numpy支持的。在
  • 这将最小化目标向量中所有值的总和。 对于您的用例,您可能希望最小化距离 对于原始样本,线性程序无法处理,因为平方误差和绝对差都不能用线性组合表示(这是c的意思)。为此,您可能需要转到full ^{}。在

不过,这会让你有个大概的想法。在

NumPy解决方案:

import numpy as np

val = B / len(m) # column sums <= B
assert val * len(m[0]) >= A # row sums >= A

# create array shaped like m, filled with val
arr = np.empty_like(m)
arr[:] = val

我选择忽略m的原始内容—在您的示例中,它都是零。在

相关问题 更多 >