我试图找到一种方法来优化特定和弦的吉他调音,以更好地适应一只手,而我在实际的优化部分遇到了一些麻烦。下面是我的代码的开始,我的目标函数定义了一个“分数”,与单手弹奏每个和弦的效果相关:
# defining chords by string and fret
d=np.array([5,7,7,4,5,np.nan])
bm=np.array([7,7,7,np.nan,5,7])
bm2=np.array([7,7,8,np.nan,6,7])
em=np.array([7,8,9,5,7,np.nan])
a7=np.array([5,5,6,5,0,np.nan])
d2=np.array([5,7,7,7,9,np.nan])
gm=np.array([6,8,7,8,10,np.nan])
g=np.array([7,8,7,np.nan,2,3])
a72=np.array([5,5,6,2,4,np.nan])
d3=np.array([5,7,7,7,5,np.nan])
#array of all chords
chords = np.array([d,bm, bm2, em, a7, d2, gm, g, a72, d3])
#objective function
def scorechord(o1, o2, o3, o4, o5):
"""
shift strings 1-5 by amounts o1-o5
positive number indicates string has been tuned down one half step
returns a number associated with best chord structures for hand
"""
newchords = np.empty([10,6])
score=0
for i in range(len(chords)):
#shift notes on string by offset amount
newchords[i][0]=chords[i][0]+o1
newchords[i][1]=chords[i][1]+o2
newchords[i][2]=chords[i][2]+o3
newchords[i][3]=chords[i][3]+o4
newchords[i][4]=chords[i][4]+o5
newchords[i][5]=chords[i][5]
for i in newchords:
imin=np.nanmin(i)
imax=np.nanmax(i)
#want max/min fret close enough for hand
if imax-imin>4 and imin!=0 and imax!=0:
score+=100
#best place to bar chord is lowest note
if stats.mode(i[0])[0]!=imin:
score+=10
#want notes to overall be close together
for j in range(5):
if np.isnan(abs(i[j+1]-i[j]))==False:
score+=abs(i[j+1]-i[j])
return score
我会使用scipy优化,但不能将其限制为整数值;我尝试了使用纸浆,但在将Lp变量传递到函数中时遇到了问题。据我所知,您通常应该显式地编写函数,而不是调用它来解决该问题,但我不知道如何使用如此复杂的函数来实现这一点(我也开始担心,即使我让它工作起来,这个函数也可能无法解决)
这是一次尝试:
Lp_prob = p.LpProblem('Problem', p.LpMinimize)
o1=p.LpVariable("o1", lowBound = -5, upBound = -5)
o2=p.LpVariable("o2", lowBound = -5, upBound = -5)
o3=p.LpVariable("o3", lowBound = -5, upBound = -5)
o4=p.LpVariable("o4", lowBound = -5, upBound = -5)
o5=p.LpVariable("o5", lowBound = -5, upBound = -5)
Lp_prob += scorechord(o1,o2,o3,o4,o5)
返回错误“float()参数必须是字符串或数字,而不是“LpAffineExpression”
我不知道该怎么做——有没有另一种方式来写出我的功能,纸浆将能够理解它,或者另一个包来考虑尝试?或者,是时候全力以赴,亲手编写一个优化函数了
目前没有回答
相关问题 更多 >
编程相关推荐