简体   繁体   English

如何仅针对解决方案取决于初始猜测的优化问题打印唯一的解决方案?

[英]How to print only unique solutions to an optimization problem for which the solution depends on the initial guess?

I'm trying to solve an optimization problem of 4 equations with 4 unknowns. 我正在尝试解决具有4个未知数的4个方程的优化问题。 Since the solution depends on the initial guess, I want to randomize the initial guess and check the solution. 由于解决方案取决于初始猜测,因此我想随机化初始猜测并检查解决方案。 I want to let python repeat this thousands of times and then collect all the unique solutions. 我想让python重复数千次,然后收集所有独特的解决方案。 Any ideas how I can do this? 有什么想法可以做到吗?

This is what I got, but I can't figure out how I can print unique solutions only. 这就是我得到的,但是我无法弄清楚如何仅打印独特的解决方案。 Currently with only 10 random initial guesses, but I'd like to do it with thousands. 目前只有10个随机的初始猜测,但我想用数千个来做。

import numpy as np
from scipy import optimize
import random
def equations(x):
    p1 = x[0]
    p2 = x[1]
    t1 = x[2]
    t2 = x[3]
    f1 = -1725*p1*(t1 + 1) + 210*p2*(t2 + 1) + (p1 - 0.4)*(-1725*t1 - 1725) + 3804.25
    f2 = -80.8*p1*(t1 + 1) - 43.2*p2*(t2 + 1) + (p2 - 0.19)*(-43.2*t2 - 43.2) + 1221.55
    f3 = -1725*p1**2*t1 - 80.8*p1*p2*t2 + p1*(-1725*p1*(t1 + 1) + 210*p2*(t2 + 1) + 3804.25) + 3721.65*p1
    f4 = 210*p1*p2*t1 - 43.2*p2**2*t2 + p2*(-80.8*p1*(t1 + 1) - 43.2*p2*(t2 + 1) + 1221.55) + 302.7*p2
    return (f1,f2,f3,f4)
mylist = []
times_to_repeat=10
while times_to_repeat >= 0:
    x=optimize.fsolve(equations,np.random.randint(-1000,1000,size=4)) 
    times_to_repeat -= 1
    mylist.append(x)  
print(type(x))
print(type(mylist))
print(mylist)

Output: 输出:

<class 'numpy.ndarray'>
<class 'list'>
[array([  0.6766083 , -16.36251351,   2.80326423,  -1.71285248]), array([   0.70453984,    0.20006569,    3.71919204,  103.97195662]), array([  0.6766083 , -16.36251351,   2.80326423,  -1.71285248]), array([  5.71533971e-11,  -2.78802240e-10,  -6.51340581e+00,
        -1.49824317e+02]), array([  1.15380439e-14,   4.54997307e-01,  -1.19518826e+01,
         3.82733776e+01]), array([   0.70453984,    0.20006569,    3.71919204,  103.9719566 ]), array([   0.70453984,    0.20006569,    3.71919204,  103.9719566 ]), array([   0.70453984,    0.20006569,    3.71919204,  103.9719566 ]), array([ -1.15803237, -20.50033894,  -2.37625565,  -1.61411274]), array([  3.74219997e-01,  -2.19855824e-11,   5.32924565e+00,
        -1.26508376e+02]), array([ -2.33169826e+00,  -3.58746853e-10,  -1.43554999e+00,
        -1.39826980e+02])]

I am essentially answering the question of identifying close solutions among the list of solutions. 我本质上是回答在解决方案列表中确定紧密解决方案的问题。 One approach would be to use k-means clustering (in scipy, this requires guessing the number of solutions). 一种方法是使用k均值聚类(本质上,这需要猜测解的数量)。 Another would be to use initialize a KDTree of solutions, compute close pairs and return centroids of the connected components in the induced graph. 另一个方法是使用初始化解决方案的KDTree,计算紧密对并返回诱导图中连接组件的质心。

import numpy as np
from scipy.cluster.vq import kmeans
from scipy.spatial import cKDTree
import networkx as nx

# if you can guess the number of different solutions
def close_solutions_kmeans(points, guess_n_sols=n_centroids):
    return kmeans(points, guess_n_sols)[0]


# direct method with KDTree
def close_solutions_kdtree(points, close):
    visited = np.zeros(points.shape[0], bool)
    representative_solutions = list()
    # make a KDTree for fast neighbor lookup
    tree = cKDTree(points)
    # make a graph to search for connected components
    g = nx.Graph()
    g.add_nodes_from(np.arange(points.shape[0]))
    g.add_edges_from(tree.query_pairs(close))
    # return mean of points in each connected component
    return np.array([points[list(c)].mean(0)
        for c in nx.connected_components(g)])

In 2D, the result may look somewhat like this: 在2D模式下,结果可能看起来像这样:

在此处输入图片说明

Pale blue points are the solutions, red points are kmeans centroids and blue points are kdtree solutions (blue and red points may overlap). 淡蓝色的点是解,红色的点是kmeans重心,蓝色的点是kdtree解(蓝色和红色点可能重叠)。

It is worth noting that there is some freedom in how you identify close solutions. 值得注意的是,您在确定紧密解决方案方面有一定的自由度。 For example, it may be that a is close to b , b is close to c but a is not close to c , possibly leading to ambiguity. 例如,可能a接近bb接近ca不接近c ,可能导致歧义。 In the close_solutions_kdtree function, we first construct a graph whose vertices are individual solutions and connect pairs of close solutions with an edge. close_solutions_kdtree函数中,我们首先构造一个图,其顶点是单个解,然后将成对的闭合解与边连接。 Centroids of connected components are the representative solutions. 连接组件的质心是代表性的解决方案。

If you look at the plot above, there is only one blue dot in the central region, representing three visibly distinct groups of solutions, and illustrating the previous point. 如果看上面的图,中心区域只有一个蓝点,代表三个明显不同的解决方案组,并且说明了上一点。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM