我正在尝试运行一个 mincut 算法(对于一个类),这适用于较小的测试用例,但是每当我放置一个更大的测试用例(最终导致分配问题)时,我都会收到此错误:
“(eval):1049: nil:NilClass (NoMethodError) 的未定义方法‘shift’”
我怀疑可能存在程序崩溃的某种情况,但我无法弄清楚。如果有人可以帮助我,那就太好了!
a = [[1, 2, 3, 4, 7], [2, 1, 3, 4], [3, 1, 2, 4], [4, 1, 2, 3, 5], [5, 4, 6, 7, 8], [6, 5, 7, 8], [7, 1, 5, 6, 8], [8, 5, 6, 7]]
mincut = 8
count = 10
def clean(a, i, j) #When collapsing two nodes together, scans
z = a[j][0] #all elements and changes value of second
m = a[i][0] #index to first, i.e. all 2's become 1's.
a.each_index do |x|
a[x].each_index do |y|
if a[x][y] == z
a[x][y] = m
end
end
end
end
def delete_loops!(a, i) #scans concatenated array, removes all duplicates of the first element
z = a[i].shift
a[i].reject!{ |item| item == z}
a[i].unshift(z)
end
def collapse!(a, i, j) #collapses two nodes together
clean(a, i, j)
a[i].concat(a[j]) #concatenates the second array into the first
a.delete_at(j) #deletes second array
delete_loops!(a, i)
end
def random(a) #picks random nodes to collapse, and returns their
t = rand(a.size) #positions in the array.
s = a[t][1 + rand(a[t].size - 1)]
for x in 0..a.size-1
if a[x][0] == s
s = x
break
end
end
return t, s
end
for x in 0..count do #repeats the program x amount of times, returns
while a.size > 2 do #the lowest value of the minimum cut.
i, j = random(a)
collapse!(a, i, j)
end
size = a[0].size - 1
if size < mincut
mincut = size
end
end
puts mincut
总结该程序,它通过执行一定数量的运行并保留返回的最小切割来计算图中的最小切割。似乎很麻烦的区域是我的“delete_loops!” 函数,它本质上检查数组以查看是否有任何元素与数组的第一个元素匹配,然后删除所述第一个元素的重复项。我使用“shift”和“unshift”方法来做到这一点(通过删除然后重新插入第一个元素,我在不删除过程中的第一个元素时遇到了麻烦)。
我认为要么是某种情况可能导致它崩溃,要么是我执行它的方式给我带来了麻烦。有任何想法吗?
#edit: full error message, from the codecademy scratchpad
(eval):1122: undefined method `shift' for nil:NilClass (NoMethodError)
from (eval):1131:in `collapse!'
from (eval):1149
from (eval):1146:in `each'
from (eval):1146
#and from my command line try (reading a text file with same array):
test.rb:29:in 'delete_loops!" : undefined method 'shift' for nil:NilClass <NoMethodError>
from test.rb:38:in 'collapse!'
from test:rb:56:in 'block in <main>'
from test.rb:53:in 'each'
from test.rb:53:in '<main>'