I added some more math to the script I used to generate the results page... and what do you know: no official winner by any of the methods! (assuming my math is correct)

check:
http://people.apache.org/~ryan/solr-logo-results.html
for a variety of attempts.

The problem with the STV method is that it continues until you meed a quota: (votes/seats+1)+1, in our case (19/2)+1=10. Nothing ever gets to 10, so you will notice that stv==votes for everything!

So the next option is to try instant runoff voting:
http://en.wikipedia.org/wiki/Instant-runoff_voting

in that method, the losers of each round is tossed out and the vote continues until there is a majority. Again, we never reach a majority, but the last two logos to lose are:
eliminating (4) 
https://issues.apache.org/jira/secure/attachment/12394264/apache_solr_a_red.jpg
eliminating (4) 
https://issues.apache.org/jira/secure/attachment/12394070/sslogo-solr-finder2.0.png

Other things to perhaps consider.  Using the "scoring" method,
https://issues.apache.org/jira/secure/attachment/12394070/sslogo-solr-finder2.0.png
is the winner.

The STV or vote counting method puts
https://issues.apache.org/jira/secure/attachment/12394264/apache_solr_a_red.jpg
or
https://issues.apache.org/jira/secure/attachment/12394264/apache_solr_b_red.jpg
at the top.

If we only count the first round of voting
https://issues.apache.org/jira/secure/attachment/12394070/sslogo-solr-finder2.0.png
wins followed by:
https://issues.apache.org/jira/secure/attachment/12394264/apache_solr_a_red.jpg
https://issues.apache.org/jira/secure/attachment/12394264/apache_solr_b_red.jpg

There you go.  clear as mud!

As I see it, we either call a new community poll -- nothing in the rules says we can't. or vote on:

1. 
https://issues.apache.org/jira/secure/attachment/12394070/sslogo-solr-finder2.0.png
last eliminated by instant runoff and it won the 'soring' method

2. 
https://issues.apache.org/jira/secure/attachment/12394264/apache_solr_a_red.jpg
last eliminated by instant runoff and *may* have won if the other similar logos were not involved.

ryan

