您将被油漆到A大小的地板上。从4个主要区域中将有12个油漆桶 颜色各有3种阴影(即总共12个桶)。铲斗尺寸,或更具体地说, 以下阵列给出了可以从每种阴影绘制的区域数量。 相同的原色的不同阴影显示在同一行中。
问题与约束
您需要选择4种阴影来绘制地板区域;
实施python程序来回答以下问题;
Q1。满足上述约束(如果A = 100)的颜色阴影(或色块)
Q2。上述情况下的浪费量
Q3。如果A = 90,那么Q1和Q2的解决方案是什么?
注意:您可以使用以下符号来引用上图中的每个阴影。
R-行索引
C-列索引
(r,c)-第(r + 1)行和第(c + 1)列的阴影
例如(0,0)-> 12,(0,1)-> 23,(1,2)-> 15,等等
这样,可以以[(0,1),(1,2),(2,0),(3,2)]格式给出Q1的答案
如果用户输入100,则系统应显示其坐标最接近100的颜色代码区域
示例
Enter your Area = 100
100 ~ 101(sum of areas 12+30+35+24, There for 101 is the closet number to 100)
Shades = [12 30 35 24]
Cordinates of shades = (0,0)(1,1)(2,2)(3,1)
这是我的应答代码
import numpy as np
import itertools
colors = np.array([[12, 23, 14], [10, 30, 15], [16, 22, 35], [14, 24, 20]])
max_tot = 0
#get total of all integers which are in array
for i in range(len(colors)):
max_tot = max_tot + max(colors[i])
#Enter Area
area = int(input("Enter your Area = "))
if(area > max_tot):
print("Area is too long. Don't have enough paints for painting")
elif(area <= 0):
print("Wrong area")
else:
#get shades which are given lowest minimum wastage
for element in itertools.product(*colors):
if(sum(element) >= area):
x = sum(element)
if(x <= max_tot):
max_tot = x
el = np.array(element)
print()
print("sum of shades =", max_tot)
print("minimum wastage =" , max_tot - area)
print("Shades =", el)
print("Cordinates of shades = " ,end ='')
#get coordinates using manual method
for i in range(4):
g,h = np.where(colors == el[i])
print("(" ,g[0],",", h[0], ")", sep=' ', end='', flush=True)
输出-:
Enter your Area = 100
sum of shades = 101
minimum wastage = 1
Shades = [12 30 35 24]
Cordinates of shades = ( 0 , 0 )( 1 , 1 )( 2 , 2 )( 3 , 1 )
您可以看到我有12 30 35 24
的坐标是手动类型。那不是一个好的编程方法。
如何直接(使用更好的方法)获得该坐标?
请注意,我已经回答了所有问题。我想要一个更好的第三季度答案
答案 0 :(得分:0)
优化搜索的唯一可能方法是在每次选择后删除重复的和值。很容易检查81种可能的浪费中是否有45种不同的浪费值:
len(set(sum(el) for el in product(*colors)))
Out[99]: 45
len(list(sum(el) for el in product(*colors)))
Out[100]: 81
其中几乎有一半是根据sum
复制的,这对于您的计算来说是不必要的权重。但这并不是很大的速度。这很大程度上取决于您运行代码的数据质量,主要是每个列表的值有多大以及列表的数量。
我整理了您的代码以使其更加高效和可读:
import numpy as np
from itertools import product
def get_area(max_tot):
# Asks to enter area and returns it or raises exception if it's wrong
# max_tot is maximum possible area
try:
area = int(input("Enter your Area = "))
except ValueError:
raise ValueError('Area is not a number')
if area > max_tot:
raise ValueError("Area is too long. Don't have enough paints for painting")
elif area <= 0:
raise ValueError("Wrong area")
else:
return area
def get_shades(colors, area, max_tot):
#get shades which are given lowest minimum wastage
for element in product(*colors):
sum_of_element = sum(element) # assigning it there to avoid double calculation
if area <= sum_of_element <= max_tot: # double comparison is possible in Python
max_tot = sum_of_element
el = np.array(element)
return el
colors = np.array([[12, 23, 14], [10, 30, 15], [16, 22, 35], [14, 24, 20]])
max_tot = np.sum(np.max(colors, axis=1))
area = get_area(max_tot)
el = get_shades(colors, area, max_tot)
print()
print("sum of shades =", max_tot)
print("minimum wastage =" , max_tot - area)
print("Shades =", el)
print("Cordinates of shades = " ,end ='')
#get coordinates using manual method
for i in range(4):
g,h = np.where(colors == el[i])
print("({}, {})".format(g[0], h[0]), sep=' ', end=' ', flush=True)
您的代码的“核心”在get_shades
函数中。我删除了sum(element)
的重复计算,并且还将一行进行两次比较以使其更具可读性。顺便说一下,可以按如下所示以100%函数样式重写get_shades
函数:
def get_shades(colors, area, max_tot):
# functional version of get_shades
def cmp(x):
# compares items based on their sum; bad items are largest by default
s = sum(x)
if s >= area: return s
else: return max_tot + 1
return min(product(*colors), key = cmp)
但是,正如您提到的那样,这还不够。您可能希望通过在每次选择后删除重复的总和来减少它:
[[12, 23, 14], [10, 30, 15]] -> [22, 24, 27, 29, 33, 38, 42, 44, 53] # 9 distinct sum values
[[22, 24, 27, 29, 33, 38, 42, 44, 53], [16, 22, 35]] -> # 24 distinct sum values
[[...], [14, 24, 20]] -> 45 distinct sum values
这是reduce
方法设计的一个很好的例子。每次迭代之后,它将获取最后的结果,对下一项进行计算,然后将其替换为新的结果。可以使用以下方式捕获总和的所有45个值:
wastages = reduce(lambda x,y: set(sum(n) for n in product(x, y)), colors)
并通过以下方法找到所需的最低金额:
min(wastages, key = cmp)
其中cmp
的定义方式如下:
def cmp(x):
if x >= area: return x
else: return max_tot + 1
但是会出现另一个大问题:阴影与它们的总和不同,不会保存在内存中。为了保留阴影和总和之间的映射,需要额外的功能。这就需要操作列表的高级方法,这似乎很慢而不是加快。我将它们排除在范围之外,因为映射需要更多困难的算法,并且仅当您的数据大于您发布的数据时,它们才有用。