【问题标题】:Finding smallest triplets given a set of options给定一组选项找到最小的三元组
【发布时间】:2015-12-01 23:20:15
【问题描述】:

我正在解决这个问题,以在给定一组三元组的情况下找到最小的三元组,这组三元组在所有三个维度中都是最小的。但是,如果存在最小的三元组是任何一维或二维,而不是所有三个维度中最小的,那么也需要考虑。

示例

让我举个例子。 说吧,我的三胞胎如下

(25, 30, 34), (15, 31, 21), (10, 40, 21), (50, 30, 34), (25, 30, 10), (9, 20, 15)

现在,(9,20,15) 看起来是所有三个维度中最小的。但是,也存在一个选项 (25,30,10),它在第三维中最小,因为它在第三维中的得分 (10) 比任何其他选项都小,因此也需要包含在输出中也。所以最终的输出是{(9,20,15) and (25,30,10)}

因此,基本上应该考虑一个解决方案,如果它是主导的或最优的。我可以这样定义这些

1. Dominant : If an outcome o is at least as good for another agent as another outcome o' and there is some
agent who strictly prefers o to o'. Then o pareto-dominates o'

2. Optimal : o* is pareto-optimal if it isn't pareto-dominated by anything else

我的算法

这是我的算法。请参阅随附的代码。让这三个维度分别称为 Course1Score、Course2Score 和 Course3Score。

所以我遍历输入,并为以下每个找到最小的

1.{Course1Score}
2.{Course2Score}
3.{Course3Score}
4.{Course1Score, Course2Score}
5.{Course1Score, Course3Score}
6.{Course2Score, Course3Score}
7.{Course1Score, Course2Score, Course3Score}

然后我在最小化上述目标的解决方案中找到不同的解决方案。

虚假案例

现在这适用于大多数情况,但以下情况除外。让输入为 (1,100,100), (100,1,100), (100,100,1), (1,1,1) 根据上述算法,最小化上述目标的分数如下

 1.Minimize {Course1Score} - (1,100,100) 
