【问题标题】:JTree, Optimization algorithm, JavaJTree,优化算法,Java
【发布时间】:2019-05-27 03:40:29
【问题描述】:

我的合作伙伴和我,我们正在努力优化频率过程...

我们希望在JTree 中尽可能简化我们的问题。

如您所见,每个 nodeleaf 在每个节点/叶中都有一个 numResampleOperations

L -> Increment or multiplication
M -> Decrement or division

我们如何计算这些值?

Target = Source*L/M
numResampleOperations = filterSize * Source * Integer.max(L, M);

我们希望在 JTextField 中显示的每个频率只获得一个值,删除不需要的分支。

对于这个例子,我们只使用了 5 个有序的 Target 频率(只允许整数值),但可以增长到 50 个频率值。

JTree 必须至少保留每个包含一个Target 频率为 150Hz,至少为 160Hz、..、210Hz 之一。

最高优先级是涉及numResampleOperations的最小总和

如何删除不需要的分支(those whose sum is very high)、节点或叶子,保证至少有一个(JTextField 上要求的频率),但所有numResampleOperations 的总和最小?

您对我们有什么建议?

我们从Generate List with Combination of Subset of List, Java开始 但由于尺寸问题,该解决方案不可行。

编辑 1

我的班级

public class NodeResample {

  private int incrementL;
  private int decrementM;
  private int sampleRateSource;
  private int sampleRateTarget;
  private double maxPassFreq;
  private Integer filterSize;
  private Integer numResampleOperations;

  public NodeResample(int incrementL, int decrementM, int sampleRateSource, int sampleRateTarget, double maxPassFreq, Integer filterSize, Integer numResampleOperations) {
    this.incrementL = incrementL;
    this.decrementM = decrementM;
    this.sampleRateSource = sampleRateSource;
    this.sampleRateTarget = sampleRateTarget;
    this.maxPassFreq = maxPassFreq;
    this.filterSize = filterSize;
    this.numResampleOperations = numResampleOperations;
  }

  public int getIncrementL() {
    return incrementL;
  }

  public void setIncrementL(int incrementL) {
    this.incrementL = incrementL;
  }

  public int getDecrementM() {
    return decrementM;
  }

  public void setDecrementM(int decrementM) {
    this.decrementM = decrementM;
  }

  public int getSampleRateSource() {
    return sampleRateSource;
  }

  public void setSampleRateSource(int sampleRateSource) {
    this.sampleRateSource = sampleRateSource;
  }

  public int getSampleRateTarget() {
    return sampleRateTarget;
  }

  public void setSampleRateTarget(int sampleRateTarget) {
    this.sampleRateTarget = sampleRateTarget;
  }

  public double getMaxPassFreq() {
    return maxPassFreq;
  }

  public void setMaxPassFreq(double maxPassFreq) {
    this.maxPassFreq = maxPassFreq;
  }

  public Integer getFilterSize() {
    return filterSize;
  }

  public void setFilterSize(Integer filterSize) {
    this.filterSize = filterSize;
  }

  public Integer getNumResampleOperations() {
    return numResampleOperations;
  }

  public void setNumResampleOperations(Integer numResampleOperations) {
    this.numResampleOperations = numResampleOperations;
  }

  @Override
  public String toString() {
    return "NodeResample{" + "L=" + incrementL + ", M=" + decrementM
        + ", Source=" + sampleRateSource + ", Target=" + sampleRateTarget
        + ", filterSize=" + filterSize + ", numResampleOperations=" + numResampleOperations + "}   ";
  }

}

现在,我注意到某些分支是必不可少的,例如包含 210First (Top) 分支,因为树的其他分支不包含它。

首先,我需要一个代码来找到包含该值(200)'或最便宜'的分支。将找到的分支添加到另一个目标 JTree。 这部分的一些代码?

我还注意到其他分支仍然具有200 的值,但是添加另一个分支的成本比继续使用第一个“必要”分支要大,因为这是only adding two nodes,其总和小于添加另一个分支。