here is the hacked up code if you are curious...



    String[][] v = new String[][] {
      {
"https://issues.apache.org/jira/secure/attachment/12394267/apache_solr_c_blue.jpg ", "https://issues.apache.org/jira/secure/attachment/12394265/apache_solr_b_blue.jpg ", "https://issues.apache.org/jira/secure/attachment/12394263/apache_solr_a_blue.jpg ",
      },
      {
"https://issues.apache.org/jira/secure/attachment/12394282/solr2_maho_impression.png ", "https://issues.apache.org/jira/secure/attachment/12394366/solr3_maho.png ", "https://issues.apache.org/jira/secure/attachment/12394264/apache_solr_a_red.jpg ", "https://issues.apache.org/jira/secure/attachment/12394266/apache_solr_b_red.jpg ", "https://issues.apache.org/jira/secure/attachment/12394218/solr-solid.png ",
      },
      {
"https://issues.apache.org/jira/secure/attachment/12394218/solr-solid.png ", "https://issues.apache.org/jira/secure/attachment/12394376/solr_sp.png ", "https://issues.apache.org/jira/secure/attachment/12393951/sslogo-solr-classic.png ", "https://issues.apache.org/jira/secure/attachment/12391946/apache_solr_burning.png ", "https://issues.apache.org/jira/secure/attachment/12392306/apache_solr_sun.png ",
      },
      {
"https://issues.apache.org/jira/secure/attachment/12394267/apache_solr_c_blue.jpg ", "https://issues.apache.org/jira/secure/attachment/12394268/apache_solr_c_red.jpg ",

"https://issues.apache.org/jira/secure/attachment/12394282/solr2_maho_impression.png ", "https://issues.apache.org/jira/secure/attachment/12394366/solr3_maho.png ", "https://issues.apache.org/jira/secure/attachment/12393936/logo_remake.jpg ",
      },
      {
"https://issues.apache.org/jira/secure/attachment/12394282/solr2_maho_impression.png ",
      },
      {
"https://issues.apache.org/jira/secure/attachment/12394282/solr2_maho_impression.png ", "https://issues.apache.org/jira/secure/attachment/12394475/solr2_maho-vote.png ", "https://issues.apache.org/jira/secure/attachment/12394268/apache_solr_c_red.jpg ",
      },
      {
"https://issues.apache.org/jira/secure/attachment/12394263/apache_solr_a_blue.jpg ", "https://issues.apache.org/jira/secure/attachment/12394282/solr2_maho_impression.png ",
      },
      {
"https://issues.apache.org/jira/secure/attachment/12394282/solr2_maho_impression.png ", "https://issues.apache.org/jira/secure/attachment/12394266/apache_solr_b_red.jpg ",
      },
      {
"https://issues.apache.org/jira/secure/attachment/12394070/sslogo-solr-finder2.0.png ", "https://issues.apache.org/jira/secure/attachment/12394282/solr2_maho_impression.png ", "https://issues.apache.org/jira/secure/attachment/12394353/solr.s5.jpg ", "https://issues.apache.org/jira/secure/attachment/12394264/apache_solr_a_red.jpg ",
      },
      {
"https://issues.apache.org/jira/secure/attachment/12394282/solr2_maho_impression.png ", "https://issues.apache.org/jira/secure/attachment/12394376/solr_sp.png ", "https://issues.apache.org/jira/secure/attachment/12393936/logo_remake.jpg ", "https://issues.apache.org/jira/secure/attachment/12394264/apache_solr_a_red.jpg ", "https://issues.apache.org/jira/secure/attachment/12394353/solr.s5.jpg ",
      },
      {
"https://issues.apache.org/jira/secure/attachment/12394282/solr2_maho_impression.png ",
      },
      {
"https://issues.apache.org/jira/secure/attachment/12394264/apache_solr_a_red.jpg ", "https://issues.apache.org/jira/secure/attachment/12394282/solr2_maho_impression.png ", "https://issues.apache.org/jira/secure/attachment/12394266/apache_solr_b_red.jpg ", "https://issues.apache.org/jira/secure/attachment/12394353/solr.s5.jpg ",
      },
      {
"https://issues.apache.org/jira/secure/attachment/12394266/apache_solr_b_red.jpg ", "https://issues.apache.org/jira/secure/attachment/12394314/apache_soir_001.jpg ",
      },
      {
"https://issues.apache.org/jira/secure/attachment/12394165/solr-logo.png ", "https://issues.apache.org/jira/secure/attachment/12391987/solr.png ", "https://issues.apache.org/jira/secure/attachment/12392306/apache_solr_sun.png ", "https://issues.apache.org/jira/secure/attachment/12394282/solr2_maho_impression.png ", "https://issues.apache.org/jira/secure/attachment/12394376/solr_sp.png ",
      },
      {
"https://issues.apache.org/jira/secure/attachment/12394070/sslogo-solr-finder2.0.png ", "https://issues.apache.org/jira/secure/attachment/12394165/solr-logo.png ", "https://issues.apache.org/jira/secure/attachment/12394266/apache_solr_b_red.jpg ", "https://issues.apache.org/jira/secure/attachment/12394282/solr2_maho_impression.png ",
      },
      {
"https://issues.apache.org/jira/secure/attachment/12394264/apache_solr_a_red.jpg ",
      },
      { /
"https://issues.apache.org/jira/secure/attachment/12394218/solr-solid.png ", "https://issues.apache.org/jira/secure/attachment/12394070/sslogo-solr-finder2.0.png ", "https://issues.apache.org/jira/secure/attachment/12391946/apache_solr_burning.png ", "https://issues.apache.org/jira/secure/attachment/12394282/solr2_maho_impression.png ",
      },
      {
"https://issues.apache.org/jira/secure/attachment/12394070/sslogo-solr-finder2.0.png ", "https://issues.apache.org/jira/secure/attachment/12394475/solr2_maho-vote.png ", "https://issues.apache.org/jira/secure/attachment/12393995/sslogo-solr-70s.png "
      },
      {
"https://issues.apache.org/jira/secure/attachment/12394350/solr.s4.jpg ", "https://issues.apache.org/jira/secure/attachment/12394268/apache_solr_c_red.jpg ", "https://issues.apache.org/jira/secure/attachment/12393995/sslogo-solr-70s.png ", "https://issues.apache.org/jira/secure/attachment/12393936/logo_remake.jpg ",
      },
      {
"https://issues.apache.org/jira/secure/attachment/12394165/solr-logo.png ", "https://issues.apache.org/jira/secure/attachment/12394475/solr2_maho-vote.png ", "https://issues.apache.org/jira/secure/attachment/12394350/solr.s4.jpg ", "https://issues.apache.org/jira/secure/attachment/12394282/solr2_maho_impression.png ", "https://issues.apache.org/jira/secure/attachment/12394314/apache_soir_001.jpg ",
      },
      {
"https://issues.apache.org/jira/secure/attachment/12394268/apache_solr_c_red.jpg ", "https://issues.apache.org/jira/secure/attachment/12394350/solr.s4.jpg ", "https://issues.apache.org/jira/secure/attachment/12394376/solr_sp.png ", "https://issues.apache.org/jira/secure/attachment/12394267/apache_solr_c_blue.jpg "
      },
// LATE VOTE
//      {
// "https://issues.apache.org/jira/secure/attachment/12394268/apache_solr_c_red.jpg ", // "https://issues.apache.org/jira/secure/attachment/12394282/solr2_maho_impression.png ", // "https://issues.apache.org/jira/secure/attachment/12394267/apache_solr_c_blue.jpg "
//      }
    };

    Map<String,Entry> votes = new HashMap<String, Entry>();

    for( String[] cast : v ) {
      int value = 5;
      for( String u : cast ) {
        Entry entry = votes.get( u );
        if( entry == null ) {
          entry = new Entry();
          entry.url = u;
          votes.put( u, entry );
        }
        entry.votes++;
        entry.score += value--;
      }
    }

    // go through each vote and remove:
    //

    // Toss out any votes for: solr2_maho_impression.png
    // but make the next vote #1
    List<List<String>> normalized = new ArrayList<List<String>>();
    for( String[] cast : v ) {
      List<String> pref = new ArrayList<String>();
      for( String u : cast ) {
if( !"https://issues.apache.org/jira/secure/attachment/12394282/solr2_maho_impression.png ".equals( u ) ) {
          pref.add( u );
        }
      }
      if( !pref.isEmpty() ) {
        normalized.add( pref );
      }
    }

    List<Entry> past = new ArrayList<Entry>();
    int quota = (normalized.size()/2)+1;
    for( int round=0; round<7&&past.isEmpty(); round++ ){
     // System.out.println( "round:"+round );
      for( List<String> pref : normalized ) {
        if( pref.size() > round ) {
Entry e = votes.get( pref.get( round ) ); // should not be null
          e.stv++;
          if( round == 0 ) {
            e.first = e.stv;
          }
        }
      }

      // check if anyone is past the quota
      for( Entry e : votes.values() ) {
        if( e.stv >= quota ) {
          past.add( e );
        }
      }
    }

    List<Entry> entries = new LinkedList<Entry>();
    entries.addAll( votes.values() );

    PrintStream out = System.out;
    out.println( "<html><body>" );

