在下面的代码中,群集有很多点。
class Cluster
attr_accessor :centroid, :points
def initialize(centroid, *points)
@centroid = centroid
@points = points
end
end
class Point
attr_accessor :x, :y
def initialize(x = 0, y = 0)
@x = x
@y = y
end
end
Cluster
对象的示例(让我们称之为c
):
#<Cluster:0x007ff5c123c210
@centroid=#<Point:0x007ff5c123c288 @x=25, @y=125>,
@points=
[#<Point:0x007ff5c123c238 @x=25, @y=125>,
#<Point:0x007ff5c1020120 @x=28, @y=145>]>
我正在尝试计算点的平均值,并在不更改@centroid
的情况下更新@points
。
我们说我有:
class Point
def +(point)
@x = @x + point.x
@y = @y + point.y
self
end
def /(num)
@x = @x/num
@y = @y/num
self
end
end
并计算所有点的平均值,我运行:
c.centroid = c.points.reduce(&:+)/c.points.length
然后,c
更改为:
#<Cluster:0x007ff5c123c210
@centroid=#<Point:0x007ff5c1515ec8 @x=26, @y=135>,
@points=
[#<Point:0x007ff5c1515ec8 @x=26, @y=135>,
#<Point:0x007ff5c1020120 @x=28, @y=145>]>
请注意@points
的第一个元素已更改。有什么建议吗?
答案 0 :(得分:5)
+
中的Point
方法修改了该点的成员@x
和@y
。您需要使用计算值返回一个新点:
def +(point)
Point.new(@x + point.x, @y + point.y)
end
def /(num)
Point.new(@x/num, @y/num)
end
答案 1 :(得分:2)
由于您未将初始值传递给reduce
,因此第一个点被修改。您可以将新点作为初始值传递给reduce
,该点将被修改并返回。
c.centroid = c.points.reduce(Point.new, &:+)/c.points.length
答案 2 :(得分:0)
我认为问题是由+方法修改点@x和@y值引起的。
尝试将+方法更改为:
def +(point)
x = @x + point.x
y = @y + point.y
self.class.new(x, y)
end