其次,我需要知道这些two nodes numResampleOperations -> (267960 + 1091720) 的值以及另一个分支的值,以便进行比较并将最佳选项添加到另一个目标JTree。 一些代码这部分?

【问题讨论】:

    标签: java swing jtree


    【解决方案1】:

    我解决了我的问题...

    我想改进我的所有方法,尤其是 searchNodeResamplePerValuegetOptimizedTree

    我创建了一个填充方法...https://pastebin.com/LvCefdc4

    您可以复制粘贴并执行。

    树 -> 未优化!

    treeOut -> 优化!

    public class OptimizationResample {
    
      public static void main(String[] args) {
    
        final JTree tree = new JTree();
        tree.setRootVisible(false);
        removeAllTreeNodes(tree);
        fillTreeNestedListNodeResample(tree, filler());
        expandAllNodes(tree);
    
        List<Integer> listSampleRateFinal = Arrays.asList(210, 200, 180, 160, 150);
        JTree treeOut = getOptimizedTree(tree, listSampleRateFinal);
        expandAllNodes(treeOut);
        final JTextField textField = new JTextField(listSampleRateFinal.toString());//listSampleRateFinal .collect(Collectors.joining(","));
    
        JSplitPane splitPane = new JSplitPane();
        splitPane.setOrientation(JSplitPane.VERTICAL_SPLIT);
        splitPane.setTopComponent(new JScrollPane(tree));
        splitPane.setBottomComponent(new JScrollPane(treeOut));
        splitPane.setDividerLocation(350);
        JPanel panel = new JPanel();
        panel.setLayout(new BoxLayout(panel, BoxLayout.PAGE_AXIS));
        panel.add(textField);
        panel.add(splitPane);
    
        JFrame frame = new JFrame("Optimization NodeResample");
        frame.setContentPane(panel);
        frame.pack();
        frame.setSize(new Dimension(600, 700));
        frame.setVisible(true);
    
      }
    
      private static JTree getOptimizedTree(JTree tree, List<Integer> listSampleRateFinal) {
        JTree treeOut = new JTree();
        treeOut.setRootVisible(false);
        removeAllTreeNodes(treeOut);
        listSampleRateFinal.forEach(target -> {
          List<List<NodeResample>> nestedListPerValue = searchNodeResamplePerValue(tree, target);
          Long lastMinimum = Long.MAX_VALUE;
          List<NodeResample> minimumlistPerValue = null;
          for (List<NodeResample> listPerValue : nestedListPerValue) {
            // I can't easily copy all nodes from treeOut to tempTree (I had problem with new JTree(treeOut.getModel());)
            List<List<NodeResample>> nestedListNodeResample2 = getNestedListNodeResampleFromTree(treeOut);
            JTree tempTree = new JTree();
            tempTree.setRootVisible(false);
            removeAllTreeNodes(tempTree);
            fillTreeNestedListNodeResample(tempTree, nestedListNodeResample2);
            addNodeResampleToTree(tempTree, listPerValue);
    
            List<DefaultMutableTreeNode> listNodes = getListNodesFromTree(tempTree);
            Long accumulator = listNodes.stream()
                .filter(leaf -> leaf.getUserObject() instanceof NodeResample)
                .map(leaf -> (NodeResample) leaf.getUserObject())
                .map(nodeResample -> (long) nodeResample.getNumResampleOperations())
                .mapToLong(Long::longValue).sum();
            if (accumulator < lastMinimum) {
              lastMinimum = accumulator;
              minimumlistPerValue = listPerValue;
            }
          }
          if (minimumlistPerValue != null) {
            System.out.println("\nminimumlistPerValue:" + Arrays.toString(minimumlistPerValue.toArray()) + "\n");
          } else {
            System.out.println("\nminimumlistPerValue:" + null + "\n");
          }
    
          addNodeResampleToTree(treeOut, minimumlistPerValue);
        });
        return treeOut;
      }
    
      private static List<List<NodeResample>> searchNodeResamplePerValue(JTree tree, int value) {
        List<DefaultMutableTreeNode> listNodes = getListNodesFromTree(tree);
        List<DefaultMutableTreeNode> listNodesWithValue = listNodes.stream()
            .filter(node -> node.getUserObject() instanceof NodeResample)
            .filter(node -> value == ((NodeResample) node.getUserObject()).getSampleRateTarget())
            .collect(Collectors.toList());
    
        List<List<NodeResample>> out = new ArrayList<>();
        Long lastSumNumResampleOperations = Long.MAX_VALUE;
    
        for (DefaultMutableTreeNode leaf : listNodesWithValue) {
    
          List<NodeResample> listNodeResample = new ArrayList<>();
          listNodeResample.add((NodeResample) leaf.getUserObject());
          TreeNode treeNode = leaf.getParent();
          while (treeNode != null) {
            DefaultMutableTreeNode parent = (DefaultMutableTreeNode) treeNode;
            if ((parent).getUserObject() instanceof NodeResample) {
              listNodeResample.add(0, (NodeResample) parent.getUserObject());
            }
            treeNode = parent.getParent();
          }
    
    //      Long totalNumResampleOperations = listNodeResample.stream()
    //          .map(nodeResample -> (long) nodeResample.getNumResampleOperations())
    //          .mapToLong(Long::longValue).sum();
    //      if (totalNumResampleOperations < lastSumNumResampleOperations) {
    //        lastSumNumResampleOperations = totalNumResampleOperations;
    //        //out = listNodeResample;
    //      }
          out.add(listNodeResample);
        }
        return out;
      }
    
      private static void removeAllTreeNodes(JTree tree) {
        DefaultMutableTreeNode rootTreeNode = (DefaultMutableTreeNode) tree.getModel().getRoot();
        if (rootTreeNode != null) {
          rootTreeNode.removeAllChildren();
        }
        reloadTree(tree);
      }
    
      private static void reloadTree(JTree tree) {
        DefaultTreeModel treeModel = ((DefaultTreeModel) tree.getModel());
        DefaultMutableTreeNode rootTreeNode = (DefaultMutableTreeNode) treeModel.getRoot();
        treeModel.reload(rootTreeNode);
      }
    
      private static void expandAllNodes(JTree tree) {
        expandAllNodes(tree, 0, tree.getRowCount());
      }
    
      private static void expandAllNodes(JTree tree, int ini, int rows) {
        try {
          if (tree != null) {
            for (int i = ini; i < rows; ++i) {
              tree.expandRow(i);
            }
    
            if (tree.getRowCount() != rows) {
              expandAllNodes(tree, rows, tree.getRowCount());
            }
          }
        } catch (ArrayIndexOutOfBoundsException ex) {
        } catch (Exception ex) {
        }
      }
    
      private static void fillTreeNestedListNodeResample(JTree tree, List<List<NodeResample>> nestedListNodeResample) {
        nestedListNodeResample.stream()
            .forEachOrdered(listNodeResample -> {
              addNodeResampleToTree(tree, listNodeResample);
            });
      }
    
      private static void addNodeResampleToTree(JTree tree, List<NodeResample> listNodeResample) {
        try {
          DefaultTreeModel treeModel = ((DefaultTreeModel) tree.getModel());
          DefaultMutableTreeNode rootTreeNode = (DefaultMutableTreeNode) treeModel.getRoot();
          DefaultMutableTreeNode nodeResampleTreeNode = rootTreeNode;
          if (listNodeResample != null) {
            for (NodeResample nodeResample : listNodeResample) {
              nodeResampleTreeNode = getDefaultMutableTreeNode(nodeResampleTreeNode, nodeResample, true);
            }
          }
          treeModel.reload(rootTreeNode);
        } catch (Exception e) {
          throw e;
        }
      }
    
      private static DefaultMutableTreeNode getDefaultMutableTreeNode(DefaultMutableTreeNode parent, NodeResample newChild, Boolean isLeaf) {
        if (parent != null) {
          DefaultMutableTreeNode child;
          for (int i = 0; i < parent.getChildCount(); i++) {
            child = (DefaultMutableTreeNode) parent.getChildAt(i);
            if (child.toString().equals(newChild.toString())) {
              return child;
            }
          }
          child = new DefaultMutableTreeNode(newChild, isLeaf);
          parent.add(child);
          return child;
        } else {
          return null;
        }
      }
    
      private static List<List<NodeResample>> getNestedListNodeResampleFromTree(JTree tree) {
        List<List<NodeResample>> nestedListNodeResample = new ArrayList<>();
        List<DefaultMutableTreeNode> listLeafDefaultMutableTreeNode = getListLeafsFromTree(tree);
        listLeafDefaultMutableTreeNode.stream()
            .filter(node -> node.getUserObject() instanceof NodeResample)
            .forEach(leaf -> {
              List<NodeResample> listNodeResample = new ArrayList<>();
              listNodeResample.add((NodeResample) leaf.getUserObject());
              TreeNode treeNode = leaf.getParent();
              while (treeNode != null) {
                DefaultMutableTreeNode parent = (DefaultMutableTreeNode) treeNode;
                if ((parent).getUserObject() instanceof NodeResample) {
                  listNodeResample.add(0, (NodeResample) parent.getUserObject());
                }
                treeNode = parent.getParent();
              }
              nestedListNodeResample.add(listNodeResample);
            });
        return nestedListNodeResample;
      }
    
      private static List<DefaultMutableTreeNode> getListLeafsFromTree(JTree tree) {
        DefaultTreeModel treeModel = ((DefaultTreeModel) tree.getModel());
        DefaultMutableTreeNode rootTreeNode = (DefaultMutableTreeNode) treeModel.getRoot();
        List<DefaultMutableTreeNode> listLeafDefaultMutableTreeNode = new ArrayList<>();
        getLeafs(rootTreeNode, listLeafDefaultMutableTreeNode);
        return listLeafDefaultMutableTreeNode;
      }
    
      private static void getLeafs(DefaultMutableTreeNode parent, List<DefaultMutableTreeNode> listLeafDefaultMutableTreeNode) {
        if (parent.isLeaf()) {
          listLeafDefaultMutableTreeNode.add(parent);
        } else {
          for (int i = 0; i < parent.getChildCount(); i++) {
            DefaultMutableTreeNode child = (DefaultMutableTreeNode) parent.getChildAt(i);
            getLeafs(child, listLeafDefaultMutableTreeNode);
          }
        }
      }
    
      private static void getListNodesFromTree(TreeNode treeNode, List<DefaultMutableTreeNode> out) {
        DefaultMutableTreeNode nodeResampleTreeNode = (DefaultMutableTreeNode) treeNode;
        out.add(nodeResampleTreeNode);
        if (treeNode.getChildCount() >= 0) {
          for (Enumeration e = treeNode.children(); e.hasMoreElements();) {
            TreeNode n = (TreeNode) e.nextElement();
            getListNodesFromTree(n, out);
          }
        }
      }
    
      private static List<DefaultMutableTreeNode> getListNodesFromTree(JTree tree) {
        TreeNode root = (TreeNode) tree.getModel().getRoot();
        List<DefaultMutableTreeNode> out = new ArrayList<>();
        getListNodesFromTree(root, out);
        return out;
      }
    
      private static List<List<NodeResample>> filler() {
        List<List<NodeResample>> nestedListNodeResample = null;//Look in Paste bin 
    
        return nestedListNodeResample;
      }
    
    }
    

    【讨论】:

    • 这段代码噪音太大,与实际操作无关。通常,您应该使用适合您实际处理的数据结构,然后为 Swing UI 实现一个包装这些数据结构的 TreeModel,而不是像从 DefaultTreeModel/ 中提取实际数据那样将数据处理代码与 Swing 相关代码混在一起DefaultMutableTreeNode。作为旁注,您可以首先使用.mapToLong(longReturningFunction),而不是.map(longReturningFunction).mapToLong(Long::longValue)
    • @Holger 谢谢,现在我需要执行您的建议。我的新疑问是如何替换JTree
    猜你喜欢
    • 2020-02-09
    • 1970-01-01
    • 2012-08-11
    • 1970-01-01
    • 1970-01-01
    • 2016-07-30
    • 2023-02-03
    • 1970-01-01
    相关资源
    最近更新 更多