Collections.sort( entries, new PropertyComparator( "votes", true, false ) );
    out.println( "<h1>Sorted by number of votes</h1>" );
    writeTable( entries, out );

Collections.sort( entries, new PropertyComparator( "score", true, false ) );
    out.println( "<h1>Sorted by score</h1>" );
    writeTable( entries, out );

Collections.sort( entries, new PropertyComparator( "stv", true, false ) ); out.println( "<h1>Sorted by Single transferable vote. Quota: "+quota+"</h1>" );
    String u = "http://en.wikipedia.org/wiki/Single_transferable_vote";;
    out.println( String.format("<a href=\"%s\">%s</a>",u,u) );
    writeTable( entries, out );

Collections.sort( entries, new PropertyComparator( "first", true, false ) ); out.println( "<h1>Sorted by first (excluding solr2_maho_impression.png)</h1>" );
    writeTable( entries, out );

    // Now use Instant-runoff voting
    Set<String> eliminated = new HashSet<String>();
    int majority = normalized.size() / 2;
    out.println( "<h1>Instant-runoff voting</h1>" );
    out.println( "<pre>" );
    Entry winner = null;
    for( int round=1; winner == null; round++ ) {
      Map<String,Entry> inRunning = new HashMap<String, Entry>();
      for( Entry e : votes.values() )  {
        if( !eliminated.contains( e.url ) ) {
          e.votes = 0;
          inRunning.put( e.url, e );
        }
      }
      out.println( "round: "+round );
      out.println( "entries: "+inRunning.size() );
      if( inRunning.isEmpty() ) {
        out.println( "finished with no winner." );
        break;
      }

      // Give each person a vote for the top remaing canidate
      for( List<String> pref : normalized ) {
        for( String p : pref ) {
          Entry e = inRunning.get( p );
          if( e != null ) {
            e.votes++;
            break;
          }
        }
      }

      // Check if anyone has a majority
      for( Entry e : inRunning.values() ) {
        if( e.votes > majority ) {
          winner = e;  // can't have two with a majority
        }
      }

      // remove the lowest score
      entries.clear();
      entries.addAll( inRunning.values() );
Collections.sort( entries, new PropertyComparator( "votes", true, true ) );
      int lowestscore = entries.get( 0 ).votes;
      for( Entry e : entries ) {
        if( e.votes == lowestscore ) {
          eliminated.add( e.url );
          out.println( "eliminating ("+lowestscore+") "+e.url );
        }
      }
    }
    out.println("</pre>");

    out.println( "</body></html>" );
  }

  void writeTable( Collection<Entry> entries, PrintStream out ) {
    out.println( "<table border=1 cellpadding=20>" );
    for( Entry entry : entries ) {
      out.println( "<tr valign=\"top\">" );
out.println( String.format( "<td>votes: %d<br/>score: %d<br/ >stv: %d<br/>first: %d",
            entry.votes, entry.score, entry.stv, entry.first  ) );
out.println( String.format( "<td><img src=\"%s\" /></td>", entry.url ) );
      out.println( "</tr>" );
    }
    out.println( "</table>" );
    out.println( "<br/><br/>" );
  }



On Dec 10, 2008, at 4:59 PM, Mike Klaas wrote:


On 10-Dec-08, at 12:41 PM, Yonik Seeley wrote:

Sure thing.

I take it that there are no objections? If so, I'll call a vote by the end
of the week.

+1
I just wish we had used this method with the community vote.

I guess as a committer I should try and figure out what order the
community would have voted and do that.

I could run the results of the community vote interpreted as STV, if that would help (it'll be a few days, though).

-Mike

Reply via email to