0

我想在 Python 中模拟 9 的江恩平方图表。对于不知道图表是什么样子的人,请单击此处了解基本概念并在当前市场价格空白处输入一个值(例如 100)。

图表基本上从中心位置开始以螺旋形式展开。(江恩图螺旋的图片)我对此的问题如下:

  1. 我应该选择什么数据结构来构建一个扩展的螺旋?正在考虑为它构建一个矩阵,但是如何调节矩阵?

  2. 如何搜索(快速,最好不遍历整个矩阵)图表中的特定值?(假设它是一个大图表,螺旋中有大约 100 个级别)

我被困在开始编码图表的方法上,所以任何对此的见解都会很棒。

4

2 回答 2

1

任何大小的江恩正方形

希望这可以解决您的问题

class GannSquare():
    """An container object for Gann Square"""

    def __init__(self, size):

        """ attributes and method of Gann Square
            input parameters: size
            output returned: an object along with its attributes
        """
        self.size = size
        self.even_size = size % 2 == 0
        self.odd_size = size % 2 == 1
        self.num_elements = size ** 2
        
        self.matrix = self.generate()
        
        self.horizontal_axis = self.get_horizontal_axis()
        self.vertical_axis = self.get_vertical_axis()
        self.diagonal_1 = self.get_diagonal_1()
        self.diagonal_2 = self.get_diagonal_2()
        self.diagonal_axis = self.get_diagonal_axis()
        
    def generate(self):
        """
        generate a Gann Square based on the input parameter size
        """
        from numpy import array
        NORTH, SOUTH, EAST, WEST = (0, 1), (0, -1), (1, 0), (-1, 0) # directional vectors
        clockwise = {
            WEST:NORTH,
            NORTH: EAST, 
            EAST: SOUTH, 
            SOUTH: WEST
        } # clockwise transformation
        
        RIGHT, LEFT = 1, -1
        # forward or backward increment

        if self.size < 1:
            raise ValueError
        x, y = self.size // 2, self.size // 2 
        # the middle of the box
        dx, dy =  WEST # initial direction
        inc = LEFT # backward increment

        G = [[None] * self.size for _ in range(self.size)]
        
        count = 0

        while True:
            count += 1
            G[x][y] = count # visit
            # follow predefined direction
            _dx, _dy = clockwise[dx,dy]
            _x, _y = x +inc* _dx, y +inc* _dy

            if (0 <= _x < self.size and 0 <= _y < self.size and
                G[_x][_y] is None): 
                # in the box
                x, y = _x, _y
                dx, dy = _dx, _dy

            else: # fill in the box
                x, y = x +inc* dx, y +inc* dy
                if not (0 <= x < self.size and 0 <= y < self.size):
                    return array(G) # out of the box
    
    def display_matrix(self):
        width = len(str(max(e for row in self.matrix for e in row if e is not None)))
        fmt = "{:0%dd}" % width
        for row in self.matrix:
            print(" ".join("_"*width if e is None else fmt.format(e) for e in row))
            
    def get_horizontal_axis(self):
        return self.matrix[:,self.size//2]
    
    def get_vertical_axis(self):
        return self.matrix[self.size//2, :]
    
    def get_diagonal_1(self):
        diagonal_1 = []
        for i in range(self.size):
            diagonal_1.append(self.matrix[i,self.size-i-1])
        return diagonal_1
    
    def get_diagonal_2(self):
        diagonal_2 = []
        for i in range(self.size):
            diagonal_2.append(self.matrix[i,i])
        return diagonal_2
    
    def get_diagonal_axis(self):
        from numpy import concatenate
        return concatenate((self.diagonal_1, self.diagonal_2))
        

示例用法:

gs = GannSquare(21)
gs.display_matrix()

结果:

381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401
380 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 402
379 306 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 326 403
378 305 240 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 258 327 404
377 304 239 182 133 134 135 136 137 138 139 140 141 142 143 144 145 198 259 328 405
376 303 238 181 132 091 092 093 094 095 096 097 098 099 100 101 146 199 260 329 406
375 302 237 180 131 090 057 058 059 060 061 062 063 064 065 102 147 200 261 330 407
374 301 236 179 130 089 056 031 032 033 034 035 036 037 066 103 148 201 262 331 408
373 300 235 178 129 088 055 030 013 014 015 016 017 038 067 104 149 202 263 332 409
372 299 234 177 128 087 054 029 012 003 004 005 018 039 068 105 150 203 264 333 410
371 298 233 176 127 086 053 028 011 002 001 006 019 040 069 106 151 204 265 334 411
370 297 232 175 126 085 052 027 010 009 008 007 020 041 070 107 152 205 266 335 412
369 296 231 174 125 084 051 026 025 024 023 022 021 042 071 108 153 206 267 336 413
368 295 230 173 124 083 050 049 048 047 046 045 044 043 072 109 154 207 268 337 414
367 294 229 172 123 082 081 080 079 078 077 076 075 074 073 110 155 208 269 338 415
366 293 228 171 122 121 120 119 118 117 116 115 114 113 112 111 156 209 270 339 416
365 292 227 170 169 168 167 166 165 164 163 162 161 160 159 158 157 210 271 340 417
364 291 226 225 224 223 222 221 220 219 218 217 216 215 214 213 212 211 272 341 418
363 290 289 288 287 286 285 284 283 282 281 280 279 278 277 276 275 274 273 342 419
362 361 360 359 358 357 356 355 354 353 352 351 350 349 348 347 346 345 344 343 420
441 440 439 438 437 436 435 434 433 432 431 430 429 428 427 426 425 424 423 422 421

和其他几种方法

gs.size, gs.num_elements, gs.even_size, gs.odd_size, 
gs.horizontal_axis, gs.vertical_axis, gs.diagonal_axis

是不言自明的。

Numpy 数组用于存储江恩矩阵,以便我们可以numpy.where在需要在其中搜索特定值时使用。

于 2021-06-20T07:31:20.777 回答
0

假设 1 位于 (0, 0),则任何给定正整数的确切位置可以通过以下函数获得:

import math

def f(num):
    n = math.floor(math.sqrt(num)) // 2
    if (num <= 4*n*n):
        k = num - (2*n-1)**2
        if k <= 2*n:
            return (- n, k - n + 1)
        else:
            return (k - 3 * n, n)
    else:
        k = num - (2*n)**2
        if k <= 2*n + 1:
            return (n, n - k + 1)
        else:
            return (3 * n - k + 1, - n)

这源于两个事实:

  1. 数字 (2*n+1)^2 总是位于 (-n, -n)
  2. 数字 (2*n)^2 总是位于 (n-1, n)
于 2016-10-20T06:40:50.677 回答