(remember this won't be over-written by say,(1,1,1) since Course1Score of (1,1,1) IS NOT LESS than Course1Score of (1,100,100) which comes first in the order of inputs) )
    2.Minimize {Course2Score} - (100,1,100)
    3.Minimize {Course3Score} - (100,100,1)
    4.Minimize {Course1Score, Course2Score} - (1,100,100)
    5.Minimize {Course1Score, Course3Score} - (1,100,100)
    6.Minimize {Course2Score, Course3Score} - (100,1,100)
    7.Minimize {Course1Score, Course2Score, Course3Score} - (1,1,1)

继续算法,我们找到不同的解决方案并将它们报告为 (1,100,100), (100,1,100), (100,100,1), (1,1,1) 然而,这个解决方案是不正确的。由于 (1,1,1) 在所有三个维度上都优于所有其他解决方案,并且 (1,100,100)、(100,1,100)、(100,100,1) 在任何一个方面都没有优于 (1,1,1)尺寸。所以,我在最后添加了一个额外的条件来检查这个,可以在函数中找到

在线java小提琴

这是我的实现的online java fiddle

我的实现

请找到我的代码

import java.util.ArrayList;

/* Glossary
 * 1. Dominant : If an outcome o is at least as good for another agent as another outcome o' and there is some
 * agent who strictly prefers o to o'. Then o Triplet-dominates o'
 * 
 * 2. Optimal : o* is Triplet-optimal if it isn't Triplet-dominated by anything else
 * 
 *   */
public class HelloWorld
{
    public static void main(String[] args)
    {
        Triplet myTriplet = new Triplet();

        /* Populating input and printing them */
        System.out.println("Printing input");
        myTriplet.PopulateSampleInput();
        myTriplet.Print(myTriplet.options);

        /* Printing the Triplet-Optimal solutions */
        ArrayList<Option> TripletSolutions = myTriplet.FindTripletOptimalSolutions();
        System.out.println("Printing TripletSolutions : ");
        myTriplet.Print(TripletSolutions);
    }
}

class Triplet
{
    ArrayList<Option> options;

    public Triplet()
    {
        options = new ArrayList<Option>();
    }

    void PopulateSampleInput()
    {
        Option option1 = new Option(25, 30, 34);
        Option option2 = new Option(15, 31, 21);
        Option option3 = new Option(10, 40, 21);
        Option option4 = new Option(50, 30, 34);
        Option option5 = new Option(25, 30, 10);
        Option option6 = new Option(9, 20, 15);

        options.add(option1);
        options.add(option2);
        options.add(option3);
        options.add(option4);
        options.add(option5);
        options.add(option6);
    }

    void Print(ArrayList<Option> al)
    {
        for(int i = 0;i< al.size();i++)
        {
            System.out.println(al.get(i).Course1Score + "," + al.get(i).Course2Score + "," + al.get(i).Course3Score);
        }
    }

    ArrayList<Option> FindTripletOptimalSolutions()
    {
        Option[] map = new Option[7];

        /* Initialization : Initially the best solution for minimizing all objectives is the first solution */
        for(int i = 0;i<map.length;i++)
            map[i] = options.get(0);

        for(int i=1;i<options.size();i++)
        {
            /* Fixing {1} */
            if(options.get(i).Course1Score < map[0].Course1Score)
                map[0] = options.get(i);

            /* Fixing {2} */
            if(options.get(i).Course2Score < map[1].Course2Score)
                map[1] = options.get(i);

            /* Fixing {3} */
            if(options.get(i).Course3Score < map[2].Course3Score)
                map[2] = options.get(i);

            /* Fixing {1,2} */
            if(options.get(i).Course1Score <= map[3].Course1Score && options.get(i).Course2Score <= map[3].Course2Score)
                map[3] = options.get(i);

            /* Fixing {1,3} */
            if(options.get(i).Course1Score <= map[4].Course1Score && options.get(i).Course3Score <= map[4].Course3Score)
                map[4] = options.get(i);

            /* Fixing {2,3} */
            if(options.get(i).Course2Score <= map[5].Course2Score && options.get(i).Course3Score <= map[5].Course3Score)
                map[5] = options.get(i);

            /* Fixing {1,2,3} */
            if(options.get(i).Course1Score <= map[6].Course1Score && options.get(i).Course2Score <= map[6].Course2Score && options.get(i).Course3Score <= map[6].Course3Score)
                map[6] = options.get(i);
        }

        /* find unique solutions */
        ArrayList<Option> DistinctSolutions = new ArrayList<Option>();
        DistinctSolutions = findUnique(map); 

        /* keeping only solutions that add something new */
        ArrayList<Option> TripletSolutions = EliminateWeakSolutionInCaseOfTie(DistinctSolutions);
        return TripletSolutions;
    }

    /* This function returns the unique solutions, otherwise, they will cancel out each other inside the 
     * EliminateWeakSolutionInCaseOfTie function that comes next */
    ArrayList<Option> findUnique(Option[] map)
    {
        ArrayList<Option> TripletSolutions = new ArrayList<Option>();
        for(int i = 0;i<map.length;i++)
        {
            if(!TripletSolutions.contains(map[i]))
                TripletSolutions.add(map[i]);
        }
        return TripletSolutions;
    }

    /* This function in case of ties where map[0]'s Course1Score is only equal to, but not less than
     * map[6]'s Course1Score, which in addition to minimizing Course1Score, also minimizes
     * Course2Score and Course3Score */
    ArrayList<Option> EliminateWeakSolutionInCaseOfTie(ArrayList<Option> DistinctSolutions)
    {
        ArrayList<Option> TripletSolutions = new ArrayList<Option>();
        int Include = 1;
        for(int i = 0;i<DistinctSolutions.size();i++,Include=1)
        {
            for(int j = 0;j<DistinctSolutions.size();j++)
            {
                if(i!=j && DistinctSolutions.get(j).Course1Score <= DistinctSolutions.get(i).Course1Score && DistinctSolutions.get(j).Course2Score <= DistinctSolutions.get(i).Course2Score && DistinctSolutions.get(j).Course3Score <= DistinctSolutions.get(i).Course3Score)
                {
                    Include = 0;
                    break;
                }
            }
            if(Include == 1)
                TripletSolutions.add(DistinctSolutions.get(i));
        }
        return TripletSolutions;
    }
}

class Option
{
    int Course1Score;
    int Course2Score;
    int Course3Score;

    public Option(int Course1Score, int Course2Score, int Course3Score)
    {
        // TODO Auto-generated constructor stub
        this.Course1Score = Course1Score;
        this.Course2Score = Course2Score;
        this.Course3Score = Course3Score;
    }
}

您能否为上述建议一个算法,和/或查看我的算法和实现?

编辑:我认为这个解决方案有效

伪代码

ParetoSolutionPool[1] = input[1]

for(i in 2:input)
    boolean ParetoDominant = false;
    boolean ParetoOptimal = true;

    for(j in 1:ParetoSolutionPool)
        if(input[i] ParetoDominates ParetoSolutionPool[j])
            remove ParetoSolutionPool[j]
            ParetoDominant = true;

        if(input[i] IsParetoDominatedBy ParetoSolutionPool[j])//extra if(ParetoDominant == false && ParetoOptimal == true && above)
            ParetoOptimal = false;
    end of for loop over j

    if(ParetoDominant || ParetoOptimal == true)
        add input[i] to ParetoSolutionPool

end of for loop over i

单词中的伪代码

基本上,两次检查。 1.如果输入/选项占主导地位(在所有三个维度上都较低),现有解决方案之一,“现有解决方案”被弹出,并被此输入替换,因为一致更好。 (例如 25,30,10 优于 25,30,34)

2.如果输入(在所有三个维度上)都不比任何现有解决方案差,那么它也必须考虑到解决方案池中。

因此,基本上在上述两种情况中的任何一种情况下,都会将输入添加到解决方案池中。两者之间的唯一区别在于,在第一种情况下,也会弹出较弱的现有解决方案。

代码

package TripletOptimizationAlgorithms;

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Collections;

public class algo4
{
    public static void main(String[] args)
    {
        Triplet myTriplet = new Triplet();

        /* Populating input and printing them */
        System.out.println("Printing input");
        //myTriplet.PopulateSampleInput();
        myTriplet.PopulateSampleInputFromFile();
        myTriplet.Print(myTriplet.options);
        System.out.println("Number of inputs read=="+myTriplet.options.size());

        /* Printing the Triplet-Optimal solutions */
        final long startTime = System.currentTimeMillis();
        ArrayList<Option> TripletSolutions = myTriplet.FindTripletOptimalSolutions();
        final long endTime = System.currentTimeMillis();

        System.out.println("Printing TripletSolutions : ");
        myTriplet.Print(TripletSolutions);

        System.out.println("Total execution time: " + (endTime - startTime) + " milliseconds" );
    }
}

class Triplet
{
    ArrayList<Option> options;

    public Triplet()
    {
        options = new ArrayList<Option>();
    }

    void PopulateSampleInput()
    {
        Option option1 = new Option(25, 30, 34);
        Option option2 = new Option(15, 31, 21);
        Option option3 = new Option(10, 40, 21);
        Option option4 = new Option(30, 30, 34);
        Option option5 = new Option(25, 30, 10);
        Option option6 = new Option(9, 20, 15);

        options.add(option1);
        options.add(option2);
        options.add(option3);
        options.add(option4);
        options.add(option5);
        options.add(option6);
    }

    void PopulateSampleInputFromFile()
    {
        try
        {
            String pwd = Paths.get(".").toAbsolutePath().normalize().toString();
            String inputpath = pwd + "/src/TripletOptimizationAlgorithms/myinput.txt";

            FileInputStream fstream = new FileInputStream(inputpath);
            DataInputStream in = new DataInputStream(fstream);
            BufferedReader br = new BufferedReader(new InputStreamReader(in));
            String strLine;
            while ((strLine = br.readLine()) != null)
            {
                String[] tokens = strLine.split(" ");
                Option myoption = new Option(Integer.parseInt(tokens[0]),Integer.parseInt(tokens[1]),Integer.parseInt(tokens[2]));//process record , etc
                options.add(myoption);
            }
            in.close();
        }
        catch (Exception e)
        {
            System.err.println("Error: " + e.getMessage());
        }
    }

    void Print(ArrayList<Option> al)
    {
        for(int i = 0;i< al.size();i++)
        {
            System.out.println(al.get(i).Course1Score + "," + al.get(i).Course2Score + "," + al.get(i).Course3Score);
        }
    }

    ArrayList<Option> FindTripletOptimalSolutions()
    {
        /* Initialization : Initialize the TripletSolutions to be the first option */
        ArrayList<Option> TripletSolutions = new ArrayList<Option>();
        TripletSolutions.add(options.get(0));

        /* looping across input */
        for(int i = 1;i<options.size();i++)
        {
            boolean TripletDominant = false;
            boolean TripletOptimal = true;
            Option optionUnderCheck = options.get(i);
            ArrayList<Integer> IndicesToRemove = new ArrayList<Integer>();

            /* looping across TripletSolutions */
            for(int j = 0;j<TripletSolutions.size();j++)
            {
                if(isTripletDominant(optionUnderCheck, TripletSolutions.get(j)) == true)
                {
                    TripletDominant = true;
                    IndicesToRemove.add(j);
                }

                if(IsTripletDominatedBy(optionUnderCheck, TripletSolutions.get(j)) == true)
                {
                    TripletOptimal = false;
                }
            }

            /* the weaker solutions have to be removed */
            if(TripletDominant == true)
            {
                Collections.sort(IndicesToRemove, Collections.reverseOrder());
                for(int k = 0;k<IndicesToRemove.size();k++)
                {
                    TripletSolutions.remove(IndicesToRemove.get(k).intValue());
                }
            }

            if(TripletDominant == true || TripletOptimal == true)
                TripletSolutions.add(optionUnderCheck);
        }

        return TripletSolutions;
    }

    boolean isTripletDominant(Option optionUnderCheck, Option existingSolution)
    {
        if(optionUnderCheck.Course1Score <= existingSolution.Course1Score && optionUnderCheck.Course2Score <= existingSolution.Course2Score && optionUnderCheck.Course3Score <= existingSolution.Course3Score)
            return true;
        return false;
    }

    boolean IsTripletDominatedBy(Option optionUnderCheck, Option existingSolution)
    {
        if(optionUnderCheck.Course1Score >= existingSolution.Course1Score && optionUnderCheck.Course2Score >= existingSolution.Course2Score && optionUnderCheck.Course3Score >= existingSolution.Course3Score)
            return true;
        return false;
    }
}

class Option
{
    int Course1Score;
    int Course2Score;
    int Course3Score;

    public Option(int Course1Score, int Course2Score, int Course3Score)
    {
        // TODO Auto-generated constructor stub
        this.Course1Score = Course1Score;
        this.Course2Score = Course2Score;
        this.Course3Score = Course3Score;
    }
}

【问题讨论】:

    标签: java algorithm optimization big-o


    【解决方案1】:

    其实这可以简化很多。
    那么让我们来看看你的匹配规则:

    1. {Course1Score} 最低
    2. {Course2Score} ...
    3. {Course3Score} ...
    4. {Course1Score, Course2Score} 最优或优势解决方案
    5. {Course1Score, Course3Score} ...
    6. {Course2Score, Course3Score} ...
    7. {Course1Score、Course2Score、Course3Score} ...

    规则 1,2 和 3 只需搜索最小化 CourseNScore 的值(将 N 替换为规则编号)。 4,5 和 6 搜索对 ​​(a , b)(将 ab 替换为各自的 CourseScore),因此不存在具有较低 ab 的对。这些对也将通过规则 1 - 3 找到,无论它们是主导的还是最优的。同样适用于规则 7 和规则 4 - 6。

    因此,我们可以轻松地将搜索减少到找到 1 个元素最少的元组并减少匹配集。这将大大加快搜索速度。这将产生 3 组元组(每个被搜索的元组元素一个)。

    下一步: 减少找到的元组的集合。这可以通过一种非常幼稚的方法来完成:
    匹配规则 7 的解决方案必须在搜索生成的所有集合中。符合规则 4 的解决方案必须在符合规则 1 和 2 的集合中。

    因此,减少结果变成了一项非常微不足道的任务。

    评论:
    变量名和方法名在 java 中通常是小写的。
    Option 生成String 的部分,就像在Triplet.Print 中使用的一样,应该转移到Option.toString(),因为这是通常的方式。但这段代码没什么可批评的。

    【讨论】:

    • 感谢当天的反馈。我想出了另一个实现。请参见上文。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-06-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多